1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright 2012-2019 Red Hat 4 * 5 * This file is subject to the terms and conditions of the GNU General 6 * Public License version 2. See the file COPYING in the main 7 * directory of this archive for more details. 8 * 9 * Authors: Matthew Garrett 10 * Dave Airlie 11 * Gerd Hoffmann 12 * 13 * Portions of this code derived from cirrusfb.c: 14 * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets 15 * 16 * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> 17 */ 18 19 #include <linux/console.h> 20 #include <linux/module.h> 21 #include <linux/pci.h> 22 23 #include <video/cirrus.h> 24 #include <video/vga.h> 25 26 #include <drm/drm_atomic_helper.h> 27 #include <drm/drm_atomic_state_helper.h> 28 #include <drm/drm_connector.h> 29 #include <drm/drm_damage_helper.h> 30 #include <drm/drm_drv.h> 31 #include <drm/drm_fb_helper.h> 32 #include <drm/drm_file.h> 33 #include <drm/drm_format_helper.h> 34 #include <drm/drm_fourcc.h> 35 #include <drm/drm_gem_shmem_helper.h> 36 #include <drm/drm_gem_framebuffer_helper.h> 37 #include <drm/drm_ioctl.h> 38 #include <drm/drm_managed.h> 39 #include <drm/drm_modeset_helper_vtables.h> 40 #include <drm/drm_probe_helper.h> 41 #include <drm/drm_simple_kms_helper.h> 42 43 #define DRIVER_NAME "cirrus" 44 #define DRIVER_DESC "qemu cirrus vga" 45 #define DRIVER_DATE "2019" 46 #define DRIVER_MAJOR 2 47 #define DRIVER_MINOR 0 48 49 #define CIRRUS_MAX_PITCH (0x1FF << 3) /* (4096 - 1) & ~111b bytes */ 50 #define CIRRUS_VRAM_SIZE (4 * 1024 * 1024) /* 4 MB */ 51 52 struct cirrus_device { 53 struct drm_device dev; 54 struct drm_simple_display_pipe pipe; 55 struct drm_connector conn; 56 unsigned int cpp; 57 unsigned int pitch; 58 void __iomem *vram; 59 void __iomem *mmio; 60 }; 61 62 #define to_cirrus(_dev) container_of(_dev, struct cirrus_device, dev) 63 64 /* ------------------------------------------------------------------ */ 65 /* 66 * The meat of this driver. The core passes us a mode and we have to program 67 * it. The modesetting here is the bare minimum required to satisfy the qemu 68 * emulation of this hardware, and running this against a real device is 69 * likely to result in an inadequately programmed mode. We've already had 70 * the opportunity to modify the mode, so whatever we receive here should 71 * be something that can be correctly programmed and displayed 72 */ 73 74 #define SEQ_INDEX 4 75 #define SEQ_DATA 5 76 77 static u8 rreg_seq(struct cirrus_device *cirrus, u8 reg) 78 { 79 iowrite8(reg, cirrus->mmio + SEQ_INDEX); 80 return ioread8(cirrus->mmio + SEQ_DATA); 81 } 82 83 static void wreg_seq(struct cirrus_device *cirrus, u8 reg, u8 val) 84 { 85 iowrite8(reg, cirrus->mmio + SEQ_INDEX); 86 iowrite8(val, cirrus->mmio + SEQ_DATA); 87 } 88 89 #define CRT_INDEX 0x14 90 #define CRT_DATA 0x15 91 92 static u8 rreg_crt(struct cirrus_device *cirrus, u8 reg) 93 { 94 iowrite8(reg, cirrus->mmio + CRT_INDEX); 95 return ioread8(cirrus->mmio + CRT_DATA); 96 } 97 98 static void wreg_crt(struct cirrus_device *cirrus, u8 reg, u8 val) 99 { 100 iowrite8(reg, cirrus->mmio + CRT_INDEX); 101 iowrite8(val, cirrus->mmio + CRT_DATA); 102 } 103 104 #define GFX_INDEX 0xe 105 #define GFX_DATA 0xf 106 107 static void wreg_gfx(struct cirrus_device *cirrus, u8 reg, u8 val) 108 { 109 iowrite8(reg, cirrus->mmio + GFX_INDEX); 110 iowrite8(val, cirrus->mmio + GFX_DATA); 111 } 112 113 #define VGA_DAC_MASK 0x06 114 115 static void wreg_hdr(struct cirrus_device *cirrus, u8 val) 116 { 117 ioread8(cirrus->mmio + VGA_DAC_MASK); 118 ioread8(cirrus->mmio + VGA_DAC_MASK); 119 ioread8(cirrus->mmio + VGA_DAC_MASK); 120 ioread8(cirrus->mmio + VGA_DAC_MASK); 121 iowrite8(val, cirrus->mmio + VGA_DAC_MASK); 122 } 123 124 static int cirrus_convert_to(struct drm_framebuffer *fb) 125 { 126 if (fb->format->cpp[0] == 4 && fb->pitches[0] > CIRRUS_MAX_PITCH) { 127 if (fb->width * 3 <= CIRRUS_MAX_PITCH) 128 /* convert from XR24 to RG24 */ 129 return 3; 130 else 131 /* convert from XR24 to RG16 */ 132 return 2; 133 } 134 return 0; 135 } 136 137 static int cirrus_cpp(struct drm_framebuffer *fb) 138 { 139 int convert_cpp = cirrus_convert_to(fb); 140 141 if (convert_cpp) 142 return convert_cpp; 143 return fb->format->cpp[0]; 144 } 145 146 static int cirrus_pitch(struct drm_framebuffer *fb) 147 { 148 int convert_cpp = cirrus_convert_to(fb); 149 150 if (convert_cpp) 151 return convert_cpp * fb->width; 152 return fb->pitches[0]; 153 } 154 155 static void cirrus_set_start_address(struct cirrus_device *cirrus, u32 offset) 156 { 157 int idx; 158 u32 addr; 159 u8 tmp; 160 161 if (!drm_dev_enter(&cirrus->dev, &idx)) 162 return; 163 164 addr = offset >> 2; 165 wreg_crt(cirrus, 0x0c, (u8)((addr >> 8) & 0xff)); 166 wreg_crt(cirrus, 0x0d, (u8)(addr & 0xff)); 167 168 tmp = rreg_crt(cirrus, 0x1b); 169 tmp &= 0xf2; 170 tmp |= (addr >> 16) & 0x01; 171 tmp |= (addr >> 15) & 0x0c; 172 wreg_crt(cirrus, 0x1b, tmp); 173 174 tmp = rreg_crt(cirrus, 0x1d); 175 tmp &= 0x7f; 176 tmp |= (addr >> 12) & 0x80; 177 wreg_crt(cirrus, 0x1d, tmp); 178 179 drm_dev_exit(idx); 180 } 181 182 static int cirrus_mode_set(struct cirrus_device *cirrus, 183 struct drm_display_mode *mode, 184 struct drm_framebuffer *fb) 185 { 186 int hsyncstart, hsyncend, htotal, hdispend; 187 int vtotal, vdispend; 188 int tmp, idx; 189 int sr07 = 0, hdr = 0; 190 191 if (!drm_dev_enter(&cirrus->dev, &idx)) 192 return -1; 193 194 htotal = mode->htotal / 8; 195 hsyncend = mode->hsync_end / 8; 196 hsyncstart = mode->hsync_start / 8; 197 hdispend = mode->hdisplay / 8; 198 199 vtotal = mode->vtotal; 200 vdispend = mode->vdisplay; 201 202 vdispend -= 1; 203 vtotal -= 2; 204 205 htotal -= 5; 206 hdispend -= 1; 207 hsyncstart += 1; 208 hsyncend += 1; 209 210 wreg_crt(cirrus, VGA_CRTC_V_SYNC_END, 0x20); 211 wreg_crt(cirrus, VGA_CRTC_H_TOTAL, htotal); 212 wreg_crt(cirrus, VGA_CRTC_H_DISP, hdispend); 213 wreg_crt(cirrus, VGA_CRTC_H_SYNC_START, hsyncstart); 214 wreg_crt(cirrus, VGA_CRTC_H_SYNC_END, hsyncend); 215 wreg_crt(cirrus, VGA_CRTC_V_TOTAL, vtotal & 0xff); 216 wreg_crt(cirrus, VGA_CRTC_V_DISP_END, vdispend & 0xff); 217 218 tmp = 0x40; 219 if ((vdispend + 1) & 512) 220 tmp |= 0x20; 221 wreg_crt(cirrus, VGA_CRTC_MAX_SCAN, tmp); 222 223 /* 224 * Overflow bits for values that don't fit in the standard registers 225 */ 226 tmp = 0x10; 227 if (vtotal & 0x100) 228 tmp |= 0x01; 229 if (vdispend & 0x100) 230 tmp |= 0x02; 231 if ((vdispend + 1) & 0x100) 232 tmp |= 0x08; 233 if (vtotal & 0x200) 234 tmp |= 0x20; 235 if (vdispend & 0x200) 236 tmp |= 0x40; 237 wreg_crt(cirrus, VGA_CRTC_OVERFLOW, tmp); 238 239 tmp = 0; 240 241 /* More overflow bits */ 242 243 if ((htotal + 5) & 0x40) 244 tmp |= 0x10; 245 if ((htotal + 5) & 0x80) 246 tmp |= 0x20; 247 if (vtotal & 0x100) 248 tmp |= 0x40; 249 if (vtotal & 0x200) 250 tmp |= 0x80; 251 252 wreg_crt(cirrus, CL_CRT1A, tmp); 253 254 /* Disable Hercules/CGA compatibility */ 255 wreg_crt(cirrus, VGA_CRTC_MODE, 0x03); 256 257 sr07 = rreg_seq(cirrus, 0x07); 258 sr07 &= 0xe0; 259 hdr = 0; 260 261 cirrus->cpp = cirrus_cpp(fb); 262 switch (cirrus->cpp * 8) { 263 case 8: 264 sr07 |= 0x11; 265 break; 266 case 16: 267 sr07 |= 0x17; 268 hdr = 0xc1; 269 break; 270 case 24: 271 sr07 |= 0x15; 272 hdr = 0xc5; 273 break; 274 case 32: 275 sr07 |= 0x19; 276 hdr = 0xc5; 277 break; 278 default: 279 drm_dev_exit(idx); 280 return -1; 281 } 282 283 wreg_seq(cirrus, 0x7, sr07); 284 285 /* Program the pitch */ 286 cirrus->pitch = cirrus_pitch(fb); 287 tmp = cirrus->pitch / 8; 288 wreg_crt(cirrus, VGA_CRTC_OFFSET, tmp); 289 290 /* Enable extended blanking and pitch bits, and enable full memory */ 291 tmp = 0x22; 292 tmp |= (cirrus->pitch >> 7) & 0x10; 293 tmp |= (cirrus->pitch >> 6) & 0x40; 294 wreg_crt(cirrus, 0x1b, tmp); 295 296 /* Enable high-colour modes */ 297 wreg_gfx(cirrus, VGA_GFX_MODE, 0x40); 298 299 /* And set graphics mode */ 300 wreg_gfx(cirrus, VGA_GFX_MISC, 0x01); 301 302 wreg_hdr(cirrus, hdr); 303 304 cirrus_set_start_address(cirrus, 0); 305 306 /* Unblank (needed on S3 resume, vgabios doesn't do it then) */ 307 outb(0x20, 0x3c0); 308 309 drm_dev_exit(idx); 310 return 0; 311 } 312 313 static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, 314 struct drm_rect *rect) 315 { 316 struct cirrus_device *cirrus = to_cirrus(fb->dev); 317 void *vmap; 318 int idx, ret; 319 320 ret = -ENODEV; 321 if (!drm_dev_enter(&cirrus->dev, &idx)) 322 goto out; 323 324 ret = -ENOMEM; 325 vmap = drm_gem_shmem_vmap(fb->obj[0]); 326 if (!vmap) 327 goto out_dev_exit; 328 329 if (cirrus->cpp == fb->format->cpp[0]) 330 drm_fb_memcpy_dstclip(cirrus->vram, 331 vmap, fb, rect); 332 333 else if (fb->format->cpp[0] == 4 && cirrus->cpp == 2) 334 drm_fb_xrgb8888_to_rgb565_dstclip(cirrus->vram, 335 cirrus->pitch, 336 vmap, fb, rect, false); 337 338 else if (fb->format->cpp[0] == 4 && cirrus->cpp == 3) 339 drm_fb_xrgb8888_to_rgb888_dstclip(cirrus->vram, 340 cirrus->pitch, 341 vmap, fb, rect); 342 343 else 344 WARN_ON_ONCE("cpp mismatch"); 345 346 drm_gem_shmem_vunmap(fb->obj[0], vmap); 347 ret = 0; 348 349 out_dev_exit: 350 drm_dev_exit(idx); 351 out: 352 return ret; 353 } 354 355 static int cirrus_fb_blit_fullscreen(struct drm_framebuffer *fb) 356 { 357 struct drm_rect fullscreen = { 358 .x1 = 0, 359 .x2 = fb->width, 360 .y1 = 0, 361 .y2 = fb->height, 362 }; 363 return cirrus_fb_blit_rect(fb, &fullscreen); 364 } 365 366 static int cirrus_check_size(int width, int height, 367 struct drm_framebuffer *fb) 368 { 369 int pitch = width * 2; 370 371 if (fb) 372 pitch = cirrus_pitch(fb); 373 374 if (pitch > CIRRUS_MAX_PITCH) 375 return -EINVAL; 376 if (pitch * height > CIRRUS_VRAM_SIZE) 377 return -EINVAL; 378 return 0; 379 } 380 381 /* ------------------------------------------------------------------ */ 382 /* cirrus connector */ 383 384 static int cirrus_conn_get_modes(struct drm_connector *conn) 385 { 386 int count; 387 388 count = drm_add_modes_noedid(conn, 389 conn->dev->mode_config.max_width, 390 conn->dev->mode_config.max_height); 391 drm_set_preferred_mode(conn, 1024, 768); 392 return count; 393 } 394 395 static const struct drm_connector_helper_funcs cirrus_conn_helper_funcs = { 396 .get_modes = cirrus_conn_get_modes, 397 }; 398 399 static const struct drm_connector_funcs cirrus_conn_funcs = { 400 .fill_modes = drm_helper_probe_single_connector_modes, 401 .destroy = drm_connector_cleanup, 402 .reset = drm_atomic_helper_connector_reset, 403 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 404 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 405 }; 406 407 static int cirrus_conn_init(struct cirrus_device *cirrus) 408 { 409 drm_connector_helper_add(&cirrus->conn, &cirrus_conn_helper_funcs); 410 return drm_connector_init(&cirrus->dev, &cirrus->conn, 411 &cirrus_conn_funcs, DRM_MODE_CONNECTOR_VGA); 412 413 } 414 415 /* ------------------------------------------------------------------ */ 416 /* cirrus (simple) display pipe */ 417 418 static enum drm_mode_status cirrus_pipe_mode_valid(struct drm_simple_display_pipe *pipe, 419 const struct drm_display_mode *mode) 420 { 421 if (cirrus_check_size(mode->hdisplay, mode->vdisplay, NULL) < 0) 422 return MODE_BAD; 423 return MODE_OK; 424 } 425 426 static int cirrus_pipe_check(struct drm_simple_display_pipe *pipe, 427 struct drm_plane_state *plane_state, 428 struct drm_crtc_state *crtc_state) 429 { 430 struct drm_framebuffer *fb = plane_state->fb; 431 432 if (!fb) 433 return 0; 434 return cirrus_check_size(fb->width, fb->height, fb); 435 } 436 437 static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, 438 struct drm_crtc_state *crtc_state, 439 struct drm_plane_state *plane_state) 440 { 441 struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); 442 443 cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb); 444 cirrus_fb_blit_fullscreen(plane_state->fb); 445 } 446 447 static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, 448 struct drm_plane_state *old_state) 449 { 450 struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); 451 struct drm_plane_state *state = pipe->plane.state; 452 struct drm_crtc *crtc = &pipe->crtc; 453 struct drm_rect rect; 454 455 if (pipe->plane.state->fb && 456 cirrus->cpp != cirrus_cpp(pipe->plane.state->fb)) 457 cirrus_mode_set(cirrus, &crtc->mode, 458 pipe->plane.state->fb); 459 460 if (drm_atomic_helper_damage_merged(old_state, state, &rect)) 461 cirrus_fb_blit_rect(pipe->plane.state->fb, &rect); 462 } 463 464 static const struct drm_simple_display_pipe_funcs cirrus_pipe_funcs = { 465 .mode_valid = cirrus_pipe_mode_valid, 466 .check = cirrus_pipe_check, 467 .enable = cirrus_pipe_enable, 468 .update = cirrus_pipe_update, 469 }; 470 471 static const uint32_t cirrus_formats[] = { 472 DRM_FORMAT_RGB565, 473 DRM_FORMAT_RGB888, 474 DRM_FORMAT_XRGB8888, 475 }; 476 477 static const uint64_t cirrus_modifiers[] = { 478 DRM_FORMAT_MOD_LINEAR, 479 DRM_FORMAT_MOD_INVALID 480 }; 481 482 static int cirrus_pipe_init(struct cirrus_device *cirrus) 483 { 484 return drm_simple_display_pipe_init(&cirrus->dev, 485 &cirrus->pipe, 486 &cirrus_pipe_funcs, 487 cirrus_formats, 488 ARRAY_SIZE(cirrus_formats), 489 cirrus_modifiers, 490 &cirrus->conn); 491 } 492 493 /* ------------------------------------------------------------------ */ 494 /* cirrus framebuffers & mode config */ 495 496 static struct drm_framebuffer* 497 cirrus_fb_create(struct drm_device *dev, struct drm_file *file_priv, 498 const struct drm_mode_fb_cmd2 *mode_cmd) 499 { 500 if (mode_cmd->pixel_format != DRM_FORMAT_RGB565 && 501 mode_cmd->pixel_format != DRM_FORMAT_RGB888 && 502 mode_cmd->pixel_format != DRM_FORMAT_XRGB8888) 503 return ERR_PTR(-EINVAL); 504 if (cirrus_check_size(mode_cmd->width, mode_cmd->height, NULL) < 0) 505 return ERR_PTR(-EINVAL); 506 return drm_gem_fb_create_with_dirty(dev, file_priv, mode_cmd); 507 } 508 509 static const struct drm_mode_config_funcs cirrus_mode_config_funcs = { 510 .fb_create = cirrus_fb_create, 511 .atomic_check = drm_atomic_helper_check, 512 .atomic_commit = drm_atomic_helper_commit, 513 }; 514 515 static int cirrus_mode_config_init(struct cirrus_device *cirrus) 516 { 517 struct drm_device *dev = &cirrus->dev; 518 int ret; 519 520 ret = drmm_mode_config_init(dev); 521 if (ret) 522 return ret; 523 524 dev->mode_config.min_width = 0; 525 dev->mode_config.min_height = 0; 526 dev->mode_config.max_width = CIRRUS_MAX_PITCH / 2; 527 dev->mode_config.max_height = 1024; 528 dev->mode_config.preferred_depth = 16; 529 dev->mode_config.prefer_shadow = 0; 530 dev->mode_config.funcs = &cirrus_mode_config_funcs; 531 532 return 0; 533 } 534 535 /* ------------------------------------------------------------------ */ 536 537 DEFINE_DRM_GEM_FOPS(cirrus_fops); 538 539 static struct drm_driver cirrus_driver = { 540 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, 541 542 .name = DRIVER_NAME, 543 .desc = DRIVER_DESC, 544 .date = DRIVER_DATE, 545 .major = DRIVER_MAJOR, 546 .minor = DRIVER_MINOR, 547 548 .fops = &cirrus_fops, 549 DRM_GEM_SHMEM_DRIVER_OPS, 550 }; 551 552 static int cirrus_pci_probe(struct pci_dev *pdev, 553 const struct pci_device_id *ent) 554 { 555 struct drm_device *dev; 556 struct cirrus_device *cirrus; 557 int ret; 558 559 ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "cirrusdrmfb"); 560 if (ret) 561 return ret; 562 563 ret = pcim_enable_device(pdev); 564 if (ret) 565 return ret; 566 567 ret = pci_request_regions(pdev, DRIVER_NAME); 568 if (ret) 569 return ret; 570 571 ret = -ENOMEM; 572 cirrus = devm_drm_dev_alloc(&pdev->dev, &cirrus_driver, 573 struct cirrus_device, dev); 574 if (IS_ERR(cirrus)) 575 return PTR_ERR(cirrus); 576 577 dev = &cirrus->dev; 578 579 cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), 580 pci_resource_len(pdev, 0)); 581 if (cirrus->vram == NULL) 582 return -ENOMEM; 583 584 cirrus->mmio = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 1), 585 pci_resource_len(pdev, 1)); 586 if (cirrus->mmio == NULL) 587 return -ENOMEM; 588 589 ret = cirrus_mode_config_init(cirrus); 590 if (ret) 591 return ret; 592 593 ret = cirrus_conn_init(cirrus); 594 if (ret < 0) 595 return ret; 596 597 ret = cirrus_pipe_init(cirrus); 598 if (ret < 0) 599 return ret; 600 601 drm_mode_config_reset(dev); 602 603 dev->pdev = pdev; 604 pci_set_drvdata(pdev, dev); 605 ret = drm_dev_register(dev, 0); 606 if (ret) 607 return ret; 608 609 drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth); 610 return 0; 611 } 612 613 static void cirrus_pci_remove(struct pci_dev *pdev) 614 { 615 struct drm_device *dev = pci_get_drvdata(pdev); 616 617 drm_dev_unplug(dev); 618 drm_atomic_helper_shutdown(dev); 619 } 620 621 static const struct pci_device_id pciidlist[] = { 622 { 623 .vendor = PCI_VENDOR_ID_CIRRUS, 624 .device = PCI_DEVICE_ID_CIRRUS_5446, 625 /* only bind to the cirrus chip in qemu */ 626 .subvendor = PCI_SUBVENDOR_ID_REDHAT_QUMRANET, 627 .subdevice = PCI_SUBDEVICE_ID_QEMU, 628 }, { 629 .vendor = PCI_VENDOR_ID_CIRRUS, 630 .device = PCI_DEVICE_ID_CIRRUS_5446, 631 .subvendor = PCI_VENDOR_ID_XEN, 632 .subdevice = 0x0001, 633 }, 634 { /* end if list */ } 635 }; 636 637 static struct pci_driver cirrus_pci_driver = { 638 .name = DRIVER_NAME, 639 .id_table = pciidlist, 640 .probe = cirrus_pci_probe, 641 .remove = cirrus_pci_remove, 642 }; 643 644 static int __init cirrus_init(void) 645 { 646 if (vgacon_text_force()) 647 return -EINVAL; 648 return pci_register_driver(&cirrus_pci_driver); 649 } 650 651 static void __exit cirrus_exit(void) 652 { 653 pci_unregister_driver(&cirrus_pci_driver); 654 } 655 656 module_init(cirrus_init); 657 module_exit(cirrus_exit); 658 659 MODULE_DEVICE_TABLE(pci, pciidlist); 660 MODULE_LICENSE("GPL"); 661