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 52struct 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 77static 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 83static 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 92static 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 98static 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 107static 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 115static 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 124static 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 137static 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 146static 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 155static 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 182static 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 313static 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 349out_dev_exit: 350 drm_dev_exit(idx); 351out: 352 return ret; 353} 354 355static 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 366static 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 384static 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 395static const struct drm_connector_helper_funcs cirrus_conn_helper_funcs = { 396 .get_modes = cirrus_conn_get_modes, 397}; 398 399static 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 407static 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 418static 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 426static 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 437static 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 447static 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 464static 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 471static const uint32_t cirrus_formats[] = { 472 DRM_FORMAT_RGB565, 473 DRM_FORMAT_RGB888, 474 DRM_FORMAT_XRGB8888, 475}; 476 477static const uint64_t cirrus_modifiers[] = { 478 DRM_FORMAT_MOD_LINEAR, 479 DRM_FORMAT_MOD_INVALID 480}; 481 482static 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 496static struct drm_framebuffer* 497cirrus_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 509static 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 515static 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 537DEFINE_DRM_GEM_FOPS(cirrus_fops); 538 539static 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 552static 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 613static 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 621static 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 637static 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 644static int __init cirrus_init(void) 645{ 646 if (vgacon_text_force()) 647 return -EINVAL; 648 return pci_register_driver(&cirrus_pci_driver); 649} 650 651static void __exit cirrus_exit(void) 652{ 653 pci_unregister_driver(&cirrus_pci_driver); 654} 655 656module_init(cirrus_init); 657module_exit(cirrus_exit); 658 659MODULE_DEVICE_TABLE(pci, pciidlist); 660MODULE_LICENSE("GPL"); 661