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 <drm/drm_fourcc.h> 35 #include <drm/drm_rect.h> 36 #include <drm/drm_atomic.h> 37 #include <drm/drm_plane_helper.h> 38 #include "intel_drv.h" 39 #include "intel_frontbuffer.h" 40 #include <drm/i915_drm.h> 41 #include "i915_drv.h" 42 43 static bool 44 format_is_yuv(uint32_t format) 45 { 46 switch (format) { 47 case DRM_FORMAT_YUYV: 48 case DRM_FORMAT_UYVY: 49 case DRM_FORMAT_VYUY: 50 case DRM_FORMAT_YVYU: 51 return true; 52 default: 53 return false; 54 } 55 } 56 57 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 58 int usecs) 59 { 60 /* paranoia */ 61 if (!adjusted_mode->crtc_htotal) 62 return 1; 63 64 return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock, 65 1000 * adjusted_mode->crtc_htotal); 66 } 67 68 #define VBLANK_EVASION_TIME_US 100 69 70 /** 71 * intel_pipe_update_start() - start update of a set of display registers 72 * @crtc: the crtc of which the registers are going to be updated 73 * @start_vbl_count: vblank counter return pointer used for error checking 74 * 75 * Mark the start of an update to pipe registers that should be updated 76 * atomically regarding vblank. If the next vblank will happens within 77 * the next 100 us, this function waits until the vblank passes. 78 * 79 * After a successful call to this function, interrupts will be disabled 80 * until a subsequent call to intel_pipe_update_end(). That is done to 81 * avoid random delays. The value written to @start_vbl_count should be 82 * supplied to intel_pipe_update_end() for error checking. 83 */ 84 void intel_pipe_update_start(struct intel_crtc *crtc) 85 { 86 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 87 const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; 88 long timeout = msecs_to_jiffies_timeout(1); 89 int scanline, min, max, vblank_start; 90 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); 91 bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 92 intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DSI); 93 DEFINE_WAIT(wait); 94 95 vblank_start = adjusted_mode->crtc_vblank_start; 96 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 97 vblank_start = DIV_ROUND_UP(vblank_start, 2); 98 99 /* FIXME needs to be calibrated sensibly */ 100 min = vblank_start - intel_usecs_to_scanlines(adjusted_mode, 101 VBLANK_EVASION_TIME_US); 102 max = vblank_start - 1; 103 104 local_irq_disable(); 105 106 if (min <= 0 || max <= 0) 107 return; 108 109 if (WARN_ON(drm_crtc_vblank_get(&crtc->base))) 110 return; 111 112 crtc->debug.min_vbl = min; 113 crtc->debug.max_vbl = max; 114 trace_i915_pipe_update_start(crtc); 115 116 for (;;) { 117 /* 118 * prepare_to_wait() has a memory barrier, which guarantees 119 * other CPUs can see the task state update by the time we 120 * read the scanline. 121 */ 122 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); 123 124 scanline = intel_get_crtc_scanline(crtc); 125 if (scanline < min || scanline > max) 126 break; 127 128 if (timeout <= 0) { 129 DRM_ERROR("Potential atomic update failure on pipe %c\n", 130 pipe_name(crtc->pipe)); 131 break; 132 } 133 134 local_irq_enable(); 135 136 timeout = schedule_timeout(timeout); 137 138 local_irq_disable(); 139 } 140 141 finish_wait(wq, &wait); 142 143 drm_crtc_vblank_put(&crtc->base); 144 145 /* 146 * On VLV/CHV DSI the scanline counter would appear to 147 * increment approx. 1/3 of a scanline before start of vblank. 148 * The registers still get latched at start of vblank however. 149 * This means we must not write any registers on the first 150 * line of vblank (since not the whole line is actually in 151 * vblank). And unfortunately we can't use the interrupt to 152 * wait here since it will fire too soon. We could use the 153 * frame start interrupt instead since it will fire after the 154 * critical scanline, but that would require more changes 155 * in the interrupt code. So for now we'll just do the nasty 156 * thing and poll for the bad scanline to pass us by. 157 * 158 * FIXME figure out if BXT+ DSI suffers from this as well 159 */ 160 while (need_vlv_dsi_wa && scanline == vblank_start) 161 scanline = intel_get_crtc_scanline(crtc); 162 163 crtc->debug.scanline_start = scanline; 164 crtc->debug.start_vbl_time = ktime_get(); 165 crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc); 166 167 trace_i915_pipe_update_vblank_evaded(crtc); 168 } 169 170 /** 171 * intel_pipe_update_end() - end update of a set of display registers 172 * @crtc: the crtc of which the registers were updated 173 * @start_vbl_count: start vblank counter (used for error checking) 174 * 175 * Mark the end of an update started with intel_pipe_update_start(). This 176 * re-enables interrupts and verifies the update was actually completed 177 * before a vblank using the value of @start_vbl_count. 178 */ 179 void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work) 180 { 181 enum i915_pipe pipe = crtc->pipe; 182 int scanline_end = intel_get_crtc_scanline(crtc); 183 u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc); 184 ktime_t end_vbl_time = ktime_get(); 185 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 186 187 if (work) { 188 work->flip_queued_vblank = end_vbl_count; 189 smp_mb__before_atomic(); 190 atomic_set(&work->pending, 1); 191 } 192 193 trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end); 194 195 /* We're still in the vblank-evade critical section, this can't race. 196 * Would be slightly nice to just grab the vblank count and arm the 197 * event outside of the critical section - the spinlock might spin for a 198 * while ... */ 199 if (crtc->base.state->event) { 200 WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0); 201 202 lockmgr(&crtc->base.dev->event_lock, LK_EXCLUSIVE); 203 drm_crtc_arm_vblank_event(&crtc->base, crtc->base.state->event); 204 lockmgr(&crtc->base.dev->event_lock, LK_RELEASE); 205 206 crtc->base.state->event = NULL; 207 } 208 209 local_irq_enable(); 210 211 if (intel_vgpu_active(dev_priv)) 212 return; 213 214 if (crtc->debug.start_vbl_count && 215 crtc->debug.start_vbl_count != end_vbl_count) { 216 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", 217 pipe_name(pipe), crtc->debug.start_vbl_count, 218 end_vbl_count, 219 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), 220 crtc->debug.min_vbl, crtc->debug.max_vbl, 221 crtc->debug.scanline_start, scanline_end); 222 } 223 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE 224 else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) > 225 VBLANK_EVASION_TIME_US) 226 DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n", 227 pipe_name(pipe), 228 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), 229 VBLANK_EVASION_TIME_US); 230 #endif 231 } 232 233 static void 234 skl_update_plane(struct drm_plane *drm_plane, 235 const struct intel_crtc_state *crtc_state, 236 const struct intel_plane_state *plane_state) 237 { 238 struct drm_device *dev = drm_plane->dev; 239 struct drm_i915_private *dev_priv = to_i915(dev); 240 struct intel_plane *intel_plane = to_intel_plane(drm_plane); 241 struct drm_framebuffer *fb = plane_state->base.fb; 242 enum plane_id plane_id = intel_plane->id; 243 enum i915_pipe pipe = intel_plane->pipe; 244 u32 plane_ctl = plane_state->ctl; 245 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 246 u32 surf_addr = plane_state->main.offset; 247 unsigned int rotation = plane_state->base.rotation; 248 u32 stride = skl_plane_stride(fb, 0, rotation); 249 int crtc_x = plane_state->base.dst.x1; 250 int crtc_y = plane_state->base.dst.y1; 251 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 252 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 253 uint32_t x = plane_state->main.x; 254 uint32_t y = plane_state->main.y; 255 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; 256 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; 257 unsigned long irqflags; 258 259 /* Sizes are 0 based */ 260 src_w--; 261 src_h--; 262 crtc_w--; 263 crtc_h--; 264 265 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 266 267 if (IS_GEMINILAKE(dev_priv)) { 268 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), 269 PLANE_COLOR_PIPE_GAMMA_ENABLE | 270 PLANE_COLOR_PIPE_CSC_ENABLE | 271 PLANE_COLOR_PLANE_GAMMA_DISABLE); 272 } 273 274 if (key->flags) { 275 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); 276 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value); 277 I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), key->channel_mask); 278 } 279 280 I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x); 281 I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride); 282 I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); 283 284 /* program plane scaler */ 285 if (plane_state->scaler_id >= 0) { 286 int scaler_id = plane_state->scaler_id; 287 const struct intel_scaler *scaler; 288 289 scaler = &crtc_state->scaler_state.scalers[scaler_id]; 290 291 I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id), 292 PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode); 293 I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0); 294 I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y); 295 I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), 296 ((crtc_w + 1) << 16)|(crtc_h + 1)); 297 298 I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0); 299 } else { 300 I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x); 301 } 302 303 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl); 304 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 305 intel_plane_ggtt_offset(plane_state) + surf_addr); 306 POSTING_READ_FW(PLANE_SURF(pipe, plane_id)); 307 308 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 309 } 310 311 static void 312 skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) 313 { 314 struct drm_device *dev = dplane->dev; 315 struct drm_i915_private *dev_priv = to_i915(dev); 316 struct intel_plane *intel_plane = to_intel_plane(dplane); 317 enum plane_id plane_id = intel_plane->id; 318 enum i915_pipe pipe = intel_plane->pipe; 319 unsigned long irqflags; 320 321 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 322 323 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0); 324 325 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0); 326 POSTING_READ_FW(PLANE_SURF(pipe, plane_id)); 327 328 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 329 } 330 331 static void 332 chv_update_csc(struct intel_plane *intel_plane, uint32_t format) 333 { 334 struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev); 335 enum plane_id plane_id = intel_plane->id; 336 337 /* Seems RGB data bypasses the CSC always */ 338 if (!format_is_yuv(format)) 339 return; 340 341 /* 342 * BT.601 limited range YCbCr -> full range RGB 343 * 344 * |r| | 6537 4769 0| |cr | 345 * |g| = |-3330 4769 -1605| x |y-64| 346 * |b| | 0 4769 8263| |cb | 347 * 348 * Cb and Cr apparently come in as signed already, so no 349 * need for any offset. For Y we need to remove the offset. 350 */ 351 I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(-64)); 352 I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 353 I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 354 355 I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4769) | SPCSC_C0(6537)); 356 I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-3330) | SPCSC_C0(0)); 357 I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1605) | SPCSC_C0(4769)); 358 I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4769) | SPCSC_C0(0)); 359 I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(8263)); 360 361 I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(940) | SPCSC_IMIN(64)); 362 I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); 363 I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); 364 365 I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 366 I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 367 I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 368 } 369 370 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, 371 const struct intel_plane_state *plane_state) 372 { 373 const struct drm_framebuffer *fb = plane_state->base.fb; 374 unsigned int rotation = plane_state->base.rotation; 375 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 376 u32 sprctl; 377 378 sprctl = SP_ENABLE | SP_GAMMA_ENABLE; 379 380 switch (fb->format->format) { 381 case DRM_FORMAT_YUYV: 382 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 383 break; 384 case DRM_FORMAT_YVYU: 385 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 386 break; 387 case DRM_FORMAT_UYVY: 388 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 389 break; 390 case DRM_FORMAT_VYUY: 391 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 392 break; 393 case DRM_FORMAT_RGB565: 394 sprctl |= SP_FORMAT_BGR565; 395 break; 396 case DRM_FORMAT_XRGB8888: 397 sprctl |= SP_FORMAT_BGRX8888; 398 break; 399 case DRM_FORMAT_ARGB8888: 400 sprctl |= SP_FORMAT_BGRA8888; 401 break; 402 case DRM_FORMAT_XBGR2101010: 403 sprctl |= SP_FORMAT_RGBX1010102; 404 break; 405 case DRM_FORMAT_ABGR2101010: 406 sprctl |= SP_FORMAT_RGBA1010102; 407 break; 408 case DRM_FORMAT_XBGR8888: 409 sprctl |= SP_FORMAT_RGBX8888; 410 break; 411 case DRM_FORMAT_ABGR8888: 412 sprctl |= SP_FORMAT_RGBA8888; 413 break; 414 default: 415 MISSING_CASE(fb->format->format); 416 return 0; 417 } 418 419 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 420 sprctl |= SP_TILED; 421 422 if (rotation & DRM_ROTATE_180) 423 sprctl |= SP_ROTATE_180; 424 425 if (rotation & DRM_REFLECT_X) 426 sprctl |= SP_MIRROR; 427 428 if (key->flags & I915_SET_COLORKEY_SOURCE) 429 sprctl |= SP_SOURCE_KEY; 430 431 return sprctl; 432 } 433 434 static void 435 vlv_update_plane(struct drm_plane *dplane, 436 const struct intel_crtc_state *crtc_state, 437 const struct intel_plane_state *plane_state) 438 { 439 struct drm_device *dev = dplane->dev; 440 struct drm_i915_private *dev_priv = to_i915(dev); 441 struct intel_plane *intel_plane = to_intel_plane(dplane); 442 struct drm_framebuffer *fb = plane_state->base.fb; 443 enum i915_pipe pipe = intel_plane->pipe; 444 enum plane_id plane_id = intel_plane->id; 445 u32 sprctl = plane_state->ctl; 446 u32 sprsurf_offset = plane_state->main.offset; 447 u32 linear_offset; 448 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 449 int crtc_x = plane_state->base.dst.x1; 450 int crtc_y = plane_state->base.dst.y1; 451 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 452 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 453 uint32_t x = plane_state->main.x; 454 uint32_t y = plane_state->main.y; 455 unsigned long irqflags; 456 457 /* Sizes are 0 based */ 458 crtc_w--; 459 crtc_h--; 460 461 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 462 463 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 464 465 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) 466 chv_update_csc(intel_plane, fb->format->format); 467 468 if (key->flags) { 469 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value); 470 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value); 471 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask); 472 } 473 I915_WRITE_FW(SPSTRIDE(pipe, plane_id), fb->pitches[0]); 474 I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x); 475 476 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 477 I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x); 478 else 479 I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset); 480 481 I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0); 482 483 I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w); 484 I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl); 485 I915_WRITE_FW(SPSURF(pipe, plane_id), 486 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 487 POSTING_READ_FW(SPSURF(pipe, plane_id)); 488 489 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 490 } 491 492 static void 493 vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) 494 { 495 struct drm_device *dev = dplane->dev; 496 struct drm_i915_private *dev_priv = to_i915(dev); 497 struct intel_plane *intel_plane = to_intel_plane(dplane); 498 enum i915_pipe pipe = intel_plane->pipe; 499 enum plane_id plane_id = intel_plane->id; 500 unsigned long irqflags; 501 502 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 503 504 I915_WRITE_FW(SPCNTR(pipe, plane_id), 0); 505 506 I915_WRITE_FW(SPSURF(pipe, plane_id), 0); 507 POSTING_READ_FW(SPSURF(pipe, plane_id)); 508 509 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 510 } 511 512 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, 513 const struct intel_plane_state *plane_state) 514 { 515 struct drm_i915_private *dev_priv = 516 to_i915(plane_state->base.plane->dev); 517 const struct drm_framebuffer *fb = plane_state->base.fb; 518 unsigned int rotation = plane_state->base.rotation; 519 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 520 u32 sprctl; 521 522 sprctl = SPRITE_ENABLE | SPRITE_GAMMA_ENABLE; 523 524 if (IS_IVYBRIDGE(dev_priv)) 525 sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 526 527 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 528 sprctl |= SPRITE_PIPE_CSC_ENABLE; 529 530 switch (fb->format->format) { 531 case DRM_FORMAT_XBGR8888: 532 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 533 break; 534 case DRM_FORMAT_XRGB8888: 535 sprctl |= SPRITE_FORMAT_RGBX888; 536 break; 537 case DRM_FORMAT_YUYV: 538 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 539 break; 540 case DRM_FORMAT_YVYU: 541 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 542 break; 543 case DRM_FORMAT_UYVY: 544 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 545 break; 546 case DRM_FORMAT_VYUY: 547 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 548 break; 549 default: 550 MISSING_CASE(fb->format->format); 551 return 0; 552 } 553 554 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 555 sprctl |= SPRITE_TILED; 556 557 if (rotation & DRM_ROTATE_180) 558 sprctl |= SPRITE_ROTATE_180; 559 560 if (key->flags & I915_SET_COLORKEY_DESTINATION) 561 sprctl |= SPRITE_DEST_KEY; 562 else if (key->flags & I915_SET_COLORKEY_SOURCE) 563 sprctl |= SPRITE_SOURCE_KEY; 564 565 return sprctl; 566 } 567 568 static void 569 ivb_update_plane(struct drm_plane *plane, 570 const struct intel_crtc_state *crtc_state, 571 const struct intel_plane_state *plane_state) 572 { 573 struct drm_device *dev = plane->dev; 574 struct drm_i915_private *dev_priv = to_i915(dev); 575 struct intel_plane *intel_plane = to_intel_plane(plane); 576 struct drm_framebuffer *fb = plane_state->base.fb; 577 enum i915_pipe pipe = intel_plane->pipe; 578 u32 sprctl = plane_state->ctl, sprscale = 0; 579 u32 sprsurf_offset = plane_state->main.offset; 580 u32 linear_offset; 581 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 582 int crtc_x = plane_state->base.dst.x1; 583 int crtc_y = plane_state->base.dst.y1; 584 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 585 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 586 uint32_t x = plane_state->main.x; 587 uint32_t y = plane_state->main.y; 588 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; 589 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; 590 unsigned long irqflags; 591 592 /* Sizes are 0 based */ 593 src_w--; 594 src_h--; 595 crtc_w--; 596 crtc_h--; 597 598 if (crtc_w != src_w || crtc_h != src_h) 599 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 600 601 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 602 603 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 604 605 if (key->flags) { 606 I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value); 607 I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value); 608 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask); 609 } 610 611 I915_WRITE_FW(SPRSTRIDE(pipe), fb->pitches[0]); 612 I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 613 614 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 615 * register */ 616 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 617 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x); 618 else if (fb->modifier == I915_FORMAT_MOD_X_TILED) 619 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x); 620 else 621 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset); 622 623 I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 624 if (intel_plane->can_scale) 625 I915_WRITE_FW(SPRSCALE(pipe), sprscale); 626 I915_WRITE_FW(SPRCTL(pipe), sprctl); 627 I915_WRITE_FW(SPRSURF(pipe), 628 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 629 POSTING_READ_FW(SPRSURF(pipe)); 630 631 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 632 } 633 634 static void 635 ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) 636 { 637 struct drm_device *dev = plane->dev; 638 struct drm_i915_private *dev_priv = to_i915(dev); 639 struct intel_plane *intel_plane = to_intel_plane(plane); 640 int pipe = intel_plane->pipe; 641 unsigned long irqflags; 642 643 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 644 645 I915_WRITE_FW(SPRCTL(pipe), 0); 646 /* Can't leave the scaler enabled... */ 647 if (intel_plane->can_scale) 648 I915_WRITE_FW(SPRSCALE(pipe), 0); 649 650 I915_WRITE_FW(SPRSURF(pipe), 0); 651 POSTING_READ_FW(SPRSURF(pipe)); 652 653 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 654 } 655 656 static u32 ilk_sprite_ctl(const struct intel_crtc_state *crtc_state, 657 const struct intel_plane_state *plane_state) 658 { 659 struct drm_i915_private *dev_priv = 660 to_i915(plane_state->base.plane->dev); 661 const struct drm_framebuffer *fb = plane_state->base.fb; 662 unsigned int rotation = plane_state->base.rotation; 663 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 664 u32 dvscntr; 665 666 dvscntr = DVS_ENABLE | DVS_GAMMA_ENABLE; 667 668 if (IS_GEN6(dev_priv)) 669 dvscntr |= DVS_TRICKLE_FEED_DISABLE; 670 671 switch (fb->format->format) { 672 case DRM_FORMAT_XBGR8888: 673 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; 674 break; 675 case DRM_FORMAT_XRGB8888: 676 dvscntr |= DVS_FORMAT_RGBX888; 677 break; 678 case DRM_FORMAT_YUYV: 679 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; 680 break; 681 case DRM_FORMAT_YVYU: 682 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; 683 break; 684 case DRM_FORMAT_UYVY: 685 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; 686 break; 687 case DRM_FORMAT_VYUY: 688 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; 689 break; 690 default: 691 MISSING_CASE(fb->format->format); 692 return 0; 693 } 694 695 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 696 dvscntr |= DVS_TILED; 697 698 if (rotation & DRM_ROTATE_180) 699 dvscntr |= DVS_ROTATE_180; 700 701 if (key->flags & I915_SET_COLORKEY_DESTINATION) 702 dvscntr |= DVS_DEST_KEY; 703 else if (key->flags & I915_SET_COLORKEY_SOURCE) 704 dvscntr |= DVS_SOURCE_KEY; 705 706 return dvscntr; 707 } 708 709 static void 710 ilk_update_plane(struct drm_plane *plane, 711 const struct intel_crtc_state *crtc_state, 712 const struct intel_plane_state *plane_state) 713 { 714 struct drm_device *dev = plane->dev; 715 struct drm_i915_private *dev_priv = to_i915(dev); 716 struct intel_plane *intel_plane = to_intel_plane(plane); 717 struct drm_framebuffer *fb = plane_state->base.fb; 718 int pipe = intel_plane->pipe; 719 u32 dvscntr = plane_state->ctl, dvsscale = 0; 720 u32 dvssurf_offset = plane_state->main.offset; 721 u32 linear_offset; 722 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 723 int crtc_x = plane_state->base.dst.x1; 724 int crtc_y = plane_state->base.dst.y1; 725 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 726 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 727 uint32_t x = plane_state->main.x; 728 uint32_t y = plane_state->main.y; 729 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; 730 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; 731 unsigned long irqflags; 732 733 /* Sizes are 0 based */ 734 src_w--; 735 src_h--; 736 crtc_w--; 737 crtc_h--; 738 739 if (crtc_w != src_w || crtc_h != src_h) 740 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; 741 742 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 743 744 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 745 746 if (key->flags) { 747 I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value); 748 I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value); 749 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask); 750 } 751 752 I915_WRITE_FW(DVSSTRIDE(pipe), fb->pitches[0]); 753 I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 754 755 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 756 I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x); 757 else 758 I915_WRITE_FW(DVSLINOFF(pipe), linear_offset); 759 760 I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 761 I915_WRITE_FW(DVSSCALE(pipe), dvsscale); 762 I915_WRITE_FW(DVSCNTR(pipe), dvscntr); 763 I915_WRITE_FW(DVSSURF(pipe), 764 intel_plane_ggtt_offset(plane_state) + dvssurf_offset); 765 POSTING_READ_FW(DVSSURF(pipe)); 766 767 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 768 } 769 770 static void 771 ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) 772 { 773 struct drm_device *dev = plane->dev; 774 struct drm_i915_private *dev_priv = to_i915(dev); 775 struct intel_plane *intel_plane = to_intel_plane(plane); 776 int pipe = intel_plane->pipe; 777 unsigned long irqflags; 778 779 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 780 781 I915_WRITE_FW(DVSCNTR(pipe), 0); 782 /* Disable the scaler */ 783 I915_WRITE_FW(DVSSCALE(pipe), 0); 784 785 I915_WRITE_FW(DVSSURF(pipe), 0); 786 POSTING_READ_FW(DVSSURF(pipe)); 787 788 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 789 } 790 791 static int 792 intel_check_sprite_plane(struct drm_plane *plane, 793 struct intel_crtc_state *crtc_state, 794 struct intel_plane_state *state) 795 { 796 struct drm_i915_private *dev_priv = to_i915(plane->dev); 797 struct drm_crtc *crtc = state->base.crtc; 798 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 799 struct intel_plane *intel_plane = to_intel_plane(plane); 800 struct drm_framebuffer *fb = state->base.fb; 801 int crtc_x, crtc_y; 802 unsigned int crtc_w, crtc_h; 803 uint32_t src_x, src_y, src_w, src_h; 804 struct drm_rect *src = &state->base.src; 805 struct drm_rect *dst = &state->base.dst; 806 const struct drm_rect *clip = &state->clip; 807 int hscale, vscale; 808 int max_scale, min_scale; 809 bool can_scale; 810 int ret; 811 812 *src = drm_plane_state_src(&state->base); 813 *dst = drm_plane_state_dest(&state->base); 814 815 if (!fb) { 816 state->base.visible = false; 817 return 0; 818 } 819 820 /* Don't modify another pipe's plane */ 821 if (intel_plane->pipe != intel_crtc->pipe) { 822 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n"); 823 return -EINVAL; 824 } 825 826 /* FIXME check all gen limits */ 827 if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) { 828 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n"); 829 return -EINVAL; 830 } 831 832 /* setup can_scale, min_scale, max_scale */ 833 if (INTEL_GEN(dev_priv) >= 9) { 834 /* use scaler when colorkey is not required */ 835 if (state->ckey.flags == I915_SET_COLORKEY_NONE) { 836 can_scale = 1; 837 min_scale = 1; 838 max_scale = skl_max_scale(intel_crtc, crtc_state); 839 } else { 840 can_scale = 0; 841 min_scale = DRM_PLANE_HELPER_NO_SCALING; 842 max_scale = DRM_PLANE_HELPER_NO_SCALING; 843 } 844 } else { 845 can_scale = intel_plane->can_scale; 846 max_scale = intel_plane->max_downscale << 16; 847 min_scale = intel_plane->can_scale ? 1 : (1 << 16); 848 } 849 850 /* 851 * FIXME the following code does a bunch of fuzzy adjustments to the 852 * coordinates and sizes. We probably need some way to decide whether 853 * more strict checking should be done instead. 854 */ 855 drm_rect_rotate(src, fb->width << 16, fb->height << 16, 856 state->base.rotation); 857 858 hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale); 859 BUG_ON(hscale < 0); 860 861 vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale); 862 BUG_ON(vscale < 0); 863 864 state->base.visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale); 865 866 crtc_x = dst->x1; 867 crtc_y = dst->y1; 868 crtc_w = drm_rect_width(dst); 869 crtc_h = drm_rect_height(dst); 870 871 if (state->base.visible) { 872 /* check again in case clipping clamped the results */ 873 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); 874 if (hscale < 0) { 875 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); 876 drm_rect_debug_print("src: ", src, true); 877 drm_rect_debug_print("dst: ", dst, false); 878 879 return hscale; 880 } 881 882 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); 883 if (vscale < 0) { 884 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); 885 drm_rect_debug_print("src: ", src, true); 886 drm_rect_debug_print("dst: ", dst, false); 887 888 return vscale; 889 } 890 891 /* Make the source viewport size an exact multiple of the scaling factors. */ 892 drm_rect_adjust_size(src, 893 drm_rect_width(dst) * hscale - drm_rect_width(src), 894 drm_rect_height(dst) * vscale - drm_rect_height(src)); 895 896 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 897 state->base.rotation); 898 899 /* sanity check to make sure the src viewport wasn't enlarged */ 900 WARN_ON(src->x1 < (int) state->base.src_x || 901 src->y1 < (int) state->base.src_y || 902 src->x2 > (int) state->base.src_x + state->base.src_w || 903 src->y2 > (int) state->base.src_y + state->base.src_h); 904 905 /* 906 * Hardware doesn't handle subpixel coordinates. 907 * Adjust to (macro)pixel boundary, but be careful not to 908 * increase the source viewport size, because that could 909 * push the downscaling factor out of bounds. 910 */ 911 src_x = src->x1 >> 16; 912 src_w = drm_rect_width(src) >> 16; 913 src_y = src->y1 >> 16; 914 src_h = drm_rect_height(src) >> 16; 915 916 if (format_is_yuv(fb->format->format)) { 917 src_x &= ~1; 918 src_w &= ~1; 919 920 /* 921 * Must keep src and dst the 922 * same if we can't scale. 923 */ 924 if (!can_scale) 925 crtc_w &= ~1; 926 927 if (crtc_w == 0) 928 state->base.visible = false; 929 } 930 } 931 932 /* Check size restrictions when scaling */ 933 if (state->base.visible && (src_w != crtc_w || src_h != crtc_h)) { 934 unsigned int width_bytes; 935 int cpp = fb->format->cpp[0]; 936 937 WARN_ON(!can_scale); 938 939 /* FIXME interlacing min height is 6 */ 940 941 if (crtc_w < 3 || crtc_h < 3) 942 state->base.visible = false; 943 944 if (src_w < 3 || src_h < 3) 945 state->base.visible = false; 946 947 width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 948 949 if (INTEL_GEN(dev_priv) < 9 && (src_w > 2048 || src_h > 2048 || 950 width_bytes > 4096 || fb->pitches[0] > 4096)) { 951 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); 952 return -EINVAL; 953 } 954 } 955 956 if (state->base.visible) { 957 src->x1 = src_x << 16; 958 src->x2 = (src_x + src_w) << 16; 959 src->y1 = src_y << 16; 960 src->y2 = (src_y + src_h) << 16; 961 } 962 963 dst->x1 = crtc_x; 964 dst->x2 = crtc_x + crtc_w; 965 dst->y1 = crtc_y; 966 dst->y2 = crtc_y + crtc_h; 967 968 if (INTEL_GEN(dev_priv) >= 9) { 969 ret = skl_check_plane_surface(state); 970 if (ret) 971 return ret; 972 973 state->ctl = skl_plane_ctl(crtc_state, state); 974 } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 975 ret = i9xx_check_plane_surface(state); 976 if (ret) 977 return ret; 978 979 state->ctl = vlv_sprite_ctl(crtc_state, state); 980 } else if (INTEL_GEN(dev_priv) >= 7) { 981 ret = i9xx_check_plane_surface(state); 982 if (ret) 983 return ret; 984 985 state->ctl = ivb_sprite_ctl(crtc_state, state); 986 } else { 987 ret = i9xx_check_plane_surface(state); 988 if (ret) 989 return ret; 990 991 state->ctl = ilk_sprite_ctl(crtc_state, state); 992 } 993 994 return 0; 995 } 996 997 int intel_sprite_set_colorkey(struct drm_device *dev, void *data, 998 struct drm_file *file_priv) 999 { 1000 struct drm_i915_private *dev_priv = to_i915(dev); 1001 struct drm_intel_sprite_colorkey *set = data; 1002 struct drm_plane *plane; 1003 struct drm_plane_state *plane_state; 1004 struct drm_atomic_state *state; 1005 struct drm_modeset_acquire_ctx ctx; 1006 int ret = 0; 1007 1008 /* Make sure we don't try to enable both src & dest simultaneously */ 1009 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 1010 return -EINVAL; 1011 1012 if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 1013 set->flags & I915_SET_COLORKEY_DESTINATION) 1014 return -EINVAL; 1015 1016 plane = drm_plane_find(dev, set->plane_id); 1017 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) 1018 return -ENOENT; 1019 1020 drm_modeset_acquire_init(&ctx, 0); 1021 1022 state = drm_atomic_state_alloc(plane->dev); 1023 if (!state) { 1024 ret = -ENOMEM; 1025 goto out; 1026 } 1027 state->acquire_ctx = &ctx; 1028 1029 while (1) { 1030 plane_state = drm_atomic_get_plane_state(state, plane); 1031 ret = PTR_ERR_OR_ZERO(plane_state); 1032 if (!ret) { 1033 to_intel_plane_state(plane_state)->ckey = *set; 1034 ret = drm_atomic_commit(state); 1035 } 1036 1037 if (ret != -EDEADLK) 1038 break; 1039 1040 drm_atomic_state_clear(state); 1041 drm_modeset_backoff(&ctx); 1042 } 1043 1044 drm_atomic_state_put(state); 1045 out: 1046 drm_modeset_drop_locks(&ctx); 1047 drm_modeset_acquire_fini(&ctx); 1048 return ret; 1049 } 1050 1051 static const uint32_t ilk_plane_formats[] = { 1052 DRM_FORMAT_XRGB8888, 1053 DRM_FORMAT_YUYV, 1054 DRM_FORMAT_YVYU, 1055 DRM_FORMAT_UYVY, 1056 DRM_FORMAT_VYUY, 1057 }; 1058 1059 static const uint32_t snb_plane_formats[] = { 1060 DRM_FORMAT_XBGR8888, 1061 DRM_FORMAT_XRGB8888, 1062 DRM_FORMAT_YUYV, 1063 DRM_FORMAT_YVYU, 1064 DRM_FORMAT_UYVY, 1065 DRM_FORMAT_VYUY, 1066 }; 1067 1068 static const uint32_t vlv_plane_formats[] = { 1069 DRM_FORMAT_RGB565, 1070 DRM_FORMAT_ABGR8888, 1071 DRM_FORMAT_ARGB8888, 1072 DRM_FORMAT_XBGR8888, 1073 DRM_FORMAT_XRGB8888, 1074 DRM_FORMAT_XBGR2101010, 1075 DRM_FORMAT_ABGR2101010, 1076 DRM_FORMAT_YUYV, 1077 DRM_FORMAT_YVYU, 1078 DRM_FORMAT_UYVY, 1079 DRM_FORMAT_VYUY, 1080 }; 1081 1082 static uint32_t skl_plane_formats[] = { 1083 DRM_FORMAT_RGB565, 1084 DRM_FORMAT_ABGR8888, 1085 DRM_FORMAT_ARGB8888, 1086 DRM_FORMAT_XBGR8888, 1087 DRM_FORMAT_XRGB8888, 1088 DRM_FORMAT_YUYV, 1089 DRM_FORMAT_YVYU, 1090 DRM_FORMAT_UYVY, 1091 DRM_FORMAT_VYUY, 1092 }; 1093 1094 struct intel_plane * 1095 intel_sprite_plane_create(struct drm_i915_private *dev_priv, 1096 enum i915_pipe pipe, int plane) 1097 { 1098 struct intel_plane *intel_plane = NULL; 1099 struct intel_plane_state *state = NULL; 1100 unsigned long possible_crtcs; 1101 const uint32_t *plane_formats; 1102 unsigned int supported_rotations; 1103 int num_plane_formats; 1104 int ret; 1105 1106 intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); 1107 if (!intel_plane) { 1108 ret = -ENOMEM; 1109 goto fail; 1110 } 1111 1112 state = intel_create_plane_state(&intel_plane->base); 1113 if (!state) { 1114 ret = -ENOMEM; 1115 goto fail; 1116 } 1117 intel_plane->base.state = &state->base; 1118 1119 if (INTEL_GEN(dev_priv) >= 9) { 1120 intel_plane->can_scale = true; 1121 state->scaler_id = -1; 1122 1123 intel_plane->update_plane = skl_update_plane; 1124 intel_plane->disable_plane = skl_disable_plane; 1125 1126 plane_formats = skl_plane_formats; 1127 num_plane_formats = ARRAY_SIZE(skl_plane_formats); 1128 } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 1129 intel_plane->can_scale = false; 1130 intel_plane->max_downscale = 1; 1131 1132 intel_plane->update_plane = vlv_update_plane; 1133 intel_plane->disable_plane = vlv_disable_plane; 1134 1135 plane_formats = vlv_plane_formats; 1136 num_plane_formats = ARRAY_SIZE(vlv_plane_formats); 1137 } else if (INTEL_GEN(dev_priv) >= 7) { 1138 if (IS_IVYBRIDGE(dev_priv)) { 1139 intel_plane->can_scale = true; 1140 intel_plane->max_downscale = 2; 1141 } else { 1142 intel_plane->can_scale = false; 1143 intel_plane->max_downscale = 1; 1144 } 1145 1146 intel_plane->update_plane = ivb_update_plane; 1147 intel_plane->disable_plane = ivb_disable_plane; 1148 1149 plane_formats = snb_plane_formats; 1150 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 1151 } else { 1152 intel_plane->can_scale = true; 1153 intel_plane->max_downscale = 16; 1154 1155 intel_plane->update_plane = ilk_update_plane; 1156 intel_plane->disable_plane = ilk_disable_plane; 1157 1158 if (IS_GEN6(dev_priv)) { 1159 plane_formats = snb_plane_formats; 1160 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 1161 } else { 1162 plane_formats = ilk_plane_formats; 1163 num_plane_formats = ARRAY_SIZE(ilk_plane_formats); 1164 } 1165 } 1166 1167 if (INTEL_GEN(dev_priv) >= 9) { 1168 supported_rotations = 1169 DRM_ROTATE_0 | DRM_ROTATE_90 | 1170 DRM_ROTATE_180 | DRM_ROTATE_270; 1171 } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 1172 supported_rotations = 1173 DRM_ROTATE_0 | DRM_ROTATE_180 | 1174 DRM_REFLECT_X; 1175 } else { 1176 supported_rotations = 1177 DRM_ROTATE_0 | DRM_ROTATE_180; 1178 } 1179 1180 intel_plane->pipe = pipe; 1181 intel_plane->plane = plane; 1182 intel_plane->id = PLANE_SPRITE0 + plane; 1183 intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane); 1184 intel_plane->check_plane = intel_check_sprite_plane; 1185 1186 possible_crtcs = (1 << pipe); 1187 1188 if (INTEL_GEN(dev_priv) >= 9) 1189 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, 1190 possible_crtcs, &intel_plane_funcs, 1191 plane_formats, num_plane_formats, 1192 DRM_PLANE_TYPE_OVERLAY, 1193 "plane %d%c", plane + 2, pipe_name(pipe)); 1194 else 1195 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, 1196 possible_crtcs, &intel_plane_funcs, 1197 plane_formats, num_plane_formats, 1198 DRM_PLANE_TYPE_OVERLAY, 1199 "sprite %c", sprite_name(pipe, plane)); 1200 if (ret) 1201 goto fail; 1202 1203 drm_plane_create_rotation_property(&intel_plane->base, 1204 DRM_ROTATE_0, 1205 supported_rotations); 1206 1207 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); 1208 1209 return intel_plane; 1210 1211 fail: 1212 kfree(state); 1213 kfree(intel_plane); 1214 1215 return ERR_PTR(ret); 1216 } 1217