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