1 /* 2 * Copyright © 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Jesse Barnes <jbarnes@virtuousgeek.org> 25 * 26 * New plane/sprite handling. 27 * 28 * The older chips had a separate interface for programming plane related 29 * registers; newer ones are much simpler and we can use the new DRM plane 30 * support. 31 */ 32 #include <drm/drmP.h> 33 #include <drm/drm_crtc.h> 34 #include <uapi_drm/drm_fourcc.h> 35 #include <drm/drm_rect.h> 36 #include "intel_drv.h" 37 #include <drm/i915_drm.h> 38 #include "i915_drv.h" 39 40 static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) 41 { 42 /* paranoia */ 43 if (!mode->crtc_htotal) 44 return 1; 45 46 return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal); 47 } 48 49 static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count) 50 { 51 struct drm_device *dev = crtc->base.dev; 52 const struct drm_display_mode *mode = &crtc->config.adjusted_mode; 53 enum i915_pipe pipe = crtc->pipe; 54 long timeout = msecs_to_jiffies_timeout(1); 55 int scanline, min, max, vblank_start; 56 DEFINE_WAIT(wait); 57 58 WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex)); 59 60 vblank_start = mode->crtc_vblank_start; 61 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 62 vblank_start = DIV_ROUND_UP(vblank_start, 2); 63 64 /* FIXME needs to be calibrated sensibly */ 65 min = vblank_start - usecs_to_scanlines(mode, 100); 66 max = vblank_start - 1; 67 68 if (min <= 0 || max <= 0) 69 return false; 70 71 if (WARN_ON(drm_vblank_get(dev, pipe))) 72 return false; 73 74 local_irq_disable(); 75 76 trace_i915_pipe_update_start(crtc, min, max); 77 78 for (;;) { 79 /* 80 * prepare_to_wait() has a memory barrier, which guarantees 81 * other CPUs can see the task state update by the time we 82 * read the scanline. 83 */ 84 prepare_to_wait(&crtc->vbl_wait, &wait, TASK_UNINTERRUPTIBLE); 85 86 scanline = intel_get_crtc_scanline(crtc); 87 if (scanline < min || scanline > max) 88 break; 89 90 if (timeout <= 0) { 91 DRM_ERROR("Potential atomic update failure on pipe %c\n", 92 pipe_name(crtc->pipe)); 93 break; 94 } 95 96 local_irq_enable(); 97 98 timeout = schedule_timeout(timeout); 99 100 local_irq_disable(); 101 } 102 103 finish_wait(&crtc->vbl_wait, &wait); 104 105 drm_vblank_put(dev, pipe); 106 107 *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe); 108 109 trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count); 110 111 return true; 112 } 113 114 static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count) 115 { 116 struct drm_device *dev = crtc->base.dev; 117 enum i915_pipe pipe = crtc->pipe; 118 u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe); 119 120 trace_i915_pipe_update_end(crtc, end_vbl_count); 121 122 local_irq_enable(); 123 124 if (start_vbl_count != end_vbl_count) 125 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n", 126 pipe_name(pipe), start_vbl_count, end_vbl_count); 127 } 128 129 static void intel_update_primary_plane(struct intel_crtc *crtc) 130 { 131 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 132 int reg = DSPCNTR(crtc->plane); 133 134 if (crtc->primary_enabled) 135 I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); 136 else 137 I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); 138 } 139 140 static void 141 vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, 142 struct drm_framebuffer *fb, 143 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, 144 unsigned int crtc_w, unsigned int crtc_h, 145 uint32_t x, uint32_t y, 146 uint32_t src_w, uint32_t src_h) 147 { 148 struct drm_device *dev = dplane->dev; 149 struct drm_i915_private *dev_priv = dev->dev_private; 150 struct intel_plane *intel_plane = to_intel_plane(dplane); 151 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 152 int pipe = intel_plane->pipe; 153 int plane = intel_plane->plane; 154 u32 sprctl; 155 unsigned long sprsurf_offset, linear_offset; 156 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 157 u32 start_vbl_count; 158 bool atomic_update; 159 160 sprctl = I915_READ(SPCNTR(pipe, plane)); 161 162 /* Mask out pixel format bits in case we change it */ 163 sprctl &= ~SP_PIXFORMAT_MASK; 164 sprctl &= ~SP_YUV_BYTE_ORDER_MASK; 165 sprctl &= ~SP_TILED; 166 167 switch (fb->pixel_format) { 168 case DRM_FORMAT_YUYV: 169 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 170 break; 171 case DRM_FORMAT_YVYU: 172 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 173 break; 174 case DRM_FORMAT_UYVY: 175 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 176 break; 177 case DRM_FORMAT_VYUY: 178 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 179 break; 180 case DRM_FORMAT_RGB565: 181 sprctl |= SP_FORMAT_BGR565; 182 break; 183 case DRM_FORMAT_XRGB8888: 184 sprctl |= SP_FORMAT_BGRX8888; 185 break; 186 case DRM_FORMAT_ARGB8888: 187 sprctl |= SP_FORMAT_BGRA8888; 188 break; 189 case DRM_FORMAT_XBGR2101010: 190 sprctl |= SP_FORMAT_RGBX1010102; 191 break; 192 case DRM_FORMAT_ABGR2101010: 193 sprctl |= SP_FORMAT_RGBA1010102; 194 break; 195 case DRM_FORMAT_XBGR8888: 196 sprctl |= SP_FORMAT_RGBX8888; 197 break; 198 case DRM_FORMAT_ABGR8888: 199 sprctl |= SP_FORMAT_RGBA8888; 200 break; 201 default: 202 /* 203 * If we get here one of the upper layers failed to filter 204 * out the unsupported plane formats 205 */ 206 BUG(); 207 break; 208 } 209 210 /* 211 * Enable gamma to match primary/cursor plane behaviour. 212 * FIXME should be user controllable via propertiesa. 213 */ 214 sprctl |= SP_GAMMA_ENABLE; 215 216 if (obj->tiling_mode != I915_TILING_NONE) 217 sprctl |= SP_TILED; 218 219 sprctl |= SP_ENABLE; 220 221 intel_update_sprite_watermarks(dplane, crtc, src_w, src_h, 222 pixel_size, true, 223 src_w != crtc_w || src_h != crtc_h); 224 225 /* Sizes are 0 based */ 226 src_w--; 227 src_h--; 228 crtc_w--; 229 crtc_h--; 230 231 linear_offset = y * fb->pitches[0] + x * pixel_size; 232 sprsurf_offset = intel_gen4_compute_page_offset(&x, &y, 233 obj->tiling_mode, 234 pixel_size, 235 fb->pitches[0]); 236 linear_offset -= sprsurf_offset; 237 238 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 239 240 intel_update_primary_plane(intel_crtc); 241 242 I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); 243 I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); 244 245 if (obj->tiling_mode != I915_TILING_NONE) 246 I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x); 247 else 248 I915_WRITE(SPLINOFF(pipe, plane), linear_offset); 249 250 I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); 251 I915_WRITE(SPCNTR(pipe, plane), sprctl); 252 I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + 253 sprsurf_offset); 254 255 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 256 257 if (atomic_update) 258 intel_pipe_update_end(intel_crtc, start_vbl_count); 259 } 260 261 static void 262 vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) 263 { 264 struct drm_device *dev = dplane->dev; 265 struct drm_i915_private *dev_priv = dev->dev_private; 266 struct intel_plane *intel_plane = to_intel_plane(dplane); 267 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 268 int pipe = intel_plane->pipe; 269 int plane = intel_plane->plane; 270 u32 start_vbl_count; 271 bool atomic_update; 272 273 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 274 275 intel_update_primary_plane(intel_crtc); 276 277 I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & 278 ~SP_ENABLE); 279 /* Activate double buffered register update */ 280 I915_WRITE(SPSURF(pipe, plane), 0); 281 282 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 283 284 if (atomic_update) 285 intel_pipe_update_end(intel_crtc, start_vbl_count); 286 287 intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false); 288 } 289 290 static int 291 vlv_update_colorkey(struct drm_plane *dplane, 292 struct drm_intel_sprite_colorkey *key) 293 { 294 struct drm_device *dev = dplane->dev; 295 struct drm_i915_private *dev_priv = dev->dev_private; 296 struct intel_plane *intel_plane = to_intel_plane(dplane); 297 int pipe = intel_plane->pipe; 298 int plane = intel_plane->plane; 299 u32 sprctl; 300 301 if (key->flags & I915_SET_COLORKEY_DESTINATION) 302 return -EINVAL; 303 304 I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value); 305 I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value); 306 I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask); 307 308 sprctl = I915_READ(SPCNTR(pipe, plane)); 309 sprctl &= ~SP_SOURCE_KEY; 310 if (key->flags & I915_SET_COLORKEY_SOURCE) 311 sprctl |= SP_SOURCE_KEY; 312 I915_WRITE(SPCNTR(pipe, plane), sprctl); 313 314 POSTING_READ(SPKEYMSK(pipe, plane)); 315 316 return 0; 317 } 318 319 static void 320 vlv_get_colorkey(struct drm_plane *dplane, 321 struct drm_intel_sprite_colorkey *key) 322 { 323 struct drm_device *dev = dplane->dev; 324 struct drm_i915_private *dev_priv = dev->dev_private; 325 struct intel_plane *intel_plane = to_intel_plane(dplane); 326 int pipe = intel_plane->pipe; 327 int plane = intel_plane->plane; 328 u32 sprctl; 329 330 key->min_value = I915_READ(SPKEYMINVAL(pipe, plane)); 331 key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane)); 332 key->channel_mask = I915_READ(SPKEYMSK(pipe, plane)); 333 334 sprctl = I915_READ(SPCNTR(pipe, plane)); 335 if (sprctl & SP_SOURCE_KEY) 336 key->flags = I915_SET_COLORKEY_SOURCE; 337 else 338 key->flags = I915_SET_COLORKEY_NONE; 339 } 340 341 static void 342 ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 343 struct drm_framebuffer *fb, 344 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, 345 unsigned int crtc_w, unsigned int crtc_h, 346 uint32_t x, uint32_t y, 347 uint32_t src_w, uint32_t src_h) 348 { 349 struct drm_device *dev = plane->dev; 350 struct drm_i915_private *dev_priv = dev->dev_private; 351 struct intel_plane *intel_plane = to_intel_plane(plane); 352 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 353 int pipe = intel_plane->pipe; 354 u32 sprctl, sprscale = 0; 355 unsigned long sprsurf_offset, linear_offset; 356 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 357 u32 start_vbl_count; 358 bool atomic_update; 359 360 sprctl = I915_READ(SPRCTL(pipe)); 361 362 /* Mask out pixel format bits in case we change it */ 363 sprctl &= ~SPRITE_PIXFORMAT_MASK; 364 sprctl &= ~SPRITE_RGB_ORDER_RGBX; 365 sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; 366 sprctl &= ~SPRITE_TILED; 367 368 switch (fb->pixel_format) { 369 case DRM_FORMAT_XBGR8888: 370 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 371 break; 372 case DRM_FORMAT_XRGB8888: 373 sprctl |= SPRITE_FORMAT_RGBX888; 374 break; 375 case DRM_FORMAT_YUYV: 376 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 377 break; 378 case DRM_FORMAT_YVYU: 379 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 380 break; 381 case DRM_FORMAT_UYVY: 382 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 383 break; 384 case DRM_FORMAT_VYUY: 385 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 386 break; 387 default: 388 BUG(); 389 } 390 391 /* 392 * Enable gamma to match primary/cursor plane behaviour. 393 * FIXME should be user controllable via propertiesa. 394 */ 395 sprctl |= SPRITE_GAMMA_ENABLE; 396 397 if (obj->tiling_mode != I915_TILING_NONE) 398 sprctl |= SPRITE_TILED; 399 400 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 401 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; 402 else 403 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 404 405 sprctl |= SPRITE_ENABLE; 406 407 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 408 sprctl |= SPRITE_PIPE_CSC_ENABLE; 409 410 intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size, 411 true, 412 src_w != crtc_w || src_h != crtc_h); 413 414 /* Sizes are 0 based */ 415 src_w--; 416 src_h--; 417 crtc_w--; 418 crtc_h--; 419 420 if (crtc_w != src_w || crtc_h != src_h) 421 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 422 423 linear_offset = y * fb->pitches[0] + x * pixel_size; 424 sprsurf_offset = 425 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, 426 pixel_size, fb->pitches[0]); 427 linear_offset -= sprsurf_offset; 428 429 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 430 431 intel_update_primary_plane(intel_crtc); 432 433 I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); 434 I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 435 436 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 437 * register */ 438 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 439 I915_WRITE(SPROFFSET(pipe), (y << 16) | x); 440 else if (obj->tiling_mode != I915_TILING_NONE) 441 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); 442 else 443 I915_WRITE(SPRLINOFF(pipe), linear_offset); 444 445 I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 446 if (intel_plane->can_scale) 447 I915_WRITE(SPRSCALE(pipe), sprscale); 448 I915_WRITE(SPRCTL(pipe), sprctl); 449 I915_WRITE(SPRSURF(pipe), 450 i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); 451 452 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 453 454 if (atomic_update) 455 intel_pipe_update_end(intel_crtc, start_vbl_count); 456 } 457 458 static void 459 ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) 460 { 461 struct drm_device *dev = plane->dev; 462 struct drm_i915_private *dev_priv = dev->dev_private; 463 struct intel_plane *intel_plane = to_intel_plane(plane); 464 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 465 int pipe = intel_plane->pipe; 466 u32 start_vbl_count; 467 bool atomic_update; 468 469 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 470 471 intel_update_primary_plane(intel_crtc); 472 473 I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); 474 /* Can't leave the scaler enabled... */ 475 if (intel_plane->can_scale) 476 I915_WRITE(SPRSCALE(pipe), 0); 477 /* Activate double buffered register update */ 478 I915_WRITE(SPRSURF(pipe), 0); 479 480 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 481 482 if (atomic_update) 483 intel_pipe_update_end(intel_crtc, start_vbl_count); 484 485 /* 486 * Avoid underruns when disabling the sprite. 487 * FIXME remove once watermark updates are done properly. 488 */ 489 intel_wait_for_vblank(dev, pipe); 490 491 intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false); 492 } 493 494 static int 495 ivb_update_colorkey(struct drm_plane *plane, 496 struct drm_intel_sprite_colorkey *key) 497 { 498 struct drm_device *dev = plane->dev; 499 struct drm_i915_private *dev_priv = dev->dev_private; 500 struct intel_plane *intel_plane; 501 u32 sprctl; 502 int ret = 0; 503 504 intel_plane = to_intel_plane(plane); 505 506 I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value); 507 I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value); 508 I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask); 509 510 sprctl = I915_READ(SPRCTL(intel_plane->pipe)); 511 sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY); 512 if (key->flags & I915_SET_COLORKEY_DESTINATION) 513 sprctl |= SPRITE_DEST_KEY; 514 else if (key->flags & I915_SET_COLORKEY_SOURCE) 515 sprctl |= SPRITE_SOURCE_KEY; 516 I915_WRITE(SPRCTL(intel_plane->pipe), sprctl); 517 518 POSTING_READ(SPRKEYMSK(intel_plane->pipe)); 519 520 return ret; 521 } 522 523 static void 524 ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) 525 { 526 struct drm_device *dev = plane->dev; 527 struct drm_i915_private *dev_priv = dev->dev_private; 528 struct intel_plane *intel_plane; 529 u32 sprctl; 530 531 intel_plane = to_intel_plane(plane); 532 533 key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe)); 534 key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe)); 535 key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe)); 536 key->flags = 0; 537 538 sprctl = I915_READ(SPRCTL(intel_plane->pipe)); 539 540 if (sprctl & SPRITE_DEST_KEY) 541 key->flags = I915_SET_COLORKEY_DESTINATION; 542 else if (sprctl & SPRITE_SOURCE_KEY) 543 key->flags = I915_SET_COLORKEY_SOURCE; 544 else 545 key->flags = I915_SET_COLORKEY_NONE; 546 } 547 548 static void 549 ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 550 struct drm_framebuffer *fb, 551 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, 552 unsigned int crtc_w, unsigned int crtc_h, 553 uint32_t x, uint32_t y, 554 uint32_t src_w, uint32_t src_h) 555 { 556 struct drm_device *dev = plane->dev; 557 struct drm_i915_private *dev_priv = dev->dev_private; 558 struct intel_plane *intel_plane = to_intel_plane(plane); 559 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 560 int pipe = intel_plane->pipe; 561 unsigned long dvssurf_offset, linear_offset; 562 u32 dvscntr, dvsscale; 563 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 564 u32 start_vbl_count; 565 bool atomic_update; 566 567 dvscntr = I915_READ(DVSCNTR(pipe)); 568 569 /* Mask out pixel format bits in case we change it */ 570 dvscntr &= ~DVS_PIXFORMAT_MASK; 571 dvscntr &= ~DVS_RGB_ORDER_XBGR; 572 dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; 573 dvscntr &= ~DVS_TILED; 574 575 switch (fb->pixel_format) { 576 case DRM_FORMAT_XBGR8888: 577 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; 578 break; 579 case DRM_FORMAT_XRGB8888: 580 dvscntr |= DVS_FORMAT_RGBX888; 581 break; 582 case DRM_FORMAT_YUYV: 583 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; 584 break; 585 case DRM_FORMAT_YVYU: 586 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; 587 break; 588 case DRM_FORMAT_UYVY: 589 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; 590 break; 591 case DRM_FORMAT_VYUY: 592 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; 593 break; 594 default: 595 BUG(); 596 } 597 598 /* 599 * Enable gamma to match primary/cursor plane behaviour. 600 * FIXME should be user controllable via propertiesa. 601 */ 602 dvscntr |= DVS_GAMMA_ENABLE; 603 604 if (obj->tiling_mode != I915_TILING_NONE) 605 dvscntr |= DVS_TILED; 606 607 if (IS_GEN6(dev)) 608 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ 609 dvscntr |= DVS_ENABLE; 610 611 intel_update_sprite_watermarks(plane, crtc, src_w, src_h, 612 pixel_size, true, 613 src_w != crtc_w || src_h != crtc_h); 614 615 /* Sizes are 0 based */ 616 src_w--; 617 src_h--; 618 crtc_w--; 619 crtc_h--; 620 621 dvsscale = 0; 622 if (crtc_w != src_w || crtc_h != src_h) 623 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; 624 625 linear_offset = y * fb->pitches[0] + x * pixel_size; 626 dvssurf_offset = 627 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, 628 pixel_size, fb->pitches[0]); 629 linear_offset -= dvssurf_offset; 630 631 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 632 633 intel_update_primary_plane(intel_crtc); 634 635 I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); 636 I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 637 638 if (obj->tiling_mode != I915_TILING_NONE) 639 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); 640 else 641 I915_WRITE(DVSLINOFF(pipe), linear_offset); 642 643 I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 644 I915_WRITE(DVSSCALE(pipe), dvsscale); 645 I915_WRITE(DVSCNTR(pipe), dvscntr); 646 I915_WRITE(DVSSURF(pipe), 647 i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); 648 649 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 650 651 if (atomic_update) 652 intel_pipe_update_end(intel_crtc, start_vbl_count); 653 } 654 655 static void 656 ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) 657 { 658 struct drm_device *dev = plane->dev; 659 struct drm_i915_private *dev_priv = dev->dev_private; 660 struct intel_plane *intel_plane = to_intel_plane(plane); 661 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 662 int pipe = intel_plane->pipe; 663 u32 start_vbl_count; 664 bool atomic_update; 665 666 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 667 668 intel_update_primary_plane(intel_crtc); 669 670 I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); 671 /* Disable the scaler */ 672 I915_WRITE(DVSSCALE(pipe), 0); 673 /* Flush double buffered register updates */ 674 I915_WRITE(DVSSURF(pipe), 0); 675 676 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 677 678 if (atomic_update) 679 intel_pipe_update_end(intel_crtc, start_vbl_count); 680 681 /* 682 * Avoid underruns when disabling the sprite. 683 * FIXME remove once watermark updates are done properly. 684 */ 685 intel_wait_for_vblank(dev, pipe); 686 687 intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false); 688 } 689 690 static void 691 intel_post_enable_primary(struct drm_crtc *crtc) 692 { 693 struct drm_device *dev = crtc->dev; 694 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 695 696 /* 697 * BDW signals flip done immediately if the plane 698 * is disabled, even if the plane enable is already 699 * armed to occur at the next vblank :( 700 */ 701 if (IS_BROADWELL(dev)) 702 intel_wait_for_vblank(dev, intel_crtc->pipe); 703 704 /* 705 * FIXME IPS should be fine as long as one plane is 706 * enabled, but in practice it seems to have problems 707 * when going from primary only to sprite only and vice 708 * versa. 709 */ 710 hsw_enable_ips(intel_crtc); 711 712 mutex_lock(&dev->struct_mutex); 713 intel_update_fbc(dev); 714 mutex_unlock(&dev->struct_mutex); 715 } 716 717 static void 718 intel_pre_disable_primary(struct drm_crtc *crtc) 719 { 720 struct drm_device *dev = crtc->dev; 721 struct drm_i915_private *dev_priv = dev->dev_private; 722 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 723 724 mutex_lock(&dev->struct_mutex); 725 if (dev_priv->fbc.plane == intel_crtc->plane) 726 intel_disable_fbc(dev); 727 mutex_unlock(&dev->struct_mutex); 728 729 /* 730 * FIXME IPS should be fine as long as one plane is 731 * enabled, but in practice it seems to have problems 732 * when going from primary only to sprite only and vice 733 * versa. 734 */ 735 hsw_disable_ips(intel_crtc); 736 } 737 738 static int 739 ilk_update_colorkey(struct drm_plane *plane, 740 struct drm_intel_sprite_colorkey *key) 741 { 742 struct drm_device *dev = plane->dev; 743 struct drm_i915_private *dev_priv = dev->dev_private; 744 struct intel_plane *intel_plane; 745 u32 dvscntr; 746 int ret = 0; 747 748 intel_plane = to_intel_plane(plane); 749 750 I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value); 751 I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value); 752 I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask); 753 754 dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); 755 dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY); 756 if (key->flags & I915_SET_COLORKEY_DESTINATION) 757 dvscntr |= DVS_DEST_KEY; 758 else if (key->flags & I915_SET_COLORKEY_SOURCE) 759 dvscntr |= DVS_SOURCE_KEY; 760 I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr); 761 762 POSTING_READ(DVSKEYMSK(intel_plane->pipe)); 763 764 return ret; 765 } 766 767 static void 768 ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) 769 { 770 struct drm_device *dev = plane->dev; 771 struct drm_i915_private *dev_priv = dev->dev_private; 772 struct intel_plane *intel_plane; 773 u32 dvscntr; 774 775 intel_plane = to_intel_plane(plane); 776 777 key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe)); 778 key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe)); 779 key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe)); 780 key->flags = 0; 781 782 dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); 783 784 if (dvscntr & DVS_DEST_KEY) 785 key->flags = I915_SET_COLORKEY_DESTINATION; 786 else if (dvscntr & DVS_SOURCE_KEY) 787 key->flags = I915_SET_COLORKEY_SOURCE; 788 else 789 key->flags = I915_SET_COLORKEY_NONE; 790 } 791 792 static bool 793 format_is_yuv(uint32_t format) 794 { 795 switch (format) { 796 case DRM_FORMAT_YUYV: 797 case DRM_FORMAT_UYVY: 798 case DRM_FORMAT_VYUY: 799 case DRM_FORMAT_YVYU: 800 return true; 801 default: 802 return false; 803 } 804 } 805 806 static bool colorkey_enabled(struct intel_plane *intel_plane) 807 { 808 struct drm_intel_sprite_colorkey key; 809 810 intel_plane->get_colorkey(&intel_plane->base, &key); 811 812 return key.flags != I915_SET_COLORKEY_NONE; 813 } 814 815 static int 816 intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 817 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 818 unsigned int crtc_w, unsigned int crtc_h, 819 uint32_t src_x, uint32_t src_y, 820 uint32_t src_w, uint32_t src_h) 821 { 822 struct drm_device *dev = plane->dev; 823 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 824 struct intel_plane *intel_plane = to_intel_plane(plane); 825 enum i915_pipe pipe = intel_crtc->pipe; 826 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); 827 struct drm_i915_gem_object *obj = intel_fb->obj; 828 struct drm_i915_gem_object *old_obj = intel_plane->obj; 829 int ret; 830 bool primary_enabled; 831 bool visible; 832 int hscale, vscale; 833 int max_scale, min_scale; 834 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 835 struct drm_rect src = { 836 /* sample coordinates in 16.16 fixed point */ 837 .x1 = src_x, 838 .x2 = src_x + src_w, 839 .y1 = src_y, 840 .y2 = src_y + src_h, 841 }; 842 struct drm_rect dst = { 843 /* integer pixels */ 844 .x1 = crtc_x, 845 .x2 = crtc_x + crtc_w, 846 .y1 = crtc_y, 847 .y2 = crtc_y + crtc_h, 848 }; 849 const struct drm_rect clip = { 850 .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0, 851 .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0, 852 }; 853 const struct { 854 int crtc_x, crtc_y; 855 unsigned int crtc_w, crtc_h; 856 uint32_t src_x, src_y, src_w, src_h; 857 } orig = { 858 .crtc_x = crtc_x, 859 .crtc_y = crtc_y, 860 .crtc_w = crtc_w, 861 .crtc_h = crtc_h, 862 .src_x = src_x, 863 .src_y = src_y, 864 .src_w = src_w, 865 .src_h = src_h, 866 }; 867 868 /* Don't modify another pipe's plane */ 869 if (intel_plane->pipe != intel_crtc->pipe) { 870 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n"); 871 return -EINVAL; 872 } 873 874 /* FIXME check all gen limits */ 875 if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) { 876 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n"); 877 return -EINVAL; 878 } 879 880 /* Sprite planes can be linear or x-tiled surfaces */ 881 switch (obj->tiling_mode) { 882 case I915_TILING_NONE: 883 case I915_TILING_X: 884 break; 885 default: 886 DRM_DEBUG_KMS("Unsupported tiling mode\n"); 887 return -EINVAL; 888 } 889 890 /* 891 * FIXME the following code does a bunch of fuzzy adjustments to the 892 * coordinates and sizes. We probably need some way to decide whether 893 * more strict checking should be done instead. 894 */ 895 max_scale = intel_plane->max_downscale << 16; 896 min_scale = intel_plane->can_scale ? 1 : (1 << 16); 897 898 hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale); 899 BUG_ON(hscale < 0); 900 901 vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale); 902 BUG_ON(vscale < 0); 903 904 visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale); 905 906 crtc_x = dst.x1; 907 crtc_y = dst.y1; 908 crtc_w = drm_rect_width(&dst); 909 crtc_h = drm_rect_height(&dst); 910 911 if (visible) { 912 /* check again in case clipping clamped the results */ 913 hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); 914 if (hscale < 0) { 915 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); 916 drm_rect_debug_print(&src, true); 917 drm_rect_debug_print(&dst, false); 918 919 return hscale; 920 } 921 922 vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); 923 if (vscale < 0) { 924 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); 925 drm_rect_debug_print(&src, true); 926 drm_rect_debug_print(&dst, false); 927 928 return vscale; 929 } 930 931 /* Make the source viewport size an exact multiple of the scaling factors. */ 932 drm_rect_adjust_size(&src, 933 drm_rect_width(&dst) * hscale - drm_rect_width(&src), 934 drm_rect_height(&dst) * vscale - drm_rect_height(&src)); 935 936 /* sanity check to make sure the src viewport wasn't enlarged */ 937 WARN_ON(src.x1 < (int) src_x || 938 src.y1 < (int) src_y || 939 src.x2 > (int) (src_x + src_w) || 940 src.y2 > (int) (src_y + src_h)); 941 942 /* 943 * Hardware doesn't handle subpixel coordinates. 944 * Adjust to (macro)pixel boundary, but be careful not to 945 * increase the source viewport size, because that could 946 * push the downscaling factor out of bounds. 947 */ 948 src_x = src.x1 >> 16; 949 src_w = drm_rect_width(&src) >> 16; 950 src_y = src.y1 >> 16; 951 src_h = drm_rect_height(&src) >> 16; 952 953 if (format_is_yuv(fb->pixel_format)) { 954 src_x &= ~1; 955 src_w &= ~1; 956 957 /* 958 * Must keep src and dst the 959 * same if we can't scale. 960 */ 961 if (!intel_plane->can_scale) 962 crtc_w &= ~1; 963 964 if (crtc_w == 0) 965 visible = false; 966 } 967 } 968 969 /* Check size restrictions when scaling */ 970 if (visible && (src_w != crtc_w || src_h != crtc_h)) { 971 unsigned int width_bytes; 972 973 WARN_ON(!intel_plane->can_scale); 974 975 /* FIXME interlacing min height is 6 */ 976 977 if (crtc_w < 3 || crtc_h < 3) 978 visible = false; 979 980 if (src_w < 3 || src_h < 3) 981 visible = false; 982 983 width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size; 984 985 if (src_w > 2048 || src_h > 2048 || 986 width_bytes > 4096 || fb->pitches[0] > 4096) { 987 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); 988 return -EINVAL; 989 } 990 } 991 992 dst.x1 = crtc_x; 993 dst.x2 = crtc_x + crtc_w; 994 dst.y1 = crtc_y; 995 dst.y2 = crtc_y + crtc_h; 996 997 /* 998 * If the sprite is completely covering the primary plane, 999 * we can disable the primary and save power. 1000 */ 1001 primary_enabled = !drm_rect_equals(&dst, &clip) || colorkey_enabled(intel_plane); 1002 WARN_ON(!primary_enabled && !visible && intel_crtc->active); 1003 1004 mutex_lock(&dev->struct_mutex); 1005 1006 /* Note that this will apply the VT-d workaround for scanouts, 1007 * which is more restrictive than required for sprites. (The 1008 * primary plane requires 256KiB alignment with 64 PTE padding, 1009 * the sprite planes only require 128KiB alignment and 32 PTE padding. 1010 */ 1011 ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); 1012 1013 i915_gem_track_fb(old_obj, obj, 1014 INTEL_FRONTBUFFER_SPRITE(pipe)); 1015 mutex_unlock(&dev->struct_mutex); 1016 1017 if (ret) 1018 return ret; 1019 1020 intel_plane->crtc_x = orig.crtc_x; 1021 intel_plane->crtc_y = orig.crtc_y; 1022 intel_plane->crtc_w = orig.crtc_w; 1023 intel_plane->crtc_h = orig.crtc_h; 1024 intel_plane->src_x = orig.src_x; 1025 intel_plane->src_y = orig.src_y; 1026 intel_plane->src_w = orig.src_w; 1027 intel_plane->src_h = orig.src_h; 1028 intel_plane->obj = obj; 1029 1030 if (intel_crtc->active) { 1031 bool primary_was_enabled = intel_crtc->primary_enabled; 1032 1033 intel_crtc->primary_enabled = primary_enabled; 1034 1035 if (primary_was_enabled != primary_enabled) 1036 intel_crtc_wait_for_pending_flips(crtc); 1037 1038 if (primary_was_enabled && !primary_enabled) 1039 intel_pre_disable_primary(crtc); 1040 1041 if (visible) 1042 intel_plane->update_plane(plane, crtc, fb, obj, 1043 crtc_x, crtc_y, crtc_w, crtc_h, 1044 src_x, src_y, src_w, src_h); 1045 else 1046 intel_plane->disable_plane(plane, crtc); 1047 1048 intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe)); 1049 1050 if (!primary_was_enabled && primary_enabled) 1051 intel_post_enable_primary(crtc); 1052 } 1053 1054 /* Unpin old obj after new one is active to avoid ugliness */ 1055 if (old_obj) { 1056 /* 1057 * It's fairly common to simply update the position of 1058 * an existing object. In that case, we don't need to 1059 * wait for vblank to avoid ugliness, we only need to 1060 * do the pin & ref bookkeeping. 1061 */ 1062 if (old_obj != obj && intel_crtc->active) 1063 intel_wait_for_vblank(dev, intel_crtc->pipe); 1064 1065 mutex_lock(&dev->struct_mutex); 1066 intel_unpin_fb_obj(old_obj); 1067 mutex_unlock(&dev->struct_mutex); 1068 } 1069 1070 return 0; 1071 } 1072 1073 static int 1074 intel_disable_plane(struct drm_plane *plane) 1075 { 1076 struct drm_device *dev = plane->dev; 1077 struct intel_plane *intel_plane = to_intel_plane(plane); 1078 struct intel_crtc *intel_crtc; 1079 enum i915_pipe pipe; 1080 1081 if (!plane->fb) 1082 return 0; 1083 1084 if (WARN_ON(!plane->crtc)) 1085 return -EINVAL; 1086 1087 intel_crtc = to_intel_crtc(plane->crtc); 1088 pipe = intel_crtc->pipe; 1089 1090 if (intel_crtc->active) { 1091 bool primary_was_enabled = intel_crtc->primary_enabled; 1092 1093 intel_crtc->primary_enabled = true; 1094 1095 intel_plane->disable_plane(plane, plane->crtc); 1096 1097 if (!primary_was_enabled && intel_crtc->primary_enabled) 1098 intel_post_enable_primary(plane->crtc); 1099 } 1100 1101 if (intel_plane->obj) { 1102 if (intel_crtc->active) 1103 intel_wait_for_vblank(dev, intel_plane->pipe); 1104 1105 mutex_lock(&dev->struct_mutex); 1106 intel_unpin_fb_obj(intel_plane->obj); 1107 i915_gem_track_fb(intel_plane->obj, NULL, 1108 INTEL_FRONTBUFFER_SPRITE(pipe)); 1109 mutex_unlock(&dev->struct_mutex); 1110 1111 intel_plane->obj = NULL; 1112 } 1113 1114 return 0; 1115 } 1116 1117 static void intel_destroy_plane(struct drm_plane *plane) 1118 { 1119 struct intel_plane *intel_plane = to_intel_plane(plane); 1120 intel_disable_plane(plane); 1121 drm_plane_cleanup(plane); 1122 kfree(intel_plane); 1123 } 1124 1125 int intel_sprite_set_colorkey(struct drm_device *dev, void *data, 1126 struct drm_file *file_priv) 1127 { 1128 struct drm_intel_sprite_colorkey *set = data; 1129 struct drm_plane *plane; 1130 struct intel_plane *intel_plane; 1131 int ret = 0; 1132 1133 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1134 return -ENODEV; 1135 1136 /* Make sure we don't try to enable both src & dest simultaneously */ 1137 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1138 return -EINVAL; 1139 1140 drm_modeset_lock_all(dev); 1141 1142 plane = drm_plane_find(dev, set->plane_id); 1143 if (!plane) { 1144 ret = -ENOENT; 1145 goto out_unlock; 1146 } 1147 1148 intel_plane = to_intel_plane(plane); 1149 ret = intel_plane->update_colorkey(plane, set); 1150 1151 out_unlock: 1152 drm_modeset_unlock_all(dev); 1153 return ret; 1154 } 1155 1156 int intel_sprite_get_colorkey(struct drm_device *dev, void *data, 1157 struct drm_file *file_priv) 1158 { 1159 struct drm_intel_sprite_colorkey *get = data; 1160 struct drm_plane *plane; 1161 struct intel_plane *intel_plane; 1162 int ret = 0; 1163 1164 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1165 return -ENODEV; 1166 1167 drm_modeset_lock_all(dev); 1168 1169 plane = drm_plane_find(dev, get->plane_id); 1170 if (!plane) { 1171 ret = -ENOENT; 1172 goto out_unlock; 1173 } 1174 1175 intel_plane = to_intel_plane(plane); 1176 intel_plane->get_colorkey(plane, get); 1177 1178 out_unlock: 1179 drm_modeset_unlock_all(dev); 1180 return ret; 1181 } 1182 1183 void intel_plane_restore(struct drm_plane *plane) 1184 { 1185 struct intel_plane *intel_plane = to_intel_plane(plane); 1186 1187 if (!plane->crtc || !plane->fb) 1188 return; 1189 1190 intel_update_plane(plane, plane->crtc, plane->fb, 1191 intel_plane->crtc_x, intel_plane->crtc_y, 1192 intel_plane->crtc_w, intel_plane->crtc_h, 1193 intel_plane->src_x, intel_plane->src_y, 1194 intel_plane->src_w, intel_plane->src_h); 1195 } 1196 1197 void intel_plane_disable(struct drm_plane *plane) 1198 { 1199 if (!plane->crtc || !plane->fb) 1200 return; 1201 1202 intel_disable_plane(plane); 1203 } 1204 1205 static const struct drm_plane_funcs intel_plane_funcs = { 1206 .update_plane = intel_update_plane, 1207 .disable_plane = intel_disable_plane, 1208 .destroy = intel_destroy_plane, 1209 }; 1210 1211 static uint32_t ilk_plane_formats[] = { 1212 DRM_FORMAT_XRGB8888, 1213 DRM_FORMAT_YUYV, 1214 DRM_FORMAT_YVYU, 1215 DRM_FORMAT_UYVY, 1216 DRM_FORMAT_VYUY, 1217 }; 1218 1219 static uint32_t snb_plane_formats[] = { 1220 DRM_FORMAT_XBGR8888, 1221 DRM_FORMAT_XRGB8888, 1222 DRM_FORMAT_YUYV, 1223 DRM_FORMAT_YVYU, 1224 DRM_FORMAT_UYVY, 1225 DRM_FORMAT_VYUY, 1226 }; 1227 1228 static uint32_t vlv_plane_formats[] = { 1229 DRM_FORMAT_RGB565, 1230 DRM_FORMAT_ABGR8888, 1231 DRM_FORMAT_ARGB8888, 1232 DRM_FORMAT_XBGR8888, 1233 DRM_FORMAT_XRGB8888, 1234 DRM_FORMAT_XBGR2101010, 1235 DRM_FORMAT_ABGR2101010, 1236 DRM_FORMAT_YUYV, 1237 DRM_FORMAT_YVYU, 1238 DRM_FORMAT_UYVY, 1239 DRM_FORMAT_VYUY, 1240 }; 1241 1242 int 1243 intel_plane_init(struct drm_device *dev, enum i915_pipe pipe, int plane) 1244 { 1245 struct intel_plane *intel_plane; 1246 unsigned long possible_crtcs; 1247 const uint32_t *plane_formats; 1248 int num_plane_formats; 1249 int ret; 1250 1251 if (INTEL_INFO(dev)->gen < 5) 1252 return -ENODEV; 1253 1254 intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); 1255 if (!intel_plane) 1256 return -ENOMEM; 1257 1258 switch (INTEL_INFO(dev)->gen) { 1259 case 5: 1260 case 6: 1261 intel_plane->can_scale = true; 1262 intel_plane->max_downscale = 16; 1263 intel_plane->update_plane = ilk_update_plane; 1264 intel_plane->disable_plane = ilk_disable_plane; 1265 intel_plane->update_colorkey = ilk_update_colorkey; 1266 intel_plane->get_colorkey = ilk_get_colorkey; 1267 1268 if (IS_GEN6(dev)) { 1269 plane_formats = snb_plane_formats; 1270 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 1271 } else { 1272 plane_formats = ilk_plane_formats; 1273 num_plane_formats = ARRAY_SIZE(ilk_plane_formats); 1274 } 1275 break; 1276 1277 case 7: 1278 case 8: 1279 if (IS_IVYBRIDGE(dev)) { 1280 intel_plane->can_scale = true; 1281 intel_plane->max_downscale = 2; 1282 } else { 1283 intel_plane->can_scale = false; 1284 intel_plane->max_downscale = 1; 1285 } 1286 1287 if (IS_VALLEYVIEW(dev)) { 1288 intel_plane->update_plane = vlv_update_plane; 1289 intel_plane->disable_plane = vlv_disable_plane; 1290 intel_plane->update_colorkey = vlv_update_colorkey; 1291 intel_plane->get_colorkey = vlv_get_colorkey; 1292 1293 plane_formats = vlv_plane_formats; 1294 num_plane_formats = ARRAY_SIZE(vlv_plane_formats); 1295 } else { 1296 intel_plane->update_plane = ivb_update_plane; 1297 intel_plane->disable_plane = ivb_disable_plane; 1298 intel_plane->update_colorkey = ivb_update_colorkey; 1299 intel_plane->get_colorkey = ivb_get_colorkey; 1300 1301 plane_formats = snb_plane_formats; 1302 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 1303 } 1304 break; 1305 1306 default: 1307 kfree(intel_plane); 1308 return -ENODEV; 1309 } 1310 1311 intel_plane->pipe = pipe; 1312 intel_plane->plane = plane; 1313 possible_crtcs = (1 << pipe); 1314 ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, 1315 &intel_plane_funcs, 1316 plane_formats, num_plane_formats, 1317 false); 1318 if (ret) 1319 kfree(intel_plane); 1320 1321 return ret; 1322 } 1323