root/drivers/gpu/drm/cirrus/cirrus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rreg_seq
  2. wreg_seq
  3. rreg_crt
  4. wreg_crt
  5. wreg_gfx
  6. wreg_hdr
  7. cirrus_convert_to
  8. cirrus_cpp
  9. cirrus_pitch
  10. cirrus_set_start_address
  11. cirrus_mode_set
  12. cirrus_fb_blit_rect
  13. cirrus_fb_blit_fullscreen
  14. cirrus_check_size
  15. cirrus_conn_get_modes
  16. cirrus_conn_init
  17. cirrus_pipe_mode_valid
  18. cirrus_pipe_check
  19. cirrus_pipe_enable
  20. cirrus_pipe_update
  21. cirrus_pipe_init
  22. cirrus_fb_create
  23. cirrus_mode_config_init
  24. cirrus_pci_probe
  25. cirrus_pci_remove
  26. cirrus_init
  27. cirrus_exit

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

/* [<][>][^][v][top][bottom][index][help] */