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.14-rc6 552 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 297/* 298 * This is called after a mode is programmed. It should reverse anything done 299 * by the prepare function 300 */ 301static void cirrus_crtc_commit(struct drm_crtc *crtc) 302{ 303} 304 305/* 306 * The core can pass us a set of gamma values to program. We actually only 307 * use this for 8-bit mode so can't perform smooth fades on deeper modes, 308 * but it's a requirement that we provide the function 309 */ 310static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 311 u16 *blue, uint32_t size, 312 struct drm_modeset_acquire_ctx *ctx) 313{ 314 struct drm_device *dev = crtc->dev; 315 struct cirrus_device *cdev = dev->dev_private; 316 u16 *r, *g, *b; 317 int i; 318 319 if (!crtc->enabled) 320 return 0; 321 322 r = crtc->gamma_store; 323 g = r + crtc->gamma_size; 324 b = g + crtc->gamma_size; 325 326 for (i = 0; i < CIRRUS_LUT_SIZE; i++) { 327 /* VGA registers */ 328 WREG8(PALETTE_INDEX, i); 329 WREG8(PALETTE_DATA, *r++ >> 8); 330 WREG8(PALETTE_DATA, *g++ >> 8); 331 WREG8(PALETTE_DATA, *b++ >> 8); 332 } 333 334 return 0; 335} 336 337/* Simple cleanup function */ 338static void cirrus_crtc_destroy(struct drm_crtc *crtc) 339{ 340 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); 341 342 drm_crtc_cleanup(crtc); 343 kfree(cirrus_crtc); 344} 345 346/* These provide the minimum set of functions required to handle a CRTC */ 347static const struct drm_crtc_funcs cirrus_crtc_funcs = { 348 .gamma_set = cirrus_crtc_gamma_set, 349 .set_config = drm_crtc_helper_set_config, 350 .destroy = cirrus_crtc_destroy, 351}; 352 353static const struct drm_crtc_helper_funcs cirrus_helper_funcs = { 354 .dpms = cirrus_crtc_dpms, 355 .mode_set = cirrus_crtc_mode_set, 356 .mode_set_base = cirrus_crtc_mode_set_base, 357 .prepare = cirrus_crtc_prepare, 358 .commit = cirrus_crtc_commit, 359}; 360 361/* CRTC setup */ 362static void cirrus_crtc_init(struct drm_device *dev) 363{ 364 struct cirrus_device *cdev = dev->dev_private; 365 struct cirrus_crtc *cirrus_crtc; 366 367 cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) + 368 (CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)), 369 GFP_KERNEL); 370 371 if (cirrus_crtc == NULL) 372 return; 373 374 drm_crtc_init(dev, &cirrus_crtc->base, &cirrus_crtc_funcs); 375 376 drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE); 377 cdev->mode_info.crtc = cirrus_crtc; 378 379 drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs); 380} 381 382static void cirrus_encoder_mode_set(struct drm_encoder *encoder, 383 struct drm_display_mode *mode, 384 struct drm_display_mode *adjusted_mode) 385{ 386} 387 388static void cirrus_encoder_dpms(struct drm_encoder *encoder, int state) 389{ 390 return; 391} 392 393static void cirrus_encoder_prepare(struct drm_encoder *encoder) 394{ 395} 396 397static void cirrus_encoder_commit(struct drm_encoder *encoder) 398{ 399} 400 401static void cirrus_encoder_destroy(struct drm_encoder *encoder) 402{ 403 struct cirrus_encoder *cirrus_encoder = to_cirrus_encoder(encoder); 404 drm_encoder_cleanup(encoder); 405 kfree(cirrus_encoder); 406} 407 408static const struct drm_encoder_helper_funcs cirrus_encoder_helper_funcs = { 409 .dpms = cirrus_encoder_dpms, 410 .mode_set = cirrus_encoder_mode_set, 411 .prepare = cirrus_encoder_prepare, 412 .commit = cirrus_encoder_commit, 413}; 414 415static const struct drm_encoder_funcs cirrus_encoder_encoder_funcs = { 416 .destroy = cirrus_encoder_destroy, 417}; 418 419static struct drm_encoder *cirrus_encoder_init(struct drm_device *dev) 420{ 421 struct drm_encoder *encoder; 422 struct cirrus_encoder *cirrus_encoder; 423 424 cirrus_encoder = kzalloc(sizeof(struct cirrus_encoder), GFP_KERNEL); 425 if (!cirrus_encoder) 426 return NULL; 427 428 encoder = &cirrus_encoder->base; 429 encoder->possible_crtcs = 0x1; 430 431 drm_encoder_init(dev, encoder, &cirrus_encoder_encoder_funcs, 432 DRM_MODE_ENCODER_DAC, NULL); 433 drm_encoder_helper_add(encoder, &cirrus_encoder_helper_funcs); 434 435 return encoder; 436} 437 438 439static int cirrus_vga_get_modes(struct drm_connector *connector) 440{ 441 int count; 442 443 /* Just add a static list of modes */ 444 if (cirrus_bpp <= 24) { 445 count = drm_add_modes_noedid(connector, 1280, 1024); 446 drm_set_preferred_mode(connector, 1024, 768); 447 } else { 448 count = drm_add_modes_noedid(connector, 800, 600); 449 drm_set_preferred_mode(connector, 800, 600); 450 } 451 return count; 452} 453 454static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector 455 *connector) 456{ 457 int enc_id = connector->encoder_ids[0]; 458 /* pick the encoder ids */ 459 if (enc_id) 460 return drm_encoder_find(connector->dev, enc_id); 461 return NULL; 462} 463 464static void cirrus_connector_destroy(struct drm_connector *connector) 465{ 466 drm_connector_cleanup(connector); 467 kfree(connector); 468} 469 470static const struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs = { 471 .get_modes = cirrus_vga_get_modes, 472 .best_encoder = cirrus_connector_best_encoder, 473}; 474 475static const struct drm_connector_funcs cirrus_vga_connector_funcs = { 476 .dpms = drm_helper_connector_dpms, 477 .fill_modes = drm_helper_probe_single_connector_modes, 478 .destroy = cirrus_connector_destroy, 479}; 480 481static struct drm_connector *cirrus_vga_init(struct drm_device *dev) 482{ 483 struct drm_connector *connector; 484 struct cirrus_connector *cirrus_connector; 485 486 cirrus_connector = kzalloc(sizeof(struct cirrus_connector), GFP_KERNEL); 487 if (!cirrus_connector) 488 return NULL; 489 490 connector = &cirrus_connector->base; 491 492 drm_connector_init(dev, connector, 493 &cirrus_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA); 494 495 drm_connector_helper_add(connector, &cirrus_vga_connector_helper_funcs); 496 497 drm_connector_register(connector); 498 return connector; 499} 500 501 502int cirrus_modeset_init(struct cirrus_device *cdev) 503{ 504 struct drm_encoder *encoder; 505 struct drm_connector *connector; 506 int ret; 507 508 drm_mode_config_init(cdev->dev); 509 cdev->mode_info.mode_config_initialized = true; 510 511 cdev->dev->mode_config.max_width = CIRRUS_MAX_FB_WIDTH; 512 cdev->dev->mode_config.max_height = CIRRUS_MAX_FB_HEIGHT; 513 514 cdev->dev->mode_config.fb_base = cdev->mc.vram_base; 515 cdev->dev->mode_config.preferred_depth = 24; 516 /* don't prefer a shadow on virt GPU */ 517 cdev->dev->mode_config.prefer_shadow = 0; 518 519 cirrus_crtc_init(cdev->dev); 520 521 encoder = cirrus_encoder_init(cdev->dev); 522 if (!encoder) { 523 DRM_ERROR("cirrus_encoder_init failed\n"); 524 return -1; 525 } 526 527 connector = cirrus_vga_init(cdev->dev); 528 if (!connector) { 529 DRM_ERROR("cirrus_vga_init failed\n"); 530 return -1; 531 } 532 533 drm_mode_connector_attach_encoder(connector, encoder); 534 535 ret = cirrus_fbdev_init(cdev); 536 if (ret) { 537 DRM_ERROR("cirrus_fbdev_init failed\n"); 538 return ret; 539 } 540 541 return 0; 542} 543 544void cirrus_modeset_fini(struct cirrus_device *cdev) 545{ 546 cirrus_fbdev_fini(cdev); 547 548 if (cdev->mode_info.mode_config_initialized) { 549 drm_mode_config_cleanup(cdev->dev); 550 cdev->mode_info.mode_config_initialized = false; 551 } 552}