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