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 <drm/drm_plane_helper.h> 37 #include "intel_drv.h" 38 #include <drm/i915_drm.h> 39 #include "i915_drv.h" 40 41 static bool 42 format_is_yuv(uint32_t format) 43 { 44 switch (format) { 45 case DRM_FORMAT_YUYV: 46 case DRM_FORMAT_UYVY: 47 case DRM_FORMAT_VYUY: 48 case DRM_FORMAT_YVYU: 49 return true; 50 default: 51 return false; 52 } 53 } 54 55 static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) 56 { 57 /* paranoia */ 58 if (!mode->crtc_htotal) 59 return 1; 60 61 return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal); 62 } 63 64 /** 65 * intel_pipe_update_start() - start update of a set of display registers 66 * @crtc: the crtc of which the registers are going to be updated 67 * @start_vbl_count: vblank counter return pointer used for error checking 68 * 69 * Mark the start of an update to pipe registers that should be updated 70 * atomically regarding vblank. If the next vblank will happens within 71 * the next 100 us, this function waits until the vblank passes. 72 * 73 * After a successful call to this function, interrupts will be disabled 74 * until a subsequent call to intel_pipe_update_end(). That is done to 75 * avoid random delays. The value written to @start_vbl_count should be 76 * supplied to intel_pipe_update_end() for error checking. 77 * 78 * Return: true if the call was successful 79 */ 80 bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count) 81 { 82 struct drm_device *dev = crtc->base.dev; 83 const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode; 84 enum i915_pipe pipe = crtc->pipe; 85 long timeout = msecs_to_jiffies_timeout(1); 86 int scanline, min, max, vblank_start; 87 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); 88 DEFINE_WAIT(wait); 89 90 vblank_start = mode->crtc_vblank_start; 91 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 92 vblank_start = DIV_ROUND_UP(vblank_start, 2); 93 94 /* FIXME needs to be calibrated sensibly */ 95 min = vblank_start - usecs_to_scanlines(mode, 100); 96 max = vblank_start - 1; 97 98 if (min <= 0 || max <= 0) 99 return false; 100 101 if (WARN_ON(drm_vblank_get(dev, pipe))) 102 return false; 103 104 local_irq_disable(); 105 106 trace_i915_pipe_update_start(crtc, min, max); 107 108 for (;;) { 109 /* 110 * prepare_to_wait() has a memory barrier, which guarantees 111 * other CPUs can see the task state update by the time we 112 * read the scanline. 113 */ 114 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); 115 116 scanline = intel_get_crtc_scanline(crtc); 117 if (scanline < min || scanline > max) 118 break; 119 120 if (timeout <= 0) { 121 DRM_ERROR("Potential atomic update failure on pipe %c\n", 122 pipe_name(crtc->pipe)); 123 break; 124 } 125 126 local_irq_enable(); 127 128 timeout = schedule_timeout(timeout); 129 130 local_irq_disable(); 131 } 132 133 finish_wait(wq, &wait); 134 135 drm_vblank_put(dev, pipe); 136 137 *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe); 138 139 trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count); 140 141 return true; 142 } 143 144 /** 145 * intel_pipe_update_end() - end update of a set of display registers 146 * @crtc: the crtc of which the registers were updated 147 * @start_vbl_count: start vblank counter (used for error checking) 148 * 149 * Mark the end of an update started with intel_pipe_update_start(). This 150 * re-enables interrupts and verifies the update was actually completed 151 * before a vblank using the value of @start_vbl_count. 152 */ 153 void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count) 154 { 155 struct drm_device *dev = crtc->base.dev; 156 enum i915_pipe pipe = crtc->pipe; 157 u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe); 158 159 trace_i915_pipe_update_end(crtc, end_vbl_count); 160 161 local_irq_enable(); 162 163 if (start_vbl_count != end_vbl_count) 164 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n", 165 pipe_name(pipe), start_vbl_count, end_vbl_count); 166 } 167 168 static void intel_update_primary_plane(struct intel_crtc *crtc) 169 { 170 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 171 int reg = DSPCNTR(crtc->plane); 172 173 if (crtc->primary_enabled) 174 I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); 175 else 176 I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); 177 } 178 179 static void 180 skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, 181 struct drm_framebuffer *fb, 182 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, 183 unsigned int crtc_w, unsigned int crtc_h, 184 uint32_t x, uint32_t y, 185 uint32_t src_w, uint32_t src_h) 186 { 187 struct drm_device *dev = drm_plane->dev; 188 struct drm_i915_private *dev_priv = dev->dev_private; 189 struct intel_plane *intel_plane = to_intel_plane(drm_plane); 190 const int pipe = intel_plane->pipe; 191 const int plane = intel_plane->plane + 1; 192 u32 plane_ctl, stride; 193 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 194 195 plane_ctl = I915_READ(PLANE_CTL(pipe, plane)); 196 197 /* Mask out pixel format bits in case we change it */ 198 plane_ctl &= ~PLANE_CTL_FORMAT_MASK; 199 plane_ctl &= ~PLANE_CTL_ORDER_RGBX; 200 plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK; 201 plane_ctl &= ~PLANE_CTL_TILED_MASK; 202 plane_ctl &= ~PLANE_CTL_ALPHA_MASK; 203 plane_ctl &= ~PLANE_CTL_ROTATE_MASK; 204 205 /* Trickle feed has to be enabled */ 206 plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE; 207 208 switch (fb->pixel_format) { 209 case DRM_FORMAT_RGB565: 210 plane_ctl |= PLANE_CTL_FORMAT_RGB_565; 211 break; 212 case DRM_FORMAT_XBGR8888: 213 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX; 214 break; 215 case DRM_FORMAT_XRGB8888: 216 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888; 217 break; 218 /* 219 * XXX: For ARBG/ABGR formats we default to expecting scanout buffers 220 * to be already pre-multiplied. We need to add a knob (or a different 221 * DRM_FORMAT) for user-space to configure that. 222 */ 223 case DRM_FORMAT_ABGR8888: 224 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | 225 PLANE_CTL_ORDER_RGBX | 226 PLANE_CTL_ALPHA_SW_PREMULTIPLY; 227 break; 228 case DRM_FORMAT_ARGB8888: 229 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | 230 PLANE_CTL_ALPHA_SW_PREMULTIPLY; 231 break; 232 case DRM_FORMAT_YUYV: 233 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV; 234 break; 235 case DRM_FORMAT_YVYU: 236 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU; 237 break; 238 case DRM_FORMAT_UYVY: 239 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY; 240 break; 241 case DRM_FORMAT_VYUY: 242 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY; 243 break; 244 default: 245 BUG(); 246 } 247 248 switch (obj->tiling_mode) { 249 case I915_TILING_NONE: 250 stride = fb->pitches[0] >> 6; 251 break; 252 case I915_TILING_X: 253 plane_ctl |= PLANE_CTL_TILED_X; 254 stride = fb->pitches[0] >> 9; 255 break; 256 default: 257 BUG(); 258 } 259 if (drm_plane->state->rotation == BIT(DRM_ROTATE_180)) 260 plane_ctl |= PLANE_CTL_ROTATE_180; 261 262 plane_ctl |= PLANE_CTL_ENABLE; 263 plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE; 264 265 intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h, 266 pixel_size, true, 267 src_w != crtc_w || src_h != crtc_h); 268 269 /* Sizes are 0 based */ 270 src_w--; 271 src_h--; 272 crtc_w--; 273 crtc_h--; 274 275 I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x); 276 I915_WRITE(PLANE_STRIDE(pipe, plane), stride); 277 I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x); 278 I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w); 279 I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl); 280 I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj)); 281 POSTING_READ(PLANE_SURF(pipe, plane)); 282 } 283 284 static void 285 skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc) 286 { 287 struct drm_device *dev = drm_plane->dev; 288 struct drm_i915_private *dev_priv = dev->dev_private; 289 struct intel_plane *intel_plane = to_intel_plane(drm_plane); 290 const int pipe = intel_plane->pipe; 291 const int plane = intel_plane->plane + 1; 292 293 I915_WRITE(PLANE_CTL(pipe, plane), 294 I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE); 295 296 /* Activate double buffered register update */ 297 I915_WRITE(PLANE_CTL(pipe, plane), 0); 298 POSTING_READ(PLANE_CTL(pipe, plane)); 299 300 intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false); 301 } 302 303 static int 304 skl_update_colorkey(struct drm_plane *drm_plane, 305 struct drm_intel_sprite_colorkey *key) 306 { 307 struct drm_device *dev = drm_plane->dev; 308 struct drm_i915_private *dev_priv = dev->dev_private; 309 struct intel_plane *intel_plane = to_intel_plane(drm_plane); 310 const int pipe = intel_plane->pipe; 311 const int plane = intel_plane->plane; 312 u32 plane_ctl; 313 314 I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); 315 I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); 316 I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask); 317 318 plane_ctl = I915_READ(PLANE_CTL(pipe, plane)); 319 plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK; 320 if (key->flags & I915_SET_COLORKEY_DESTINATION) 321 plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION; 322 else if (key->flags & I915_SET_COLORKEY_SOURCE) 323 plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE; 324 I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl); 325 326 POSTING_READ(PLANE_CTL(pipe, plane)); 327 328 return 0; 329 } 330 331 static void 332 skl_get_colorkey(struct drm_plane *drm_plane, 333 struct drm_intel_sprite_colorkey *key) 334 { 335 struct drm_device *dev = drm_plane->dev; 336 struct drm_i915_private *dev_priv = dev->dev_private; 337 struct intel_plane *intel_plane = to_intel_plane(drm_plane); 338 const int pipe = intel_plane->pipe; 339 const int plane = intel_plane->plane; 340 u32 plane_ctl; 341 342 key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane)); 343 key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane)); 344 key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane)); 345 346 plane_ctl = I915_READ(PLANE_CTL(pipe, plane)); 347 348 switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) { 349 case PLANE_CTL_KEY_ENABLE_DESTINATION: 350 key->flags = I915_SET_COLORKEY_DESTINATION; 351 break; 352 case PLANE_CTL_KEY_ENABLE_SOURCE: 353 key->flags = I915_SET_COLORKEY_SOURCE; 354 break; 355 default: 356 key->flags = I915_SET_COLORKEY_NONE; 357 } 358 } 359 360 static void 361 chv_update_csc(struct intel_plane *intel_plane, uint32_t format) 362 { 363 struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private; 364 int plane = intel_plane->plane; 365 366 /* Seems RGB data bypasses the CSC always */ 367 if (!format_is_yuv(format)) 368 return; 369 370 /* 371 * BT.601 limited range YCbCr -> full range RGB 372 * 373 * |r| | 6537 4769 0| |cr | 374 * |g| = |-3330 4769 -1605| x |y-64| 375 * |b| | 0 4769 8263| |cb | 376 * 377 * Cb and Cr apparently come in as signed already, so no 378 * need for any offset. For Y we need to remove the offset. 379 */ 380 I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64)); 381 I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 382 I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 383 384 I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537)); 385 I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0)); 386 I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769)); 387 I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0)); 388 I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263)); 389 390 I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64)); 391 I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); 392 I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); 393 394 I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 395 I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 396 I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 397 } 398 399 static void 400 vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, 401 struct drm_framebuffer *fb, 402 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, 403 unsigned int crtc_w, unsigned int crtc_h, 404 uint32_t x, uint32_t y, 405 uint32_t src_w, uint32_t src_h) 406 { 407 struct drm_device *dev = dplane->dev; 408 struct drm_i915_private *dev_priv = dev->dev_private; 409 struct intel_plane *intel_plane = to_intel_plane(dplane); 410 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 411 int pipe = intel_plane->pipe; 412 int plane = intel_plane->plane; 413 u32 sprctl; 414 unsigned long sprsurf_offset, linear_offset; 415 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 416 417 sprctl = I915_READ(SPCNTR(pipe, plane)); 418 419 /* Mask out pixel format bits in case we change it */ 420 sprctl &= ~SP_PIXFORMAT_MASK; 421 sprctl &= ~SP_YUV_BYTE_ORDER_MASK; 422 sprctl &= ~SP_TILED; 423 sprctl &= ~SP_ROTATE_180; 424 425 switch (fb->pixel_format) { 426 case DRM_FORMAT_YUYV: 427 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 428 break; 429 case DRM_FORMAT_YVYU: 430 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 431 break; 432 case DRM_FORMAT_UYVY: 433 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 434 break; 435 case DRM_FORMAT_VYUY: 436 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 437 break; 438 case DRM_FORMAT_RGB565: 439 sprctl |= SP_FORMAT_BGR565; 440 break; 441 case DRM_FORMAT_XRGB8888: 442 sprctl |= SP_FORMAT_BGRX8888; 443 break; 444 case DRM_FORMAT_ARGB8888: 445 sprctl |= SP_FORMAT_BGRA8888; 446 break; 447 case DRM_FORMAT_XBGR2101010: 448 sprctl |= SP_FORMAT_RGBX1010102; 449 break; 450 case DRM_FORMAT_ABGR2101010: 451 sprctl |= SP_FORMAT_RGBA1010102; 452 break; 453 case DRM_FORMAT_XBGR8888: 454 sprctl |= SP_FORMAT_RGBX8888; 455 break; 456 case DRM_FORMAT_ABGR8888: 457 sprctl |= SP_FORMAT_RGBA8888; 458 break; 459 default: 460 /* 461 * If we get here one of the upper layers failed to filter 462 * out the unsupported plane formats 463 */ 464 BUG(); 465 break; 466 } 467 468 /* 469 * Enable gamma to match primary/cursor plane behaviour. 470 * FIXME should be user controllable via propertiesa. 471 */ 472 sprctl |= SP_GAMMA_ENABLE; 473 474 if (obj->tiling_mode != I915_TILING_NONE) 475 sprctl |= SP_TILED; 476 477 sprctl |= SP_ENABLE; 478 479 intel_update_sprite_watermarks(dplane, crtc, src_w, src_h, 480 pixel_size, true, 481 src_w != crtc_w || src_h != crtc_h); 482 483 /* Sizes are 0 based */ 484 src_w--; 485 src_h--; 486 crtc_w--; 487 crtc_h--; 488 489 linear_offset = y * fb->pitches[0] + x * pixel_size; 490 sprsurf_offset = intel_gen4_compute_page_offset(&x, &y, 491 obj->tiling_mode, 492 pixel_size, 493 fb->pitches[0]); 494 linear_offset -= sprsurf_offset; 495 496 if (dplane->state->rotation == BIT(DRM_ROTATE_180)) { 497 sprctl |= SP_ROTATE_180; 498 499 x += src_w; 500 y += src_h; 501 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; 502 } 503 504 intel_update_primary_plane(intel_crtc); 505 506 if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) 507 chv_update_csc(intel_plane, fb->pixel_format); 508 509 I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); 510 I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); 511 512 if (obj->tiling_mode != I915_TILING_NONE) 513 I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x); 514 else 515 I915_WRITE(SPLINOFF(pipe, plane), linear_offset); 516 517 I915_WRITE(SPCONSTALPHA(pipe, plane), 0); 518 519 I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); 520 I915_WRITE(SPCNTR(pipe, plane), sprctl); 521 I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + 522 sprsurf_offset); 523 524 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 525 } 526 527 static void 528 vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) 529 { 530 struct drm_device *dev = dplane->dev; 531 struct drm_i915_private *dev_priv = dev->dev_private; 532 struct intel_plane *intel_plane = to_intel_plane(dplane); 533 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 534 int pipe = intel_plane->pipe; 535 int plane = intel_plane->plane; 536 537 intel_update_primary_plane(intel_crtc); 538 539 I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & 540 ~SP_ENABLE); 541 /* Activate double buffered register update */ 542 I915_WRITE(SPSURF(pipe, plane), 0); 543 544 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 545 546 intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false); 547 } 548 549 static int 550 vlv_update_colorkey(struct drm_plane *dplane, 551 struct drm_intel_sprite_colorkey *key) 552 { 553 struct drm_device *dev = dplane->dev; 554 struct drm_i915_private *dev_priv = dev->dev_private; 555 struct intel_plane *intel_plane = to_intel_plane(dplane); 556 int pipe = intel_plane->pipe; 557 int plane = intel_plane->plane; 558 u32 sprctl; 559 560 if (key->flags & I915_SET_COLORKEY_DESTINATION) 561 return -EINVAL; 562 563 I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value); 564 I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value); 565 I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask); 566 567 sprctl = I915_READ(SPCNTR(pipe, plane)); 568 sprctl &= ~SP_SOURCE_KEY; 569 if (key->flags & I915_SET_COLORKEY_SOURCE) 570 sprctl |= SP_SOURCE_KEY; 571 I915_WRITE(SPCNTR(pipe, plane), sprctl); 572 573 POSTING_READ(SPKEYMSK(pipe, plane)); 574 575 return 0; 576 } 577 578 static void 579 vlv_get_colorkey(struct drm_plane *dplane, 580 struct drm_intel_sprite_colorkey *key) 581 { 582 struct drm_device *dev = dplane->dev; 583 struct drm_i915_private *dev_priv = dev->dev_private; 584 struct intel_plane *intel_plane = to_intel_plane(dplane); 585 int pipe = intel_plane->pipe; 586 int plane = intel_plane->plane; 587 u32 sprctl; 588 589 key->min_value = I915_READ(SPKEYMINVAL(pipe, plane)); 590 key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane)); 591 key->channel_mask = I915_READ(SPKEYMSK(pipe, plane)); 592 593 sprctl = I915_READ(SPCNTR(pipe, plane)); 594 if (sprctl & SP_SOURCE_KEY) 595 key->flags = I915_SET_COLORKEY_SOURCE; 596 else 597 key->flags = I915_SET_COLORKEY_NONE; 598 } 599 600 static void 601 ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 602 struct drm_framebuffer *fb, 603 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, 604 unsigned int crtc_w, unsigned int crtc_h, 605 uint32_t x, uint32_t y, 606 uint32_t src_w, uint32_t src_h) 607 { 608 struct drm_device *dev = plane->dev; 609 struct drm_i915_private *dev_priv = dev->dev_private; 610 struct intel_plane *intel_plane = to_intel_plane(plane); 611 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 612 int pipe = intel_plane->pipe; 613 u32 sprctl, sprscale = 0; 614 unsigned long sprsurf_offset, linear_offset; 615 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 616 617 sprctl = I915_READ(SPRCTL(pipe)); 618 619 /* Mask out pixel format bits in case we change it */ 620 sprctl &= ~SPRITE_PIXFORMAT_MASK; 621 sprctl &= ~SPRITE_RGB_ORDER_RGBX; 622 sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; 623 sprctl &= ~SPRITE_TILED; 624 sprctl &= ~SPRITE_ROTATE_180; 625 626 switch (fb->pixel_format) { 627 case DRM_FORMAT_XBGR8888: 628 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 629 break; 630 case DRM_FORMAT_XRGB8888: 631 sprctl |= SPRITE_FORMAT_RGBX888; 632 break; 633 case DRM_FORMAT_YUYV: 634 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 635 break; 636 case DRM_FORMAT_YVYU: 637 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 638 break; 639 case DRM_FORMAT_UYVY: 640 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 641 break; 642 case DRM_FORMAT_VYUY: 643 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 644 break; 645 default: 646 BUG(); 647 } 648 649 /* 650 * Enable gamma to match primary/cursor plane behaviour. 651 * FIXME should be user controllable via propertiesa. 652 */ 653 sprctl |= SPRITE_GAMMA_ENABLE; 654 655 if (obj->tiling_mode != I915_TILING_NONE) 656 sprctl |= SPRITE_TILED; 657 658 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 659 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; 660 else 661 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 662 663 sprctl |= SPRITE_ENABLE; 664 665 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 666 sprctl |= SPRITE_PIPE_CSC_ENABLE; 667 668 intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size, 669 true, 670 src_w != crtc_w || src_h != crtc_h); 671 672 /* Sizes are 0 based */ 673 src_w--; 674 src_h--; 675 crtc_w--; 676 crtc_h--; 677 678 if (crtc_w != src_w || crtc_h != src_h) 679 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 680 681 linear_offset = y * fb->pitches[0] + x * pixel_size; 682 sprsurf_offset = 683 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, 684 pixel_size, fb->pitches[0]); 685 linear_offset -= sprsurf_offset; 686 687 if (plane->state->rotation == BIT(DRM_ROTATE_180)) { 688 sprctl |= SPRITE_ROTATE_180; 689 690 /* HSW and BDW does this automagically in hardware */ 691 if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) { 692 x += src_w; 693 y += src_h; 694 linear_offset += src_h * fb->pitches[0] + 695 src_w * pixel_size; 696 } 697 } 698 699 intel_update_primary_plane(intel_crtc); 700 701 I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); 702 I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 703 704 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 705 * register */ 706 if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 707 I915_WRITE(SPROFFSET(pipe), (y << 16) | x); 708 else if (obj->tiling_mode != I915_TILING_NONE) 709 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); 710 else 711 I915_WRITE(SPRLINOFF(pipe), linear_offset); 712 713 I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 714 if (intel_plane->can_scale) 715 I915_WRITE(SPRSCALE(pipe), sprscale); 716 I915_WRITE(SPRCTL(pipe), sprctl); 717 I915_WRITE(SPRSURF(pipe), 718 i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); 719 720 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 721 } 722 723 static void 724 ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) 725 { 726 struct drm_device *dev = plane->dev; 727 struct drm_i915_private *dev_priv = dev->dev_private; 728 struct intel_plane *intel_plane = to_intel_plane(plane); 729 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 730 int pipe = intel_plane->pipe; 731 732 intel_update_primary_plane(intel_crtc); 733 734 I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); 735 /* Can't leave the scaler enabled... */ 736 if (intel_plane->can_scale) 737 I915_WRITE(SPRSCALE(pipe), 0); 738 /* Activate double buffered register update */ 739 I915_WRITE(SPRSURF(pipe), 0); 740 741 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 742 743 /* 744 * Avoid underruns when disabling the sprite. 745 * FIXME remove once watermark updates are done properly. 746 */ 747 intel_crtc->atomic.wait_vblank = true; 748 intel_crtc->atomic.update_sprite_watermarks |= (1 << drm_plane_index(plane)); 749 } 750 751 static int 752 ivb_update_colorkey(struct drm_plane *plane, 753 struct drm_intel_sprite_colorkey *key) 754 { 755 struct drm_device *dev = plane->dev; 756 struct drm_i915_private *dev_priv = dev->dev_private; 757 struct intel_plane *intel_plane; 758 u32 sprctl; 759 int ret = 0; 760 761 intel_plane = to_intel_plane(plane); 762 763 I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value); 764 I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value); 765 I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask); 766 767 sprctl = I915_READ(SPRCTL(intel_plane->pipe)); 768 sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY); 769 if (key->flags & I915_SET_COLORKEY_DESTINATION) 770 sprctl |= SPRITE_DEST_KEY; 771 else if (key->flags & I915_SET_COLORKEY_SOURCE) 772 sprctl |= SPRITE_SOURCE_KEY; 773 I915_WRITE(SPRCTL(intel_plane->pipe), sprctl); 774 775 POSTING_READ(SPRKEYMSK(intel_plane->pipe)); 776 777 return ret; 778 } 779 780 static void 781 ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) 782 { 783 struct drm_device *dev = plane->dev; 784 struct drm_i915_private *dev_priv = dev->dev_private; 785 struct intel_plane *intel_plane; 786 u32 sprctl; 787 788 intel_plane = to_intel_plane(plane); 789 790 key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe)); 791 key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe)); 792 key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe)); 793 key->flags = 0; 794 795 sprctl = I915_READ(SPRCTL(intel_plane->pipe)); 796 797 if (sprctl & SPRITE_DEST_KEY) 798 key->flags = I915_SET_COLORKEY_DESTINATION; 799 else if (sprctl & SPRITE_SOURCE_KEY) 800 key->flags = I915_SET_COLORKEY_SOURCE; 801 else 802 key->flags = I915_SET_COLORKEY_NONE; 803 } 804 805 static void 806 ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 807 struct drm_framebuffer *fb, 808 struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, 809 unsigned int crtc_w, unsigned int crtc_h, 810 uint32_t x, uint32_t y, 811 uint32_t src_w, uint32_t src_h) 812 { 813 struct drm_device *dev = plane->dev; 814 struct drm_i915_private *dev_priv = dev->dev_private; 815 struct intel_plane *intel_plane = to_intel_plane(plane); 816 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 817 int pipe = intel_plane->pipe; 818 unsigned long dvssurf_offset, linear_offset; 819 u32 dvscntr, dvsscale; 820 int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 821 822 dvscntr = I915_READ(DVSCNTR(pipe)); 823 824 /* Mask out pixel format bits in case we change it */ 825 dvscntr &= ~DVS_PIXFORMAT_MASK; 826 dvscntr &= ~DVS_RGB_ORDER_XBGR; 827 dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; 828 dvscntr &= ~DVS_TILED; 829 dvscntr &= ~DVS_ROTATE_180; 830 831 switch (fb->pixel_format) { 832 case DRM_FORMAT_XBGR8888: 833 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; 834 break; 835 case DRM_FORMAT_XRGB8888: 836 dvscntr |= DVS_FORMAT_RGBX888; 837 break; 838 case DRM_FORMAT_YUYV: 839 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; 840 break; 841 case DRM_FORMAT_YVYU: 842 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; 843 break; 844 case DRM_FORMAT_UYVY: 845 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; 846 break; 847 case DRM_FORMAT_VYUY: 848 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; 849 break; 850 default: 851 BUG(); 852 } 853 854 /* 855 * Enable gamma to match primary/cursor plane behaviour. 856 * FIXME should be user controllable via propertiesa. 857 */ 858 dvscntr |= DVS_GAMMA_ENABLE; 859 860 if (obj->tiling_mode != I915_TILING_NONE) 861 dvscntr |= DVS_TILED; 862 863 if (IS_GEN6(dev)) 864 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ 865 dvscntr |= DVS_ENABLE; 866 867 intel_update_sprite_watermarks(plane, crtc, src_w, src_h, 868 pixel_size, true, 869 src_w != crtc_w || src_h != crtc_h); 870 871 /* Sizes are 0 based */ 872 src_w--; 873 src_h--; 874 crtc_w--; 875 crtc_h--; 876 877 dvsscale = 0; 878 if (crtc_w != src_w || crtc_h != src_h) 879 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; 880 881 linear_offset = y * fb->pitches[0] + x * pixel_size; 882 dvssurf_offset = 883 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, 884 pixel_size, fb->pitches[0]); 885 linear_offset -= dvssurf_offset; 886 887 if (plane->state->rotation == BIT(DRM_ROTATE_180)) { 888 dvscntr |= DVS_ROTATE_180; 889 890 x += src_w; 891 y += src_h; 892 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; 893 } 894 895 intel_update_primary_plane(intel_crtc); 896 897 I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); 898 I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 899 900 if (obj->tiling_mode != I915_TILING_NONE) 901 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); 902 else 903 I915_WRITE(DVSLINOFF(pipe), linear_offset); 904 905 I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 906 I915_WRITE(DVSSCALE(pipe), dvsscale); 907 I915_WRITE(DVSCNTR(pipe), dvscntr); 908 I915_WRITE(DVSSURF(pipe), 909 i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); 910 911 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 912 } 913 914 static void 915 ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) 916 { 917 struct drm_device *dev = plane->dev; 918 struct drm_i915_private *dev_priv = dev->dev_private; 919 struct intel_plane *intel_plane = to_intel_plane(plane); 920 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 921 int pipe = intel_plane->pipe; 922 923 intel_update_primary_plane(intel_crtc); 924 925 I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); 926 /* Disable the scaler */ 927 I915_WRITE(DVSSCALE(pipe), 0); 928 /* Flush double buffered register updates */ 929 I915_WRITE(DVSSURF(pipe), 0); 930 931 intel_flush_primary_plane(dev_priv, intel_crtc->plane); 932 933 /* 934 * Avoid underruns when disabling the sprite. 935 * FIXME remove once watermark updates are done properly. 936 */ 937 intel_crtc->atomic.wait_vblank = true; 938 intel_crtc->atomic.update_sprite_watermarks |= (1 << drm_plane_index(plane)); 939 } 940 941 /** 942 * intel_post_enable_primary - Perform operations after enabling primary plane 943 * @crtc: the CRTC whose primary plane was just enabled 944 * 945 * Performs potentially sleeping operations that must be done after the primary 946 * plane is enabled, such as updating FBC and IPS. Note that this may be 947 * called due to an explicit primary plane update, or due to an implicit 948 * re-enable that is caused when a sprite plane is updated to no longer 949 * completely hide the primary plane. 950 */ 951 void 952 intel_post_enable_primary(struct drm_crtc *crtc) 953 { 954 struct drm_device *dev = crtc->dev; 955 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 956 957 /* 958 * BDW signals flip done immediately if the plane 959 * is disabled, even if the plane enable is already 960 * armed to occur at the next vblank :( 961 */ 962 if (IS_BROADWELL(dev)) 963 intel_wait_for_vblank(dev, intel_crtc->pipe); 964 965 /* 966 * FIXME IPS should be fine as long as one plane is 967 * enabled, but in practice it seems to have problems 968 * when going from primary only to sprite only and vice 969 * versa. 970 */ 971 hsw_enable_ips(intel_crtc); 972 973 mutex_lock(&dev->struct_mutex); 974 intel_fbc_update(dev); 975 mutex_unlock(&dev->struct_mutex); 976 } 977 978 /** 979 * intel_pre_disable_primary - Perform operations before disabling primary plane 980 * @crtc: the CRTC whose primary plane is to be disabled 981 * 982 * Performs potentially sleeping operations that must be done before the 983 * primary plane is enabled, such as updating FBC and IPS. Note that this may 984 * be called due to an explicit primary plane update, or due to an implicit 985 * disable that is caused when a sprite plane completely hides the primary 986 * plane. 987 */ 988 void 989 intel_pre_disable_primary(struct drm_crtc *crtc) 990 { 991 struct drm_device *dev = crtc->dev; 992 struct drm_i915_private *dev_priv = dev->dev_private; 993 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 994 995 mutex_lock(&dev->struct_mutex); 996 if (dev_priv->fbc.plane == intel_crtc->plane) 997 intel_fbc_disable(dev); 998 mutex_unlock(&dev->struct_mutex); 999 1000 /* 1001 * FIXME IPS should be fine as long as one plane is 1002 * enabled, but in practice it seems to have problems 1003 * when going from primary only to sprite only and vice 1004 * versa. 1005 */ 1006 hsw_disable_ips(intel_crtc); 1007 } 1008 1009 static int 1010 ilk_update_colorkey(struct drm_plane *plane, 1011 struct drm_intel_sprite_colorkey *key) 1012 { 1013 struct drm_device *dev = plane->dev; 1014 struct drm_i915_private *dev_priv = dev->dev_private; 1015 struct intel_plane *intel_plane; 1016 u32 dvscntr; 1017 int ret = 0; 1018 1019 intel_plane = to_intel_plane(plane); 1020 1021 I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value); 1022 I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value); 1023 I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask); 1024 1025 dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); 1026 dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY); 1027 if (key->flags & I915_SET_COLORKEY_DESTINATION) 1028 dvscntr |= DVS_DEST_KEY; 1029 else if (key->flags & I915_SET_COLORKEY_SOURCE) 1030 dvscntr |= DVS_SOURCE_KEY; 1031 I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr); 1032 1033 POSTING_READ(DVSKEYMSK(intel_plane->pipe)); 1034 1035 return ret; 1036 } 1037 1038 static void 1039 ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) 1040 { 1041 struct drm_device *dev = plane->dev; 1042 struct drm_i915_private *dev_priv = dev->dev_private; 1043 struct intel_plane *intel_plane; 1044 u32 dvscntr; 1045 1046 intel_plane = to_intel_plane(plane); 1047 1048 key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe)); 1049 key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe)); 1050 key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe)); 1051 key->flags = 0; 1052 1053 dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); 1054 1055 if (dvscntr & DVS_DEST_KEY) 1056 key->flags = I915_SET_COLORKEY_DESTINATION; 1057 else if (dvscntr & DVS_SOURCE_KEY) 1058 key->flags = I915_SET_COLORKEY_SOURCE; 1059 else 1060 key->flags = I915_SET_COLORKEY_NONE; 1061 } 1062 1063 static bool colorkey_enabled(struct intel_plane *intel_plane) 1064 { 1065 struct drm_intel_sprite_colorkey key; 1066 1067 intel_plane->get_colorkey(&intel_plane->base, &key); 1068 1069 return key.flags != I915_SET_COLORKEY_NONE; 1070 } 1071 1072 static int 1073 intel_check_sprite_plane(struct drm_plane *plane, 1074 struct intel_plane_state *state) 1075 { 1076 struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc); 1077 struct intel_plane *intel_plane = to_intel_plane(plane); 1078 struct drm_framebuffer *fb = state->base.fb; 1079 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 1080 int crtc_x, crtc_y; 1081 unsigned int crtc_w, crtc_h; 1082 uint32_t src_x, src_y, src_w, src_h; 1083 struct drm_rect *src = &state->src; 1084 struct drm_rect *dst = &state->dst; 1085 const struct drm_rect *clip = &state->clip; 1086 int hscale, vscale; 1087 int max_scale, min_scale; 1088 int pixel_size; 1089 1090 intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc); 1091 1092 if (!fb) { 1093 state->visible = false; 1094 goto finish; 1095 } 1096 1097 /* Don't modify another pipe's plane */ 1098 if (intel_plane->pipe != intel_crtc->pipe) { 1099 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n"); 1100 return -EINVAL; 1101 } 1102 1103 /* FIXME check all gen limits */ 1104 if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) { 1105 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n"); 1106 return -EINVAL; 1107 } 1108 1109 /* Sprite planes can be linear or x-tiled surfaces */ 1110 switch (obj->tiling_mode) { 1111 case I915_TILING_NONE: 1112 case I915_TILING_X: 1113 break; 1114 default: 1115 DRM_DEBUG_KMS("Unsupported tiling mode\n"); 1116 return -EINVAL; 1117 } 1118 1119 /* 1120 * FIXME the following code does a bunch of fuzzy adjustments to the 1121 * coordinates and sizes. We probably need some way to decide whether 1122 * more strict checking should be done instead. 1123 */ 1124 max_scale = intel_plane->max_downscale << 16; 1125 min_scale = intel_plane->can_scale ? 1 : (1 << 16); 1126 1127 drm_rect_rotate(src, fb->width << 16, fb->height << 16, 1128 state->base.rotation); 1129 1130 hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale); 1131 BUG_ON(hscale < 0); 1132 1133 vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale); 1134 BUG_ON(vscale < 0); 1135 1136 state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale); 1137 1138 crtc_x = dst->x1; 1139 crtc_y = dst->y1; 1140 crtc_w = drm_rect_width(dst); 1141 crtc_h = drm_rect_height(dst); 1142 1143 if (state->visible) { 1144 /* check again in case clipping clamped the results */ 1145 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); 1146 if (hscale < 0) { 1147 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); 1148 drm_rect_debug_print(src, true); 1149 drm_rect_debug_print(dst, false); 1150 1151 return hscale; 1152 } 1153 1154 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); 1155 if (vscale < 0) { 1156 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); 1157 drm_rect_debug_print(src, true); 1158 drm_rect_debug_print(dst, false); 1159 1160 return vscale; 1161 } 1162 1163 /* Make the source viewport size an exact multiple of the scaling factors. */ 1164 drm_rect_adjust_size(src, 1165 drm_rect_width(dst) * hscale - drm_rect_width(src), 1166 drm_rect_height(dst) * vscale - drm_rect_height(src)); 1167 1168 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 1169 state->base.rotation); 1170 1171 /* sanity check to make sure the src viewport wasn't enlarged */ 1172 WARN_ON(src->x1 < (int) state->base.src_x || 1173 src->y1 < (int) state->base.src_y || 1174 src->x2 > (int) state->base.src_x + state->base.src_w || 1175 src->y2 > (int) state->base.src_y + state->base.src_h); 1176 1177 /* 1178 * Hardware doesn't handle subpixel coordinates. 1179 * Adjust to (macro)pixel boundary, but be careful not to 1180 * increase the source viewport size, because that could 1181 * push the downscaling factor out of bounds. 1182 */ 1183 src_x = src->x1 >> 16; 1184 src_w = drm_rect_width(src) >> 16; 1185 src_y = src->y1 >> 16; 1186 src_h = drm_rect_height(src) >> 16; 1187 1188 if (format_is_yuv(fb->pixel_format)) { 1189 src_x &= ~1; 1190 src_w &= ~1; 1191 1192 /* 1193 * Must keep src and dst the 1194 * same if we can't scale. 1195 */ 1196 if (!intel_plane->can_scale) 1197 crtc_w &= ~1; 1198 1199 if (crtc_w == 0) 1200 state->visible = false; 1201 } 1202 } 1203 1204 /* Check size restrictions when scaling */ 1205 if (state->visible && (src_w != crtc_w || src_h != crtc_h)) { 1206 unsigned int width_bytes; 1207 1208 WARN_ON(!intel_plane->can_scale); 1209 1210 /* FIXME interlacing min height is 6 */ 1211 1212 if (crtc_w < 3 || crtc_h < 3) 1213 state->visible = false; 1214 1215 if (src_w < 3 || src_h < 3) 1216 state->visible = false; 1217 1218 pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); 1219 width_bytes = ((src_x * pixel_size) & 63) + 1220 src_w * pixel_size; 1221 1222 if (src_w > 2048 || src_h > 2048 || 1223 width_bytes > 4096 || fb->pitches[0] > 4096) { 1224 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); 1225 return -EINVAL; 1226 } 1227 } 1228 1229 if (state->visible) { 1230 src->x1 = src_x; 1231 src->x2 = src_x + src_w; 1232 src->y1 = src_y; 1233 src->y2 = src_y + src_h; 1234 } 1235 1236 dst->x1 = crtc_x; 1237 dst->x2 = crtc_x + crtc_w; 1238 dst->y1 = crtc_y; 1239 dst->y2 = crtc_y + crtc_h; 1240 1241 finish: 1242 /* 1243 * If the sprite is completely covering the primary plane, 1244 * we can disable the primary and save power. 1245 */ 1246 state->hides_primary = fb != NULL && drm_rect_equals(dst, clip) && 1247 !colorkey_enabled(intel_plane); 1248 WARN_ON(state->hides_primary && !state->visible && intel_crtc->active); 1249 1250 if (intel_crtc->active) { 1251 if (intel_crtc->primary_enabled == state->hides_primary) 1252 intel_crtc->atomic.wait_for_flips = true; 1253 1254 if (intel_crtc->primary_enabled && state->hides_primary) 1255 intel_crtc->atomic.pre_disable_primary = true; 1256 1257 intel_crtc->atomic.fb_bits |= 1258 INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe); 1259 1260 if (!intel_crtc->primary_enabled && !state->hides_primary) 1261 intel_crtc->atomic.post_enable_primary = true; 1262 } 1263 1264 return 0; 1265 } 1266 1267 static void 1268 intel_commit_sprite_plane(struct drm_plane *plane, 1269 struct intel_plane_state *state) 1270 { 1271 struct drm_crtc *crtc = state->base.crtc; 1272 struct intel_crtc *intel_crtc; 1273 struct intel_plane *intel_plane = to_intel_plane(plane); 1274 struct drm_framebuffer *fb = state->base.fb; 1275 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 1276 int crtc_x, crtc_y; 1277 unsigned int crtc_w, crtc_h; 1278 uint32_t src_x, src_y, src_w, src_h; 1279 1280 crtc = crtc ? crtc : plane->crtc; 1281 intel_crtc = to_intel_crtc(crtc); 1282 1283 plane->fb = state->base.fb; 1284 intel_plane->obj = obj; 1285 1286 if (intel_crtc->active) { 1287 intel_crtc->primary_enabled = !state->hides_primary; 1288 1289 if (state->visible) { 1290 crtc_x = state->dst.x1; 1291 crtc_y = state->dst.y1; 1292 crtc_w = drm_rect_width(&state->dst); 1293 crtc_h = drm_rect_height(&state->dst); 1294 src_x = state->src.x1; 1295 src_y = state->src.y1; 1296 src_w = drm_rect_width(&state->src); 1297 src_h = drm_rect_height(&state->src); 1298 intel_plane->update_plane(plane, crtc, fb, obj, 1299 crtc_x, crtc_y, crtc_w, crtc_h, 1300 src_x, src_y, src_w, src_h); 1301 } else { 1302 intel_plane->disable_plane(plane, crtc); 1303 } 1304 } 1305 } 1306 1307 int intel_sprite_set_colorkey(struct drm_device *dev, void *data, 1308 struct drm_file *file_priv) 1309 { 1310 struct drm_intel_sprite_colorkey *set = data; 1311 struct drm_plane *plane; 1312 struct intel_plane *intel_plane; 1313 int ret = 0; 1314 1315 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1316 return -ENODEV; 1317 1318 /* Make sure we don't try to enable both src & dest simultaneously */ 1319 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1320 return -EINVAL; 1321 1322 drm_modeset_lock_all(dev); 1323 1324 plane = drm_plane_find(dev, set->plane_id); 1325 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) { 1326 ret = -ENOENT; 1327 goto out_unlock; 1328 } 1329 1330 intel_plane = to_intel_plane(plane); 1331 ret = intel_plane->update_colorkey(plane, set); 1332 1333 out_unlock: 1334 drm_modeset_unlock_all(dev); 1335 return ret; 1336 } 1337 1338 int intel_sprite_get_colorkey(struct drm_device *dev, void *data, 1339 struct drm_file *file_priv) 1340 { 1341 struct drm_intel_sprite_colorkey *get = data; 1342 struct drm_plane *plane; 1343 struct intel_plane *intel_plane; 1344 int ret = 0; 1345 1346 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1347 return -ENODEV; 1348 1349 drm_modeset_lock_all(dev); 1350 1351 plane = drm_plane_find(dev, get->plane_id); 1352 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) { 1353 ret = -ENOENT; 1354 goto out_unlock; 1355 } 1356 1357 intel_plane = to_intel_plane(plane); 1358 intel_plane->get_colorkey(plane, get); 1359 1360 out_unlock: 1361 drm_modeset_unlock_all(dev); 1362 return ret; 1363 } 1364 1365 int intel_plane_set_property(struct drm_plane *plane, 1366 struct drm_property *prop, 1367 uint64_t val) 1368 { 1369 struct drm_device *dev = plane->dev; 1370 uint64_t old_val; 1371 int ret = -ENOENT; 1372 1373 if (prop == dev->mode_config.rotation_property) { 1374 /* exactly one rotation angle please */ 1375 if (hweight32(val & 0xf) != 1) 1376 return -EINVAL; 1377 1378 if (plane->state->rotation == val) 1379 return 0; 1380 1381 old_val = plane->state->rotation; 1382 plane->state->rotation = val; 1383 ret = intel_plane_restore(plane); 1384 if (ret) 1385 plane->state->rotation = old_val; 1386 } 1387 1388 return ret; 1389 } 1390 1391 int intel_plane_restore(struct drm_plane *plane) 1392 { 1393 if (!plane->crtc || !plane->fb) 1394 return 0; 1395 1396 return plane->funcs->update_plane(plane, plane->crtc, plane->fb, 1397 plane->state->crtc_x, plane->state->crtc_y, 1398 plane->state->crtc_w, plane->state->crtc_h, 1399 plane->state->src_x, plane->state->src_y, 1400 plane->state->src_w, plane->state->src_h); 1401 } 1402 1403 static uint32_t ilk_plane_formats[] = { 1404 DRM_FORMAT_XRGB8888, 1405 DRM_FORMAT_YUYV, 1406 DRM_FORMAT_YVYU, 1407 DRM_FORMAT_UYVY, 1408 DRM_FORMAT_VYUY, 1409 }; 1410 1411 static uint32_t snb_plane_formats[] = { 1412 DRM_FORMAT_XBGR8888, 1413 DRM_FORMAT_XRGB8888, 1414 DRM_FORMAT_YUYV, 1415 DRM_FORMAT_YVYU, 1416 DRM_FORMAT_UYVY, 1417 DRM_FORMAT_VYUY, 1418 }; 1419 1420 static uint32_t vlv_plane_formats[] = { 1421 DRM_FORMAT_RGB565, 1422 DRM_FORMAT_ABGR8888, 1423 DRM_FORMAT_ARGB8888, 1424 DRM_FORMAT_XBGR8888, 1425 DRM_FORMAT_XRGB8888, 1426 DRM_FORMAT_XBGR2101010, 1427 DRM_FORMAT_ABGR2101010, 1428 DRM_FORMAT_YUYV, 1429 DRM_FORMAT_YVYU, 1430 DRM_FORMAT_UYVY, 1431 DRM_FORMAT_VYUY, 1432 }; 1433 1434 static uint32_t skl_plane_formats[] = { 1435 DRM_FORMAT_RGB565, 1436 DRM_FORMAT_ABGR8888, 1437 DRM_FORMAT_ARGB8888, 1438 DRM_FORMAT_XBGR8888, 1439 DRM_FORMAT_XRGB8888, 1440 DRM_FORMAT_YUYV, 1441 DRM_FORMAT_YVYU, 1442 DRM_FORMAT_UYVY, 1443 DRM_FORMAT_VYUY, 1444 }; 1445 1446 int 1447 intel_plane_init(struct drm_device *dev, enum i915_pipe pipe, int plane) 1448 { 1449 struct intel_plane *intel_plane; 1450 struct intel_plane_state *state; 1451 unsigned long possible_crtcs; 1452 const uint32_t *plane_formats; 1453 int num_plane_formats; 1454 int ret; 1455 1456 if (INTEL_INFO(dev)->gen < 5) 1457 return -ENODEV; 1458 1459 intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); 1460 if (!intel_plane) 1461 return -ENOMEM; 1462 1463 state = intel_create_plane_state(&intel_plane->base); 1464 if (!state) { 1465 kfree(intel_plane); 1466 return -ENOMEM; 1467 } 1468 intel_plane->base.state = &state->base; 1469 1470 switch (INTEL_INFO(dev)->gen) { 1471 case 5: 1472 case 6: 1473 intel_plane->can_scale = true; 1474 intel_plane->max_downscale = 16; 1475 intel_plane->update_plane = ilk_update_plane; 1476 intel_plane->disable_plane = ilk_disable_plane; 1477 intel_plane->update_colorkey = ilk_update_colorkey; 1478 intel_plane->get_colorkey = ilk_get_colorkey; 1479 1480 if (IS_GEN6(dev)) { 1481 plane_formats = snb_plane_formats; 1482 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 1483 } else { 1484 plane_formats = ilk_plane_formats; 1485 num_plane_formats = ARRAY_SIZE(ilk_plane_formats); 1486 } 1487 break; 1488 1489 case 7: 1490 case 8: 1491 if (IS_IVYBRIDGE(dev)) { 1492 intel_plane->can_scale = true; 1493 intel_plane->max_downscale = 2; 1494 } else { 1495 intel_plane->can_scale = false; 1496 intel_plane->max_downscale = 1; 1497 } 1498 1499 if (IS_VALLEYVIEW(dev)) { 1500 intel_plane->update_plane = vlv_update_plane; 1501 intel_plane->disable_plane = vlv_disable_plane; 1502 intel_plane->update_colorkey = vlv_update_colorkey; 1503 intel_plane->get_colorkey = vlv_get_colorkey; 1504 1505 plane_formats = vlv_plane_formats; 1506 num_plane_formats = ARRAY_SIZE(vlv_plane_formats); 1507 } else { 1508 intel_plane->update_plane = ivb_update_plane; 1509 intel_plane->disable_plane = ivb_disable_plane; 1510 intel_plane->update_colorkey = ivb_update_colorkey; 1511 intel_plane->get_colorkey = ivb_get_colorkey; 1512 1513 plane_formats = snb_plane_formats; 1514 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 1515 } 1516 break; 1517 case 9: 1518 /* 1519 * FIXME: Skylake planes can be scaled (with some restrictions), 1520 * but this is for another time. 1521 */ 1522 intel_plane->can_scale = false; 1523 intel_plane->max_downscale = 1; 1524 intel_plane->update_plane = skl_update_plane; 1525 intel_plane->disable_plane = skl_disable_plane; 1526 intel_plane->update_colorkey = skl_update_colorkey; 1527 intel_plane->get_colorkey = skl_get_colorkey; 1528 1529 plane_formats = skl_plane_formats; 1530 num_plane_formats = ARRAY_SIZE(skl_plane_formats); 1531 break; 1532 default: 1533 kfree(intel_plane); 1534 return -ENODEV; 1535 } 1536 1537 intel_plane->pipe = pipe; 1538 intel_plane->plane = plane; 1539 intel_plane->check_plane = intel_check_sprite_plane; 1540 intel_plane->commit_plane = intel_commit_sprite_plane; 1541 possible_crtcs = (1 << pipe); 1542 ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs, 1543 &intel_plane_funcs, 1544 plane_formats, num_plane_formats, 1545 DRM_PLANE_TYPE_OVERLAY); 1546 if (ret) { 1547 kfree(intel_plane); 1548 goto out; 1549 } 1550 1551 if (!dev->mode_config.rotation_property) 1552 dev->mode_config.rotation_property = 1553 drm_mode_create_rotation_property(dev, 1554 BIT(DRM_ROTATE_0) | 1555 BIT(DRM_ROTATE_180)); 1556 1557 if (dev->mode_config.rotation_property) 1558 drm_object_attach_property(&intel_plane->base.base, 1559 dev->mode_config.rotation_property, 1560 state->base.rotation); 1561 1562 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); 1563 1564 out: 1565 return ret; 1566 } 1567