Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.8 628 lines 15 kB view raw
1 2/* 3 * Copyright 2012 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 * 12 * Portions of this code derived from cirrusfb.c: 13 * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets 14 * 15 * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> 16 */ 17#include <drm/drmP.h> 18#include <drm/drm_crtc_helper.h> 19 20#include <video/cirrus.h> 21 22#include "cirrus_drv.h" 23 24#define CIRRUS_LUT_SIZE 256 25 26#define PALETTE_INDEX 0x8 27#define PALETTE_DATA 0x9 28 29/* 30 * This file contains setup code for the CRTC. 31 */ 32 33static void cirrus_crtc_load_lut(struct drm_crtc *crtc) 34{ 35 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); 36 struct drm_device *dev = crtc->dev; 37 struct cirrus_device *cdev = dev->dev_private; 38 int i; 39 40 if (!crtc->enabled) 41 return; 42 43 for (i = 0; i < CIRRUS_LUT_SIZE; i++) { 44 /* VGA registers */ 45 WREG8(PALETTE_INDEX, i); 46 WREG8(PALETTE_DATA, cirrus_crtc->lut_r[i]); 47 WREG8(PALETTE_DATA, cirrus_crtc->lut_g[i]); 48 WREG8(PALETTE_DATA, cirrus_crtc->lut_b[i]); 49 } 50} 51 52/* 53 * The DRM core requires DPMS functions, but they make little sense in our 54 * case and so are just stubs 55 */ 56 57static void cirrus_crtc_dpms(struct drm_crtc *crtc, int mode) 58{ 59 struct drm_device *dev = crtc->dev; 60 struct cirrus_device *cdev = dev->dev_private; 61 u8 sr01, gr0e; 62 63 switch (mode) { 64 case DRM_MODE_DPMS_ON: 65 sr01 = 0x00; 66 gr0e = 0x00; 67 break; 68 case DRM_MODE_DPMS_STANDBY: 69 sr01 = 0x20; 70 gr0e = 0x02; 71 break; 72 case DRM_MODE_DPMS_SUSPEND: 73 sr01 = 0x20; 74 gr0e = 0x04; 75 break; 76 case DRM_MODE_DPMS_OFF: 77 sr01 = 0x20; 78 gr0e = 0x06; 79 break; 80 default: 81 return; 82 } 83 84 WREG8(SEQ_INDEX, 0x1); 85 sr01 |= RREG8(SEQ_DATA) & ~0x20; 86 WREG_SEQ(0x1, sr01); 87 88 WREG8(GFX_INDEX, 0xe); 89 gr0e |= RREG8(GFX_DATA) & ~0x06; 90 WREG_GFX(0xe, gr0e); 91} 92 93/* 94 * The core passes the desired mode to the CRTC code to see whether any 95 * CRTC-specific modifications need to be made to it. We're in a position 96 * to just pass that straight through, so this does nothing 97 */ 98static bool cirrus_crtc_mode_fixup(struct drm_crtc *crtc, 99 const struct drm_display_mode *mode, 100 struct drm_display_mode *adjusted_mode) 101{ 102 return true; 103} 104 105void cirrus_set_start_address(struct drm_crtc *crtc, unsigned offset) 106{ 107 struct cirrus_device *cdev = crtc->dev->dev_private; 108 u32 addr; 109 u8 tmp; 110 111 addr = offset >> 2; 112 WREG_CRT(0x0c, (u8)((addr >> 8) & 0xff)); 113 WREG_CRT(0x0d, (u8)(addr & 0xff)); 114 115 WREG8(CRT_INDEX, 0x1b); 116 tmp = RREG8(CRT_DATA); 117 tmp &= 0xf2; 118 tmp |= (addr >> 16) & 0x01; 119 tmp |= (addr >> 15) & 0x0c; 120 WREG_CRT(0x1b, tmp); 121 WREG8(CRT_INDEX, 0x1d); 122 tmp = RREG8(CRT_DATA); 123 tmp &= 0x7f; 124 tmp |= (addr >> 12) & 0x80; 125 WREG_CRT(0x1d, tmp); 126} 127 128/* cirrus is different - we will force move buffers out of VRAM */ 129static int cirrus_crtc_do_set_base(struct drm_crtc *crtc, 130 struct drm_framebuffer *fb, 131 int x, int y, int atomic) 132{ 133 struct cirrus_device *cdev = crtc->dev->dev_private; 134 struct drm_gem_object *obj; 135 struct cirrus_framebuffer *cirrus_fb; 136 struct cirrus_bo *bo; 137 int ret; 138 u64 gpu_addr; 139 140 /* push the previous fb to system ram */ 141 if (!atomic && fb) { 142 cirrus_fb = to_cirrus_framebuffer(fb); 143 obj = cirrus_fb->obj; 144 bo = gem_to_cirrus_bo(obj); 145 ret = cirrus_bo_reserve(bo, false); 146 if (ret) 147 return ret; 148 cirrus_bo_push_sysram(bo); 149 cirrus_bo_unreserve(bo); 150 } 151 152 cirrus_fb = to_cirrus_framebuffer(crtc->fb); 153 obj = cirrus_fb->obj; 154 bo = gem_to_cirrus_bo(obj); 155 156 ret = cirrus_bo_reserve(bo, false); 157 if (ret) 158 return ret; 159 160 ret = cirrus_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); 161 if (ret) { 162 cirrus_bo_unreserve(bo); 163 return ret; 164 } 165 166 if (&cdev->mode_info.gfbdev->gfb == cirrus_fb) { 167 /* if pushing console in kmap it */ 168 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); 169 if (ret) 170 DRM_ERROR("failed to kmap fbcon\n"); 171 } 172 cirrus_bo_unreserve(bo); 173 174 cirrus_set_start_address(crtc, (u32)gpu_addr); 175 return 0; 176} 177 178static int cirrus_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 179 struct drm_framebuffer *old_fb) 180{ 181 return cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0); 182} 183 184/* 185 * The meat of this driver. The core passes us a mode and we have to program 186 * it. The modesetting here is the bare minimum required to satisfy the qemu 187 * emulation of this hardware, and running this against a real device is 188 * likely to result in an inadequately programmed mode. We've already had 189 * the opportunity to modify the mode, so whatever we receive here should 190 * be something that can be correctly programmed and displayed 191 */ 192static int cirrus_crtc_mode_set(struct drm_crtc *crtc, 193 struct drm_display_mode *mode, 194 struct drm_display_mode *adjusted_mode, 195 int x, int y, struct drm_framebuffer *old_fb) 196{ 197 struct drm_device *dev = crtc->dev; 198 struct cirrus_device *cdev = dev->dev_private; 199 int hsyncstart, hsyncend, htotal, hdispend; 200 int vtotal, vdispend; 201 int tmp; 202 int sr07 = 0, hdr = 0; 203 204 htotal = mode->htotal / 8; 205 hsyncend = mode->hsync_end / 8; 206 hsyncstart = mode->hsync_start / 8; 207 hdispend = mode->hdisplay / 8; 208 209 vtotal = mode->vtotal; 210 vdispend = mode->vdisplay; 211 212 vdispend -= 1; 213 vtotal -= 2; 214 215 htotal -= 5; 216 hdispend -= 1; 217 hsyncstart += 1; 218 hsyncend += 1; 219 220 WREG_CRT(VGA_CRTC_V_SYNC_END, 0x20); 221 WREG_CRT(VGA_CRTC_H_TOTAL, htotal); 222 WREG_CRT(VGA_CRTC_H_DISP, hdispend); 223 WREG_CRT(VGA_CRTC_H_SYNC_START, hsyncstart); 224 WREG_CRT(VGA_CRTC_H_SYNC_END, hsyncend); 225 WREG_CRT(VGA_CRTC_V_TOTAL, vtotal & 0xff); 226 WREG_CRT(VGA_CRTC_V_DISP_END, vdispend & 0xff); 227 228 tmp = 0x40; 229 if ((vdispend + 1) & 512) 230 tmp |= 0x20; 231 WREG_CRT(VGA_CRTC_MAX_SCAN, tmp); 232 233 /* 234 * Overflow bits for values that don't fit in the standard registers 235 */ 236 tmp = 16; 237 if (vtotal & 256) 238 tmp |= 1; 239 if (vdispend & 256) 240 tmp |= 2; 241 if ((vdispend + 1) & 256) 242 tmp |= 8; 243 if (vtotal & 512) 244 tmp |= 32; 245 if (vdispend & 512) 246 tmp |= 64; 247 WREG_CRT(VGA_CRTC_OVERFLOW, tmp); 248 249 tmp = 0; 250 251 /* More overflow bits */ 252 253 if ((htotal + 5) & 64) 254 tmp |= 16; 255 if ((htotal + 5) & 128) 256 tmp |= 32; 257 if (vtotal & 256) 258 tmp |= 64; 259 if (vtotal & 512) 260 tmp |= 128; 261 262 WREG_CRT(CL_CRT1A, tmp); 263 264 /* Disable Hercules/CGA compatibility */ 265 WREG_CRT(VGA_CRTC_MODE, 0x03); 266 267 WREG8(SEQ_INDEX, 0x7); 268 sr07 = RREG8(SEQ_DATA); 269 sr07 &= 0xe0; 270 hdr = 0; 271 switch (crtc->fb->bits_per_pixel) { 272 case 8: 273 sr07 |= 0x11; 274 break; 275 case 16: 276 sr07 |= 0xc1; 277 hdr = 0xc0; 278 break; 279 case 24: 280 sr07 |= 0x15; 281 hdr = 0xc5; 282 break; 283 case 32: 284 sr07 |= 0x19; 285 hdr = 0xc5; 286 break; 287 default: 288 return -1; 289 } 290 291 WREG_SEQ(0x7, sr07); 292 293 /* Program the pitch */ 294 tmp = crtc->fb->pitches[0] / 8; 295 WREG_CRT(VGA_CRTC_OFFSET, tmp); 296 297 /* Enable extended blanking and pitch bits, and enable full memory */ 298 tmp = 0x22; 299 tmp |= (crtc->fb->pitches[0] >> 7) & 0x10; 300 tmp |= (crtc->fb->pitches[0] >> 6) & 0x40; 301 WREG_CRT(0x1b, tmp); 302 303 /* Enable high-colour modes */ 304 WREG_GFX(VGA_GFX_MODE, 0x40); 305 306 /* And set graphics mode */ 307 WREG_GFX(VGA_GFX_MISC, 0x01); 308 309 WREG_HDR(hdr); 310 cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0); 311 return 0; 312} 313 314/* 315 * This is called before a mode is programmed. A typical use might be to 316 * enable DPMS during the programming to avoid seeing intermediate stages, 317 * but that's not relevant to us 318 */ 319static void cirrus_crtc_prepare(struct drm_crtc *crtc) 320{ 321} 322 323/* 324 * This is called after a mode is programmed. It should reverse anything done 325 * by the prepare function 326 */ 327static void cirrus_crtc_commit(struct drm_crtc *crtc) 328{ 329} 330 331/* 332 * The core can pass us a set of gamma values to program. We actually only 333 * use this for 8-bit mode so can't perform smooth fades on deeper modes, 334 * but it's a requirement that we provide the function 335 */ 336static void cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 337 u16 *blue, uint32_t start, uint32_t size) 338{ 339 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); 340 int i; 341 342 if (size != CIRRUS_LUT_SIZE) 343 return; 344 345 for (i = 0; i < CIRRUS_LUT_SIZE; i++) { 346 cirrus_crtc->lut_r[i] = red[i]; 347 cirrus_crtc->lut_g[i] = green[i]; 348 cirrus_crtc->lut_b[i] = blue[i]; 349 } 350 cirrus_crtc_load_lut(crtc); 351} 352 353/* Simple cleanup function */ 354static void cirrus_crtc_destroy(struct drm_crtc *crtc) 355{ 356 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); 357 358 drm_crtc_cleanup(crtc); 359 kfree(cirrus_crtc); 360} 361 362/* These provide the minimum set of functions required to handle a CRTC */ 363static const struct drm_crtc_funcs cirrus_crtc_funcs = { 364 .gamma_set = cirrus_crtc_gamma_set, 365 .set_config = drm_crtc_helper_set_config, 366 .destroy = cirrus_crtc_destroy, 367}; 368 369static const struct drm_crtc_helper_funcs cirrus_helper_funcs = { 370 .dpms = cirrus_crtc_dpms, 371 .mode_fixup = cirrus_crtc_mode_fixup, 372 .mode_set = cirrus_crtc_mode_set, 373 .mode_set_base = cirrus_crtc_mode_set_base, 374 .prepare = cirrus_crtc_prepare, 375 .commit = cirrus_crtc_commit, 376 .load_lut = cirrus_crtc_load_lut, 377}; 378 379/* CRTC setup */ 380static void cirrus_crtc_init(struct drm_device *dev) 381{ 382 struct cirrus_device *cdev = dev->dev_private; 383 struct cirrus_crtc *cirrus_crtc; 384 int i; 385 386 cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) + 387 (CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)), 388 GFP_KERNEL); 389 390 if (cirrus_crtc == NULL) 391 return; 392 393 drm_crtc_init(dev, &cirrus_crtc->base, &cirrus_crtc_funcs); 394 395 drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE); 396 cdev->mode_info.crtc = cirrus_crtc; 397 398 for (i = 0; i < CIRRUS_LUT_SIZE; i++) { 399 cirrus_crtc->lut_r[i] = i; 400 cirrus_crtc->lut_g[i] = i; 401 cirrus_crtc->lut_b[i] = i; 402 } 403 404 drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs); 405} 406 407/** Sets the color ramps on behalf of fbcon */ 408void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, 409 u16 blue, int regno) 410{ 411 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); 412 413 cirrus_crtc->lut_r[regno] = red; 414 cirrus_crtc->lut_g[regno] = green; 415 cirrus_crtc->lut_b[regno] = blue; 416} 417 418/** Gets the color ramps on behalf of fbcon */ 419void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, 420 u16 *blue, int regno) 421{ 422 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); 423 424 *red = cirrus_crtc->lut_r[regno]; 425 *green = cirrus_crtc->lut_g[regno]; 426 *blue = cirrus_crtc->lut_b[regno]; 427} 428 429 430static bool cirrus_encoder_mode_fixup(struct drm_encoder *encoder, 431 const struct drm_display_mode *mode, 432 struct drm_display_mode *adjusted_mode) 433{ 434 return true; 435} 436 437static void cirrus_encoder_mode_set(struct drm_encoder *encoder, 438 struct drm_display_mode *mode, 439 struct drm_display_mode *adjusted_mode) 440{ 441} 442 443static void cirrus_encoder_dpms(struct drm_encoder *encoder, int state) 444{ 445 return; 446} 447 448static void cirrus_encoder_prepare(struct drm_encoder *encoder) 449{ 450} 451 452static void cirrus_encoder_commit(struct drm_encoder *encoder) 453{ 454} 455 456void cirrus_encoder_destroy(struct drm_encoder *encoder) 457{ 458 struct cirrus_encoder *cirrus_encoder = to_cirrus_encoder(encoder); 459 drm_encoder_cleanup(encoder); 460 kfree(cirrus_encoder); 461} 462 463static const struct drm_encoder_helper_funcs cirrus_encoder_helper_funcs = { 464 .dpms = cirrus_encoder_dpms, 465 .mode_fixup = cirrus_encoder_mode_fixup, 466 .mode_set = cirrus_encoder_mode_set, 467 .prepare = cirrus_encoder_prepare, 468 .commit = cirrus_encoder_commit, 469}; 470 471static const struct drm_encoder_funcs cirrus_encoder_encoder_funcs = { 472 .destroy = cirrus_encoder_destroy, 473}; 474 475static struct drm_encoder *cirrus_encoder_init(struct drm_device *dev) 476{ 477 struct drm_encoder *encoder; 478 struct cirrus_encoder *cirrus_encoder; 479 480 cirrus_encoder = kzalloc(sizeof(struct cirrus_encoder), GFP_KERNEL); 481 if (!cirrus_encoder) 482 return NULL; 483 484 encoder = &cirrus_encoder->base; 485 encoder->possible_crtcs = 0x1; 486 487 drm_encoder_init(dev, encoder, &cirrus_encoder_encoder_funcs, 488 DRM_MODE_ENCODER_DAC); 489 drm_encoder_helper_add(encoder, &cirrus_encoder_helper_funcs); 490 491 return encoder; 492} 493 494 495int cirrus_vga_get_modes(struct drm_connector *connector) 496{ 497 /* Just add a static list of modes */ 498 drm_add_modes_noedid(connector, 640, 480); 499 drm_add_modes_noedid(connector, 800, 600); 500 drm_add_modes_noedid(connector, 1024, 768); 501 drm_add_modes_noedid(connector, 1280, 1024); 502 503 return 4; 504} 505 506static int cirrus_vga_mode_valid(struct drm_connector *connector, 507 struct drm_display_mode *mode) 508{ 509 /* Any mode we've added is valid */ 510 return MODE_OK; 511} 512 513struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector 514 *connector) 515{ 516 int enc_id = connector->encoder_ids[0]; 517 struct drm_mode_object *obj; 518 struct drm_encoder *encoder; 519 520 /* pick the encoder ids */ 521 if (enc_id) { 522 obj = 523 drm_mode_object_find(connector->dev, enc_id, 524 DRM_MODE_OBJECT_ENCODER); 525 if (!obj) 526 return NULL; 527 encoder = obj_to_encoder(obj); 528 return encoder; 529 } 530 return NULL; 531} 532 533static enum drm_connector_status cirrus_vga_detect(struct drm_connector 534 *connector, bool force) 535{ 536 return connector_status_connected; 537} 538 539static void cirrus_connector_destroy(struct drm_connector *connector) 540{ 541 drm_connector_cleanup(connector); 542 kfree(connector); 543} 544 545struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs = { 546 .get_modes = cirrus_vga_get_modes, 547 .mode_valid = cirrus_vga_mode_valid, 548 .best_encoder = cirrus_connector_best_encoder, 549}; 550 551struct drm_connector_funcs cirrus_vga_connector_funcs = { 552 .dpms = drm_helper_connector_dpms, 553 .detect = cirrus_vga_detect, 554 .fill_modes = drm_helper_probe_single_connector_modes, 555 .destroy = cirrus_connector_destroy, 556}; 557 558static struct drm_connector *cirrus_vga_init(struct drm_device *dev) 559{ 560 struct drm_connector *connector; 561 struct cirrus_connector *cirrus_connector; 562 563 cirrus_connector = kzalloc(sizeof(struct cirrus_connector), GFP_KERNEL); 564 if (!cirrus_connector) 565 return NULL; 566 567 connector = &cirrus_connector->base; 568 569 drm_connector_init(dev, connector, 570 &cirrus_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA); 571 572 drm_connector_helper_add(connector, &cirrus_vga_connector_helper_funcs); 573 574 return connector; 575} 576 577 578int cirrus_modeset_init(struct cirrus_device *cdev) 579{ 580 struct drm_encoder *encoder; 581 struct drm_connector *connector; 582 int ret; 583 584 drm_mode_config_init(cdev->dev); 585 cdev->mode_info.mode_config_initialized = true; 586 587 cdev->dev->mode_config.max_width = CIRRUS_MAX_FB_WIDTH; 588 cdev->dev->mode_config.max_height = CIRRUS_MAX_FB_HEIGHT; 589 590 cdev->dev->mode_config.fb_base = cdev->mc.vram_base; 591 cdev->dev->mode_config.preferred_depth = 24; 592 /* don't prefer a shadow on virt GPU */ 593 cdev->dev->mode_config.prefer_shadow = 0; 594 595 cirrus_crtc_init(cdev->dev); 596 597 encoder = cirrus_encoder_init(cdev->dev); 598 if (!encoder) { 599 DRM_ERROR("cirrus_encoder_init failed\n"); 600 return -1; 601 } 602 603 connector = cirrus_vga_init(cdev->dev); 604 if (!connector) { 605 DRM_ERROR("cirrus_vga_init failed\n"); 606 return -1; 607 } 608 609 drm_mode_connector_attach_encoder(connector, encoder); 610 611 ret = cirrus_fbdev_init(cdev); 612 if (ret) { 613 DRM_ERROR("cirrus_fbdev_init failed\n"); 614 return ret; 615 } 616 617 return 0; 618} 619 620void cirrus_modeset_fini(struct cirrus_device *cdev) 621{ 622 cirrus_fbdev_fini(cdev); 623 624 if (cdev->mode_info.mode_config_initialized) { 625 drm_mode_config_cleanup(cdev->dev); 626 cdev->mode_info.mode_config_initialized = false; 627 } 628}