1 1.6 riastrad /* $NetBSD: intel_sprite.c,v 1.6 2021/12/19 12:05:09 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2011 Intel Corporation 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice (including the next 14 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the 15 1.1 riastrad * Software. 16 1.1 riastrad * 17 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 1.1 riastrad * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 1.1 riastrad * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 1.1 riastrad * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 1.1 riastrad * SOFTWARE. 24 1.1 riastrad * 25 1.1 riastrad * Authors: 26 1.1 riastrad * Jesse Barnes <jbarnes (at) virtuousgeek.org> 27 1.1 riastrad * 28 1.1 riastrad * New plane/sprite handling. 29 1.1 riastrad * 30 1.1 riastrad * The older chips had a separate interface for programming plane related 31 1.1 riastrad * registers; newer ones are much simpler and we can use the new DRM plane 32 1.1 riastrad * support. 33 1.1 riastrad */ 34 1.1 riastrad 35 1.1 riastrad #include <sys/cdefs.h> 36 1.6 riastrad __KERNEL_RCSID(0, "$NetBSD: intel_sprite.c,v 1.6 2021/12/19 12:05:09 riastradh Exp $"); 37 1.1 riastrad 38 1.1 riastrad #include <drm/drm_atomic.h> 39 1.1 riastrad #include <drm/drm_atomic_helper.h> 40 1.1 riastrad #include <drm/drm_color_mgmt.h> 41 1.1 riastrad #include <drm/drm_crtc.h> 42 1.1 riastrad #include <drm/drm_fourcc.h> 43 1.1 riastrad #include <drm/drm_plane_helper.h> 44 1.1 riastrad #include <drm/drm_rect.h> 45 1.1 riastrad #include <drm/i915_drm.h> 46 1.1 riastrad 47 1.1 riastrad #include "i915_drv.h" 48 1.1 riastrad #include "i915_trace.h" 49 1.1 riastrad #include "intel_atomic_plane.h" 50 1.1 riastrad #include "intel_display_types.h" 51 1.1 riastrad #include "intel_frontbuffer.h" 52 1.1 riastrad #include "intel_pm.h" 53 1.1 riastrad #include "intel_psr.h" 54 1.1 riastrad #include "intel_sprite.h" 55 1.1 riastrad 56 1.1 riastrad int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 57 1.1 riastrad int usecs) 58 1.1 riastrad { 59 1.1 riastrad /* paranoia */ 60 1.1 riastrad if (!adjusted_mode->crtc_htotal) 61 1.1 riastrad return 1; 62 1.1 riastrad 63 1.1 riastrad return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock, 64 1.1 riastrad 1000 * adjusted_mode->crtc_htotal); 65 1.1 riastrad } 66 1.1 riastrad 67 1.1 riastrad /* FIXME: We should instead only take spinlocks once for the entire update 68 1.1 riastrad * instead of once per mmio. */ 69 1.1 riastrad #if IS_ENABLED(CONFIG_PROVE_LOCKING) 70 1.1 riastrad #define VBLANK_EVASION_TIME_US 250 71 1.1 riastrad #else 72 1.1 riastrad #define VBLANK_EVASION_TIME_US 100 73 1.1 riastrad #endif 74 1.1 riastrad 75 1.1 riastrad /** 76 1.1 riastrad * intel_pipe_update_start() - start update of a set of display registers 77 1.1 riastrad * @new_crtc_state: the new crtc state 78 1.1 riastrad * 79 1.1 riastrad * Mark the start of an update to pipe registers that should be updated 80 1.1 riastrad * atomically regarding vblank. If the next vblank will happens within 81 1.1 riastrad * the next 100 us, this function waits until the vblank passes. 82 1.1 riastrad * 83 1.1 riastrad * After a successful call to this function, interrupts will be disabled 84 1.1 riastrad * until a subsequent call to intel_pipe_update_end(). That is done to 85 1.1 riastrad * avoid random delays. 86 1.1 riastrad */ 87 1.1 riastrad void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) 88 1.1 riastrad { 89 1.1 riastrad struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); 90 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 91 1.1 riastrad const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode; 92 1.1 riastrad long timeout = msecs_to_jiffies_timeout(1); 93 1.1 riastrad int scanline, min, max, vblank_start; 94 1.2 riastrad drm_waitqueue_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); 95 1.2 riastrad int ret; 96 1.1 riastrad bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 97 1.1 riastrad intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); 98 1.1 riastrad u32 psr_status; 99 1.1 riastrad 100 1.1 riastrad vblank_start = adjusted_mode->crtc_vblank_start; 101 1.1 riastrad if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 102 1.1 riastrad vblank_start = DIV_ROUND_UP(vblank_start, 2); 103 1.1 riastrad 104 1.1 riastrad /* FIXME needs to be calibrated sensibly */ 105 1.1 riastrad min = vblank_start - intel_usecs_to_scanlines(adjusted_mode, 106 1.1 riastrad VBLANK_EVASION_TIME_US); 107 1.1 riastrad max = vblank_start - 1; 108 1.1 riastrad 109 1.1 riastrad if (min <= 0 || max <= 0) 110 1.1 riastrad goto irq_disable; 111 1.1 riastrad 112 1.1 riastrad if (WARN_ON(drm_crtc_vblank_get(&crtc->base))) 113 1.1 riastrad goto irq_disable; 114 1.1 riastrad 115 1.1 riastrad /* 116 1.1 riastrad * Wait for psr to idle out after enabling the VBL interrupts 117 1.1 riastrad * VBL interrupts will start the PSR exit and prevent a PSR 118 1.1 riastrad * re-entry as well. 119 1.1 riastrad */ 120 1.1 riastrad if (intel_psr_wait_for_idle(new_crtc_state, &psr_status)) 121 1.1 riastrad DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n", 122 1.1 riastrad psr_status); 123 1.1 riastrad 124 1.6 riastrad spin_lock(&dev_priv->drm.event_lock); 125 1.1 riastrad 126 1.1 riastrad crtc->debug.min_vbl = min; 127 1.1 riastrad crtc->debug.max_vbl = max; 128 1.1 riastrad trace_intel_pipe_update_start(crtc); 129 1.1 riastrad 130 1.6 riastrad DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, wq, &dev_priv->drm.event_lock, 131 1.3 riastrad timeout, 132 1.2 riastrad (scanline = intel_get_crtc_scanline(crtc), 133 1.2 riastrad scanline < min || scanline > max)); 134 1.2 riastrad if (ret <= 0) 135 1.2 riastrad DRM_ERROR("Potential atomic update failure on pipe %c: %d\n", 136 1.2 riastrad pipe_name(crtc->pipe), ret ? ret : -EWOULDBLOCK); 137 1.2 riastrad drm_crtc_vblank_put_locked(&crtc->base); 138 1.1 riastrad 139 1.1 riastrad /* 140 1.1 riastrad * On VLV/CHV DSI the scanline counter would appear to 141 1.1 riastrad * increment approx. 1/3 of a scanline before start of vblank. 142 1.1 riastrad * The registers still get latched at start of vblank however. 143 1.1 riastrad * This means we must not write any registers on the first 144 1.1 riastrad * line of vblank (since not the whole line is actually in 145 1.1 riastrad * vblank). And unfortunately we can't use the interrupt to 146 1.1 riastrad * wait here since it will fire too soon. We could use the 147 1.1 riastrad * frame start interrupt instead since it will fire after the 148 1.1 riastrad * critical scanline, but that would require more changes 149 1.1 riastrad * in the interrupt code. So for now we'll just do the nasty 150 1.1 riastrad * thing and poll for the bad scanline to pass us by. 151 1.1 riastrad * 152 1.1 riastrad * FIXME figure out if BXT+ DSI suffers from this as well 153 1.1 riastrad */ 154 1.1 riastrad while (need_vlv_dsi_wa && scanline == vblank_start) 155 1.1 riastrad scanline = intel_get_crtc_scanline(crtc); 156 1.1 riastrad 157 1.1 riastrad crtc->debug.scanline_start = scanline; 158 1.1 riastrad crtc->debug.start_vbl_time = ktime_get(); 159 1.1 riastrad crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc); 160 1.1 riastrad 161 1.1 riastrad trace_intel_pipe_update_vblank_evaded(crtc); 162 1.1 riastrad return; 163 1.1 riastrad 164 1.1 riastrad irq_disable: 165 1.6 riastrad spin_lock(&dev_priv->drm.event_lock); 166 1.1 riastrad } 167 1.1 riastrad 168 1.1 riastrad /** 169 1.1 riastrad * intel_pipe_update_end() - end update of a set of display registers 170 1.1 riastrad * @new_crtc_state: the new crtc state 171 1.1 riastrad * 172 1.1 riastrad * Mark the end of an update started with intel_pipe_update_start(). This 173 1.1 riastrad * re-enables interrupts and verifies the update was actually completed 174 1.1 riastrad * before a vblank. 175 1.1 riastrad */ 176 1.1 riastrad void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) 177 1.1 riastrad { 178 1.1 riastrad struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); 179 1.1 riastrad enum pipe pipe = crtc->pipe; 180 1.1 riastrad int scanline_end = intel_get_crtc_scanline(crtc); 181 1.1 riastrad u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc); 182 1.1 riastrad ktime_t end_vbl_time = ktime_get(); 183 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 184 1.1 riastrad 185 1.6 riastrad BUG_ON(!spin_is_locked(&dev_priv->drm.event_lock)); 186 1.6 riastrad 187 1.1 riastrad trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end); 188 1.1 riastrad 189 1.1 riastrad /* We're still in the vblank-evade critical section, this can't race. 190 1.1 riastrad * Would be slightly nice to just grab the vblank count and arm the 191 1.1 riastrad * event outside of the critical section - the spinlock might spin for a 192 1.1 riastrad * while ... */ 193 1.1 riastrad if (new_crtc_state->uapi.event) { 194 1.6 riastrad WARN_ON(drm_crtc_vblank_get_locked(&crtc->base) != 0); 195 1.1 riastrad 196 1.1 riastrad drm_crtc_arm_vblank_event(&crtc->base, 197 1.1 riastrad new_crtc_state->uapi.event); 198 1.1 riastrad 199 1.1 riastrad new_crtc_state->uapi.event = NULL; 200 1.1 riastrad } 201 1.6 riastrad spin_unlock(&dev_priv->drm.event_lock); 202 1.1 riastrad 203 1.1 riastrad if (intel_vgpu_active(dev_priv)) 204 1.1 riastrad return; 205 1.1 riastrad 206 1.1 riastrad if (crtc->debug.start_vbl_count && 207 1.1 riastrad crtc->debug.start_vbl_count != end_vbl_count) { 208 1.2 riastrad DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %"PRIdMAX" us, min %d, max %d, scanline start %d, end %d\n", 209 1.1 riastrad pipe_name(pipe), crtc->debug.start_vbl_count, 210 1.1 riastrad end_vbl_count, 211 1.1 riastrad ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), 212 1.1 riastrad crtc->debug.min_vbl, crtc->debug.max_vbl, 213 1.1 riastrad crtc->debug.scanline_start, scanline_end); 214 1.1 riastrad } 215 1.1 riastrad #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE 216 1.1 riastrad else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) > 217 1.1 riastrad VBLANK_EVASION_TIME_US) 218 1.1 riastrad DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n", 219 1.1 riastrad pipe_name(pipe), 220 1.1 riastrad ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), 221 1.1 riastrad VBLANK_EVASION_TIME_US); 222 1.1 riastrad #endif 223 1.1 riastrad } 224 1.1 riastrad 225 1.1 riastrad int intel_plane_check_stride(const struct intel_plane_state *plane_state) 226 1.1 riastrad { 227 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 228 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 229 1.1 riastrad unsigned int rotation = plane_state->hw.rotation; 230 1.1 riastrad u32 stride, max_stride; 231 1.1 riastrad 232 1.1 riastrad /* 233 1.1 riastrad * We ignore stride for all invisible planes that 234 1.1 riastrad * can be remapped. Otherwise we could end up 235 1.1 riastrad * with a false positive when the remapping didn't 236 1.1 riastrad * kick in due the plane being invisible. 237 1.1 riastrad */ 238 1.1 riastrad if (intel_plane_can_remap(plane_state) && 239 1.1 riastrad !plane_state->uapi.visible) 240 1.1 riastrad return 0; 241 1.1 riastrad 242 1.1 riastrad /* FIXME other color planes? */ 243 1.1 riastrad stride = plane_state->color_plane[0].stride; 244 1.1 riastrad max_stride = plane->max_stride(plane, fb->format->format, 245 1.1 riastrad fb->modifier, rotation); 246 1.1 riastrad 247 1.1 riastrad if (stride > max_stride) { 248 1.1 riastrad DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n", 249 1.1 riastrad fb->base.id, stride, 250 1.1 riastrad plane->base.base.id, plane->base.name, max_stride); 251 1.1 riastrad return -EINVAL; 252 1.1 riastrad } 253 1.1 riastrad 254 1.1 riastrad return 0; 255 1.1 riastrad } 256 1.1 riastrad 257 1.1 riastrad int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) 258 1.1 riastrad { 259 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 260 1.1 riastrad struct drm_rect *src = &plane_state->uapi.src; 261 1.1 riastrad u32 src_x, src_y, src_w, src_h, hsub, vsub; 262 1.1 riastrad bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation); 263 1.1 riastrad 264 1.1 riastrad /* 265 1.1 riastrad * Hardware doesn't handle subpixel coordinates. 266 1.1 riastrad * Adjust to (macro)pixel boundary, but be careful not to 267 1.1 riastrad * increase the source viewport size, because that could 268 1.1 riastrad * push the downscaling factor out of bounds. 269 1.1 riastrad */ 270 1.1 riastrad src_x = src->x1 >> 16; 271 1.1 riastrad src_w = drm_rect_width(src) >> 16; 272 1.1 riastrad src_y = src->y1 >> 16; 273 1.1 riastrad src_h = drm_rect_height(src) >> 16; 274 1.1 riastrad 275 1.1 riastrad drm_rect_init(src, src_x << 16, src_y << 16, 276 1.1 riastrad src_w << 16, src_h << 16); 277 1.1 riastrad 278 1.1 riastrad if (!fb->format->is_yuv) 279 1.1 riastrad return 0; 280 1.1 riastrad 281 1.1 riastrad /* YUV specific checks */ 282 1.1 riastrad if (!rotated) { 283 1.1 riastrad hsub = fb->format->hsub; 284 1.1 riastrad vsub = fb->format->vsub; 285 1.1 riastrad } else { 286 1.1 riastrad hsub = vsub = max(fb->format->hsub, fb->format->vsub); 287 1.1 riastrad } 288 1.1 riastrad 289 1.1 riastrad if (src_x % hsub || src_w % hsub) { 290 1.1 riastrad DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u for %sYUV planes\n", 291 1.1 riastrad src_x, src_w, hsub, rotated ? "rotated " : ""); 292 1.1 riastrad return -EINVAL; 293 1.1 riastrad } 294 1.1 riastrad 295 1.1 riastrad if (src_y % vsub || src_h % vsub) { 296 1.1 riastrad DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u for %sYUV planes\n", 297 1.1 riastrad src_y, src_h, vsub, rotated ? "rotated " : ""); 298 1.1 riastrad return -EINVAL; 299 1.1 riastrad } 300 1.1 riastrad 301 1.1 riastrad return 0; 302 1.1 riastrad } 303 1.1 riastrad 304 1.1 riastrad bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id) 305 1.1 riastrad { 306 1.1 riastrad return INTEL_GEN(dev_priv) >= 11 && 307 1.1 riastrad icl_hdr_plane_mask() & BIT(plane_id); 308 1.1 riastrad } 309 1.1 riastrad 310 1.1 riastrad static void 311 1.1 riastrad skl_plane_ratio(const struct intel_crtc_state *crtc_state, 312 1.1 riastrad const struct intel_plane_state *plane_state, 313 1.1 riastrad unsigned int *num, unsigned int *den) 314 1.1 riastrad { 315 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev); 316 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 317 1.1 riastrad 318 1.1 riastrad if (fb->format->cpp[0] == 8) { 319 1.1 riastrad if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { 320 1.1 riastrad *num = 10; 321 1.1 riastrad *den = 8; 322 1.1 riastrad } else { 323 1.1 riastrad *num = 9; 324 1.1 riastrad *den = 8; 325 1.1 riastrad } 326 1.1 riastrad } else { 327 1.1 riastrad *num = 1; 328 1.1 riastrad *den = 1; 329 1.1 riastrad } 330 1.1 riastrad } 331 1.1 riastrad 332 1.1 riastrad static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 333 1.1 riastrad const struct intel_plane_state *plane_state) 334 1.1 riastrad { 335 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev); 336 1.1 riastrad unsigned int pixel_rate = crtc_state->pixel_rate; 337 1.1 riastrad unsigned int src_w, src_h, dst_w, dst_h; 338 1.1 riastrad unsigned int num, den; 339 1.1 riastrad 340 1.1 riastrad skl_plane_ratio(crtc_state, plane_state, &num, &den); 341 1.1 riastrad 342 1.1 riastrad /* two pixels per clock on glk+ */ 343 1.1 riastrad if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 344 1.1 riastrad den *= 2; 345 1.1 riastrad 346 1.1 riastrad src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 347 1.1 riastrad src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 348 1.1 riastrad dst_w = drm_rect_width(&plane_state->uapi.dst); 349 1.1 riastrad dst_h = drm_rect_height(&plane_state->uapi.dst); 350 1.1 riastrad 351 1.1 riastrad /* Downscaling limits the maximum pixel rate */ 352 1.1 riastrad dst_w = min(src_w, dst_w); 353 1.1 riastrad dst_h = min(src_h, dst_h); 354 1.1 riastrad 355 1.1 riastrad return DIV64_U64_ROUND_UP(mul_u32_u32(pixel_rate * num, src_w * src_h), 356 1.1 riastrad mul_u32_u32(den, dst_w * dst_h)); 357 1.1 riastrad } 358 1.1 riastrad 359 1.1 riastrad static unsigned int 360 1.1 riastrad skl_plane_max_stride(struct intel_plane *plane, 361 1.1 riastrad u32 pixel_format, u64 modifier, 362 1.1 riastrad unsigned int rotation) 363 1.1 riastrad { 364 1.1 riastrad const struct drm_format_info *info = drm_format_info(pixel_format); 365 1.1 riastrad int cpp = info->cpp[0]; 366 1.1 riastrad 367 1.1 riastrad /* 368 1.1 riastrad * "The stride in bytes must not exceed the 369 1.1 riastrad * of the size of 8K pixels and 32K bytes." 370 1.1 riastrad */ 371 1.1 riastrad if (drm_rotation_90_or_270(rotation)) 372 1.1 riastrad return min(8192, 32768 / cpp); 373 1.1 riastrad else 374 1.1 riastrad return min(8192 * cpp, 32768); 375 1.1 riastrad } 376 1.1 riastrad 377 1.1 riastrad static void 378 1.1 riastrad skl_program_scaler(struct intel_plane *plane, 379 1.1 riastrad const struct intel_crtc_state *crtc_state, 380 1.1 riastrad const struct intel_plane_state *plane_state) 381 1.1 riastrad { 382 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 383 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 384 1.1 riastrad enum pipe pipe = plane->pipe; 385 1.1 riastrad int scaler_id = plane_state->scaler_id; 386 1.1 riastrad const struct intel_scaler *scaler = 387 1.1 riastrad &crtc_state->scaler_state.scalers[scaler_id]; 388 1.1 riastrad int crtc_x = plane_state->uapi.dst.x1; 389 1.1 riastrad int crtc_y = plane_state->uapi.dst.y1; 390 1.1 riastrad u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 391 1.1 riastrad u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 392 1.1 riastrad u16 y_hphase, uv_rgb_hphase; 393 1.1 riastrad u16 y_vphase, uv_rgb_vphase; 394 1.1 riastrad int hscale, vscale; 395 1.1 riastrad 396 1.1 riastrad hscale = drm_rect_calc_hscale(&plane_state->uapi.src, 397 1.1 riastrad &plane_state->uapi.dst, 398 1.1 riastrad 0, INT_MAX); 399 1.1 riastrad vscale = drm_rect_calc_vscale(&plane_state->uapi.src, 400 1.1 riastrad &plane_state->uapi.dst, 401 1.1 riastrad 0, INT_MAX); 402 1.1 riastrad 403 1.1 riastrad /* TODO: handle sub-pixel coordinates */ 404 1.1 riastrad if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 405 1.1 riastrad !icl_is_hdr_plane(dev_priv, plane->id)) { 406 1.1 riastrad y_hphase = skl_scaler_calc_phase(1, hscale, false); 407 1.1 riastrad y_vphase = skl_scaler_calc_phase(1, vscale, false); 408 1.1 riastrad 409 1.1 riastrad /* MPEG2 chroma siting convention */ 410 1.1 riastrad uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true); 411 1.1 riastrad uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false); 412 1.1 riastrad } else { 413 1.1 riastrad /* not used */ 414 1.1 riastrad y_hphase = 0; 415 1.1 riastrad y_vphase = 0; 416 1.1 riastrad 417 1.1 riastrad uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false); 418 1.1 riastrad uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); 419 1.1 riastrad } 420 1.1 riastrad 421 1.1 riastrad I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id), 422 1.1 riastrad PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode); 423 1.1 riastrad I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id), 424 1.1 riastrad PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); 425 1.1 riastrad I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id), 426 1.1 riastrad PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase)); 427 1.1 riastrad I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y); 428 1.1 riastrad I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h); 429 1.1 riastrad } 430 1.1 riastrad 431 1.1 riastrad /* Preoffset values for YUV to RGB Conversion */ 432 1.1 riastrad #define PREOFF_YUV_TO_RGB_HI 0x1800 433 1.1 riastrad #define PREOFF_YUV_TO_RGB_ME 0x1F00 434 1.1 riastrad #define PREOFF_YUV_TO_RGB_LO 0x1800 435 1.1 riastrad 436 1.1 riastrad #define ROFF(x) (((x) & 0xffff) << 16) 437 1.1 riastrad #define GOFF(x) (((x) & 0xffff) << 0) 438 1.1 riastrad #define BOFF(x) (((x) & 0xffff) << 16) 439 1.1 riastrad 440 1.1 riastrad static void 441 1.1 riastrad icl_program_input_csc(struct intel_plane *plane, 442 1.1 riastrad const struct intel_crtc_state *crtc_state, 443 1.1 riastrad const struct intel_plane_state *plane_state) 444 1.1 riastrad { 445 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 446 1.1 riastrad enum pipe pipe = plane->pipe; 447 1.1 riastrad enum plane_id plane_id = plane->id; 448 1.1 riastrad 449 1.1 riastrad static const u16 input_csc_matrix[][9] = { 450 1.1 riastrad /* 451 1.1 riastrad * BT.601 full range YCbCr -> full range RGB 452 1.1 riastrad * The matrix required is : 453 1.1 riastrad * [1.000, 0.000, 1.371, 454 1.1 riastrad * 1.000, -0.336, -0.698, 455 1.1 riastrad * 1.000, 1.732, 0.0000] 456 1.1 riastrad */ 457 1.1 riastrad [DRM_COLOR_YCBCR_BT601] = { 458 1.1 riastrad 0x7AF8, 0x7800, 0x0, 459 1.1 riastrad 0x8B28, 0x7800, 0x9AC0, 460 1.1 riastrad 0x0, 0x7800, 0x7DD8, 461 1.1 riastrad }, 462 1.1 riastrad /* 463 1.1 riastrad * BT.709 full range YCbCr -> full range RGB 464 1.1 riastrad * The matrix required is : 465 1.1 riastrad * [1.000, 0.000, 1.574, 466 1.1 riastrad * 1.000, -0.187, -0.468, 467 1.1 riastrad * 1.000, 1.855, 0.0000] 468 1.1 riastrad */ 469 1.1 riastrad [DRM_COLOR_YCBCR_BT709] = { 470 1.1 riastrad 0x7C98, 0x7800, 0x0, 471 1.1 riastrad 0x9EF8, 0x7800, 0xAC00, 472 1.1 riastrad 0x0, 0x7800, 0x7ED8, 473 1.1 riastrad }, 474 1.1 riastrad /* 475 1.1 riastrad * BT.2020 full range YCbCr -> full range RGB 476 1.1 riastrad * The matrix required is : 477 1.1 riastrad * [1.000, 0.000, 1.474, 478 1.1 riastrad * 1.000, -0.1645, -0.5713, 479 1.1 riastrad * 1.000, 1.8814, 0.0000] 480 1.1 riastrad */ 481 1.1 riastrad [DRM_COLOR_YCBCR_BT2020] = { 482 1.1 riastrad 0x7BC8, 0x7800, 0x0, 483 1.1 riastrad 0x8928, 0x7800, 0xAA88, 484 1.1 riastrad 0x0, 0x7800, 0x7F10, 485 1.1 riastrad }, 486 1.1 riastrad }; 487 1.1 riastrad 488 1.1 riastrad /* Matrix for Limited Range to Full Range Conversion */ 489 1.1 riastrad static const u16 input_csc_matrix_lr[][9] = { 490 1.1 riastrad /* 491 1.1 riastrad * BT.601 Limted range YCbCr -> full range RGB 492 1.1 riastrad * The matrix required is : 493 1.1 riastrad * [1.164384, 0.000, 1.596027, 494 1.1 riastrad * 1.164384, -0.39175, -0.812813, 495 1.1 riastrad * 1.164384, 2.017232, 0.0000] 496 1.1 riastrad */ 497 1.1 riastrad [DRM_COLOR_YCBCR_BT601] = { 498 1.1 riastrad 0x7CC8, 0x7950, 0x0, 499 1.1 riastrad 0x8D00, 0x7950, 0x9C88, 500 1.1 riastrad 0x0, 0x7950, 0x6810, 501 1.1 riastrad }, 502 1.1 riastrad /* 503 1.1 riastrad * BT.709 Limited range YCbCr -> full range RGB 504 1.1 riastrad * The matrix required is : 505 1.1 riastrad * [1.164384, 0.000, 1.792741, 506 1.1 riastrad * 1.164384, -0.213249, -0.532909, 507 1.1 riastrad * 1.164384, 2.112402, 0.0000] 508 1.1 riastrad */ 509 1.1 riastrad [DRM_COLOR_YCBCR_BT709] = { 510 1.1 riastrad 0x7E58, 0x7950, 0x0, 511 1.1 riastrad 0x8888, 0x7950, 0xADA8, 512 1.1 riastrad 0x0, 0x7950, 0x6870, 513 1.1 riastrad }, 514 1.1 riastrad /* 515 1.1 riastrad * BT.2020 Limited range YCbCr -> full range RGB 516 1.1 riastrad * The matrix required is : 517 1.1 riastrad * [1.164, 0.000, 1.678, 518 1.1 riastrad * 1.164, -0.1873, -0.6504, 519 1.1 riastrad * 1.164, 2.1417, 0.0000] 520 1.1 riastrad */ 521 1.1 riastrad [DRM_COLOR_YCBCR_BT2020] = { 522 1.1 riastrad 0x7D70, 0x7950, 0x0, 523 1.1 riastrad 0x8A68, 0x7950, 0xAC00, 524 1.1 riastrad 0x0, 0x7950, 0x6890, 525 1.1 riastrad }, 526 1.1 riastrad }; 527 1.1 riastrad const u16 *csc; 528 1.1 riastrad 529 1.1 riastrad if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 530 1.1 riastrad csc = input_csc_matrix[plane_state->hw.color_encoding]; 531 1.1 riastrad else 532 1.1 riastrad csc = input_csc_matrix_lr[plane_state->hw.color_encoding]; 533 1.1 riastrad 534 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) | 535 1.1 riastrad GOFF(csc[1])); 536 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), BOFF(csc[2])); 537 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), ROFF(csc[3]) | 538 1.1 riastrad GOFF(csc[4])); 539 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), BOFF(csc[5])); 540 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), ROFF(csc[6]) | 541 1.1 riastrad GOFF(csc[7])); 542 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), BOFF(csc[8])); 543 1.1 riastrad 544 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0), 545 1.1 riastrad PREOFF_YUV_TO_RGB_HI); 546 1.1 riastrad if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 547 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 0); 548 1.1 riastrad else 549 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 550 1.1 riastrad PREOFF_YUV_TO_RGB_ME); 551 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2), 552 1.1 riastrad PREOFF_YUV_TO_RGB_LO); 553 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0); 554 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0); 555 1.1 riastrad I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0); 556 1.1 riastrad } 557 1.1 riastrad 558 1.1 riastrad static void 559 1.1 riastrad skl_program_plane(struct intel_plane *plane, 560 1.1 riastrad const struct intel_crtc_state *crtc_state, 561 1.1 riastrad const struct intel_plane_state *plane_state, 562 1.1 riastrad int color_plane) 563 1.1 riastrad { 564 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 565 1.1 riastrad enum plane_id plane_id = plane->id; 566 1.1 riastrad enum pipe pipe = plane->pipe; 567 1.1 riastrad const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 568 1.1 riastrad u32 surf_addr = plane_state->color_plane[color_plane].offset; 569 1.1 riastrad u32 stride = skl_plane_stride(plane_state, color_plane); 570 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 571 1.1 riastrad int aux_plane = intel_main_to_aux_plane(fb, color_plane); 572 1.1 riastrad u32 aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr; 573 1.1 riastrad u32 aux_stride = skl_plane_stride(plane_state, aux_plane); 574 1.1 riastrad int crtc_x = plane_state->uapi.dst.x1; 575 1.1 riastrad int crtc_y = plane_state->uapi.dst.y1; 576 1.1 riastrad u32 x = plane_state->color_plane[color_plane].x; 577 1.1 riastrad u32 y = plane_state->color_plane[color_plane].y; 578 1.1 riastrad u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 579 1.1 riastrad u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 580 1.1 riastrad u8 alpha = plane_state->hw.alpha >> 8; 581 1.1 riastrad u32 plane_color_ctl = 0; 582 1.1 riastrad unsigned long irqflags; 583 1.1 riastrad u32 keymsk, keymax; 584 1.1 riastrad u32 plane_ctl = plane_state->ctl; 585 1.1 riastrad 586 1.1 riastrad plane_ctl |= skl_plane_ctl_crtc(crtc_state); 587 1.1 riastrad 588 1.1 riastrad if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 589 1.1 riastrad plane_color_ctl = plane_state->color_ctl | 590 1.1 riastrad glk_plane_color_ctl_crtc(crtc_state); 591 1.1 riastrad 592 1.1 riastrad /* Sizes are 0 based */ 593 1.1 riastrad src_w--; 594 1.1 riastrad src_h--; 595 1.1 riastrad 596 1.1 riastrad keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha); 597 1.1 riastrad 598 1.1 riastrad keymsk = key->channel_mask & 0x7ffffff; 599 1.1 riastrad if (alpha < 0xff) 600 1.1 riastrad keymsk |= PLANE_KEYMSK_ALPHA_ENABLE; 601 1.1 riastrad 602 1.1 riastrad /* The scaler will handle the output position */ 603 1.1 riastrad if (plane_state->scaler_id >= 0) { 604 1.1 riastrad crtc_x = 0; 605 1.1 riastrad crtc_y = 0; 606 1.1 riastrad } 607 1.1 riastrad 608 1.1 riastrad spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 609 1.1 riastrad 610 1.1 riastrad I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride); 611 1.1 riastrad I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x); 612 1.1 riastrad I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); 613 1.1 riastrad 614 1.1 riastrad if (INTEL_GEN(dev_priv) < 12) 615 1.1 riastrad aux_dist |= aux_stride; 616 1.1 riastrad I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), aux_dist); 617 1.1 riastrad 618 1.1 riastrad if (icl_is_hdr_plane(dev_priv, plane_id)) 619 1.1 riastrad I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), plane_state->cus_ctl); 620 1.1 riastrad 621 1.1 riastrad if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 622 1.1 riastrad I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl); 623 1.1 riastrad 624 1.1 riastrad if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id)) 625 1.1 riastrad icl_program_input_csc(plane, crtc_state, plane_state); 626 1.1 riastrad 627 1.1 riastrad skl_write_plane_wm(plane, crtc_state); 628 1.1 riastrad 629 1.1 riastrad I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); 630 1.1 riastrad I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk); 631 1.1 riastrad I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax); 632 1.1 riastrad 633 1.1 riastrad I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x); 634 1.1 riastrad 635 1.1 riastrad if (INTEL_GEN(dev_priv) < 11) 636 1.1 riastrad I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id), 637 1.1 riastrad (plane_state->color_plane[1].y << 16) | 638 1.1 riastrad plane_state->color_plane[1].x); 639 1.1 riastrad 640 1.1 riastrad /* 641 1.1 riastrad * The control register self-arms if the plane was previously 642 1.1 riastrad * disabled. Try to make the plane enable atomic by writing 643 1.1 riastrad * the control register just before the surface register. 644 1.1 riastrad */ 645 1.1 riastrad I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl); 646 1.1 riastrad I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 647 1.1 riastrad intel_plane_ggtt_offset(plane_state) + surf_addr); 648 1.1 riastrad 649 1.1 riastrad if (plane_state->scaler_id >= 0) 650 1.1 riastrad skl_program_scaler(plane, crtc_state, plane_state); 651 1.1 riastrad 652 1.1 riastrad spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 653 1.1 riastrad } 654 1.1 riastrad 655 1.1 riastrad static void 656 1.1 riastrad skl_update_plane(struct intel_plane *plane, 657 1.1 riastrad const struct intel_crtc_state *crtc_state, 658 1.1 riastrad const struct intel_plane_state *plane_state) 659 1.1 riastrad { 660 1.1 riastrad int color_plane = 0; 661 1.1 riastrad 662 1.1 riastrad if (plane_state->planar_linked_plane && !plane_state->planar_slave) 663 1.1 riastrad /* Program the UV plane on planar master */ 664 1.1 riastrad color_plane = 1; 665 1.1 riastrad 666 1.1 riastrad skl_program_plane(plane, crtc_state, plane_state, color_plane); 667 1.1 riastrad } 668 1.1 riastrad static void 669 1.1 riastrad skl_disable_plane(struct intel_plane *plane, 670 1.1 riastrad const struct intel_crtc_state *crtc_state) 671 1.1 riastrad { 672 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 673 1.1 riastrad enum plane_id plane_id = plane->id; 674 1.1 riastrad enum pipe pipe = plane->pipe; 675 1.1 riastrad unsigned long irqflags; 676 1.1 riastrad 677 1.1 riastrad spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 678 1.1 riastrad 679 1.1 riastrad if (icl_is_hdr_plane(dev_priv, plane_id)) 680 1.1 riastrad I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0); 681 1.1 riastrad 682 1.1 riastrad skl_write_plane_wm(plane, crtc_state); 683 1.1 riastrad 684 1.1 riastrad I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0); 685 1.1 riastrad I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0); 686 1.1 riastrad 687 1.1 riastrad spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 688 1.1 riastrad } 689 1.1 riastrad 690 1.1 riastrad static bool 691 1.1 riastrad skl_plane_get_hw_state(struct intel_plane *plane, 692 1.1 riastrad enum pipe *pipe) 693 1.1 riastrad { 694 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 695 1.1 riastrad enum intel_display_power_domain power_domain; 696 1.1 riastrad enum plane_id plane_id = plane->id; 697 1.1 riastrad intel_wakeref_t wakeref; 698 1.1 riastrad bool ret; 699 1.1 riastrad 700 1.1 riastrad power_domain = POWER_DOMAIN_PIPE(plane->pipe); 701 1.1 riastrad wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 702 1.1 riastrad if (!wakeref) 703 1.1 riastrad return false; 704 1.1 riastrad 705 1.1 riastrad ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE; 706 1.1 riastrad 707 1.1 riastrad *pipe = plane->pipe; 708 1.1 riastrad 709 1.1 riastrad intel_display_power_put(dev_priv, power_domain, wakeref); 710 1.1 riastrad 711 1.1 riastrad return ret; 712 1.1 riastrad } 713 1.1 riastrad 714 1.1 riastrad static void i9xx_plane_linear_gamma(u16 gamma[8]) 715 1.1 riastrad { 716 1.1 riastrad /* The points are not evenly spaced. */ 717 1.1 riastrad static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 }; 718 1.1 riastrad int i; 719 1.1 riastrad 720 1.1 riastrad for (i = 0; i < 8; i++) 721 1.1 riastrad gamma[i] = (in[i] << 8) / 32; 722 1.1 riastrad } 723 1.1 riastrad 724 1.1 riastrad static void 725 1.1 riastrad chv_update_csc(const struct intel_plane_state *plane_state) 726 1.1 riastrad { 727 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 728 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 729 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 730 1.1 riastrad enum plane_id plane_id = plane->id; 731 1.1 riastrad /* 732 1.1 riastrad * |r| | c0 c1 c2 | |cr| 733 1.1 riastrad * |g| = | c3 c4 c5 | x |y | 734 1.1 riastrad * |b| | c6 c7 c8 | |cb| 735 1.1 riastrad * 736 1.1 riastrad * Coefficients are s3.12. 737 1.1 riastrad * 738 1.1 riastrad * Cb and Cr apparently come in as signed already, and 739 1.1 riastrad * we always get full range data in on account of CLRC0/1. 740 1.1 riastrad */ 741 1.1 riastrad static const s16 csc_matrix[][9] = { 742 1.1 riastrad /* BT.601 full range YCbCr -> full range RGB */ 743 1.1 riastrad [DRM_COLOR_YCBCR_BT601] = { 744 1.1 riastrad 5743, 4096, 0, 745 1.1 riastrad -2925, 4096, -1410, 746 1.1 riastrad 0, 4096, 7258, 747 1.1 riastrad }, 748 1.1 riastrad /* BT.709 full range YCbCr -> full range RGB */ 749 1.1 riastrad [DRM_COLOR_YCBCR_BT709] = { 750 1.1 riastrad 6450, 4096, 0, 751 1.1 riastrad -1917, 4096, -767, 752 1.1 riastrad 0, 4096, 7601, 753 1.1 riastrad }, 754 1.1 riastrad }; 755 1.1 riastrad const s16 *csc = csc_matrix[plane_state->hw.color_encoding]; 756 1.1 riastrad 757 1.1 riastrad /* Seems RGB data bypasses the CSC always */ 758 1.1 riastrad if (!fb->format->is_yuv) 759 1.1 riastrad return; 760 1.1 riastrad 761 1.1 riastrad I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 762 1.1 riastrad I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 763 1.1 riastrad I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 764 1.1 riastrad 765 1.1 riastrad I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0])); 766 1.1 riastrad I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2])); 767 1.1 riastrad I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4])); 768 1.1 riastrad I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6])); 769 1.1 riastrad I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8])); 770 1.1 riastrad 771 1.1 riastrad I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0)); 772 1.1 riastrad I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 773 1.1 riastrad I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512)); 774 1.1 riastrad 775 1.1 riastrad I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 776 1.1 riastrad I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 777 1.1 riastrad I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 778 1.1 riastrad } 779 1.1 riastrad 780 1.1 riastrad #define SIN_0 0 781 1.1 riastrad #define COS_0 1 782 1.1 riastrad 783 1.1 riastrad static void 784 1.1 riastrad vlv_update_clrc(const struct intel_plane_state *plane_state) 785 1.1 riastrad { 786 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 787 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 788 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 789 1.1 riastrad enum pipe pipe = plane->pipe; 790 1.1 riastrad enum plane_id plane_id = plane->id; 791 1.1 riastrad int contrast, brightness, sh_scale, sh_sin, sh_cos; 792 1.1 riastrad 793 1.1 riastrad if (fb->format->is_yuv && 794 1.1 riastrad plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) { 795 1.1 riastrad /* 796 1.1 riastrad * Expand limited range to full range: 797 1.1 riastrad * Contrast is applied first and is used to expand Y range. 798 1.1 riastrad * Brightness is applied second and is used to remove the 799 1.1 riastrad * offset from Y. Saturation/hue is used to expand CbCr range. 800 1.1 riastrad */ 801 1.1 riastrad contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16); 802 1.1 riastrad brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16); 803 1.1 riastrad sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128); 804 1.1 riastrad sh_sin = SIN_0 * sh_scale; 805 1.1 riastrad sh_cos = COS_0 * sh_scale; 806 1.1 riastrad } else { 807 1.1 riastrad /* Pass-through everything. */ 808 1.1 riastrad contrast = 1 << 6; 809 1.1 riastrad brightness = 0; 810 1.1 riastrad sh_scale = 1 << 7; 811 1.1 riastrad sh_sin = SIN_0 * sh_scale; 812 1.1 riastrad sh_cos = COS_0 * sh_scale; 813 1.1 riastrad } 814 1.1 riastrad 815 1.1 riastrad /* FIXME these register are single buffered :( */ 816 1.1 riastrad I915_WRITE_FW(SPCLRC0(pipe, plane_id), 817 1.1 riastrad SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness)); 818 1.1 riastrad I915_WRITE_FW(SPCLRC1(pipe, plane_id), 819 1.1 riastrad SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos)); 820 1.1 riastrad } 821 1.1 riastrad 822 1.1 riastrad static void 823 1.1 riastrad vlv_plane_ratio(const struct intel_crtc_state *crtc_state, 824 1.1 riastrad const struct intel_plane_state *plane_state, 825 1.1 riastrad unsigned int *num, unsigned int *den) 826 1.1 riastrad { 827 1.1 riastrad u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 828 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 829 1.1 riastrad unsigned int cpp = fb->format->cpp[0]; 830 1.1 riastrad 831 1.1 riastrad /* 832 1.1 riastrad * VLV bspec only considers cases where all three planes are 833 1.1 riastrad * enabled, and cases where the primary and one sprite is enabled. 834 1.1 riastrad * Let's assume the case with just two sprites enabled also 835 1.1 riastrad * maps to the latter case. 836 1.1 riastrad */ 837 1.1 riastrad if (hweight8(active_planes) == 3) { 838 1.1 riastrad switch (cpp) { 839 1.1 riastrad case 8: 840 1.1 riastrad *num = 11; 841 1.1 riastrad *den = 8; 842 1.1 riastrad break; 843 1.1 riastrad case 4: 844 1.1 riastrad *num = 18; 845 1.1 riastrad *den = 16; 846 1.1 riastrad break; 847 1.1 riastrad default: 848 1.1 riastrad *num = 1; 849 1.1 riastrad *den = 1; 850 1.1 riastrad break; 851 1.1 riastrad } 852 1.1 riastrad } else if (hweight8(active_planes) == 2) { 853 1.1 riastrad switch (cpp) { 854 1.1 riastrad case 8: 855 1.1 riastrad *num = 10; 856 1.1 riastrad *den = 8; 857 1.1 riastrad break; 858 1.1 riastrad case 4: 859 1.1 riastrad *num = 17; 860 1.1 riastrad *den = 16; 861 1.1 riastrad break; 862 1.1 riastrad default: 863 1.1 riastrad *num = 1; 864 1.1 riastrad *den = 1; 865 1.1 riastrad break; 866 1.1 riastrad } 867 1.1 riastrad } else { 868 1.1 riastrad switch (cpp) { 869 1.1 riastrad case 8: 870 1.1 riastrad *num = 10; 871 1.1 riastrad *den = 8; 872 1.1 riastrad break; 873 1.1 riastrad default: 874 1.1 riastrad *num = 1; 875 1.1 riastrad *den = 1; 876 1.1 riastrad break; 877 1.1 riastrad } 878 1.1 riastrad } 879 1.1 riastrad } 880 1.1 riastrad 881 1.1 riastrad int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 882 1.1 riastrad const struct intel_plane_state *plane_state) 883 1.1 riastrad { 884 1.1 riastrad unsigned int pixel_rate; 885 1.1 riastrad unsigned int num, den; 886 1.1 riastrad 887 1.1 riastrad /* 888 1.1 riastrad * Note that crtc_state->pixel_rate accounts for both 889 1.1 riastrad * horizontal and vertical panel fitter downscaling factors. 890 1.1 riastrad * Pre-HSW bspec tells us to only consider the horizontal 891 1.1 riastrad * downscaling factor here. We ignore that and just consider 892 1.1 riastrad * both for simplicity. 893 1.1 riastrad */ 894 1.1 riastrad pixel_rate = crtc_state->pixel_rate; 895 1.1 riastrad 896 1.1 riastrad vlv_plane_ratio(crtc_state, plane_state, &num, &den); 897 1.1 riastrad 898 1.1 riastrad return DIV_ROUND_UP(pixel_rate * num, den); 899 1.1 riastrad } 900 1.1 riastrad 901 1.1 riastrad static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 902 1.1 riastrad { 903 1.1 riastrad u32 sprctl = 0; 904 1.1 riastrad 905 1.1 riastrad if (crtc_state->gamma_enable) 906 1.1 riastrad sprctl |= SP_GAMMA_ENABLE; 907 1.1 riastrad 908 1.1 riastrad return sprctl; 909 1.1 riastrad } 910 1.1 riastrad 911 1.1 riastrad static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, 912 1.1 riastrad const struct intel_plane_state *plane_state) 913 1.1 riastrad { 914 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 915 1.1 riastrad unsigned int rotation = plane_state->hw.rotation; 916 1.1 riastrad const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 917 1.1 riastrad u32 sprctl; 918 1.1 riastrad 919 1.1 riastrad sprctl = SP_ENABLE; 920 1.1 riastrad 921 1.1 riastrad switch (fb->format->format) { 922 1.1 riastrad case DRM_FORMAT_YUYV: 923 1.1 riastrad sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; 924 1.1 riastrad break; 925 1.1 riastrad case DRM_FORMAT_YVYU: 926 1.1 riastrad sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; 927 1.1 riastrad break; 928 1.1 riastrad case DRM_FORMAT_UYVY: 929 1.1 riastrad sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; 930 1.1 riastrad break; 931 1.1 riastrad case DRM_FORMAT_VYUY: 932 1.1 riastrad sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; 933 1.1 riastrad break; 934 1.1 riastrad case DRM_FORMAT_C8: 935 1.1 riastrad sprctl |= SP_FORMAT_8BPP; 936 1.1 riastrad break; 937 1.1 riastrad case DRM_FORMAT_RGB565: 938 1.1 riastrad sprctl |= SP_FORMAT_BGR565; 939 1.1 riastrad break; 940 1.1 riastrad case DRM_FORMAT_XRGB8888: 941 1.1 riastrad sprctl |= SP_FORMAT_BGRX8888; 942 1.1 riastrad break; 943 1.1 riastrad case DRM_FORMAT_ARGB8888: 944 1.1 riastrad sprctl |= SP_FORMAT_BGRA8888; 945 1.1 riastrad break; 946 1.1 riastrad case DRM_FORMAT_XBGR2101010: 947 1.1 riastrad sprctl |= SP_FORMAT_RGBX1010102; 948 1.1 riastrad break; 949 1.1 riastrad case DRM_FORMAT_ABGR2101010: 950 1.1 riastrad sprctl |= SP_FORMAT_RGBA1010102; 951 1.1 riastrad break; 952 1.1 riastrad case DRM_FORMAT_XRGB2101010: 953 1.1 riastrad sprctl |= SP_FORMAT_BGRX1010102; 954 1.1 riastrad break; 955 1.1 riastrad case DRM_FORMAT_ARGB2101010: 956 1.1 riastrad sprctl |= SP_FORMAT_BGRA1010102; 957 1.1 riastrad break; 958 1.1 riastrad case DRM_FORMAT_XBGR8888: 959 1.1 riastrad sprctl |= SP_FORMAT_RGBX8888; 960 1.1 riastrad break; 961 1.1 riastrad case DRM_FORMAT_ABGR8888: 962 1.1 riastrad sprctl |= SP_FORMAT_RGBA8888; 963 1.1 riastrad break; 964 1.1 riastrad default: 965 1.1 riastrad MISSING_CASE(fb->format->format); 966 1.1 riastrad return 0; 967 1.1 riastrad } 968 1.1 riastrad 969 1.1 riastrad if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 970 1.1 riastrad sprctl |= SP_YUV_FORMAT_BT709; 971 1.1 riastrad 972 1.1 riastrad if (fb->modifier == I915_FORMAT_MOD_X_TILED) 973 1.1 riastrad sprctl |= SP_TILED; 974 1.1 riastrad 975 1.1 riastrad if (rotation & DRM_MODE_ROTATE_180) 976 1.1 riastrad sprctl |= SP_ROTATE_180; 977 1.1 riastrad 978 1.1 riastrad if (rotation & DRM_MODE_REFLECT_X) 979 1.1 riastrad sprctl |= SP_MIRROR; 980 1.1 riastrad 981 1.1 riastrad if (key->flags & I915_SET_COLORKEY_SOURCE) 982 1.1 riastrad sprctl |= SP_SOURCE_KEY; 983 1.1 riastrad 984 1.1 riastrad return sprctl; 985 1.1 riastrad } 986 1.1 riastrad 987 1.1 riastrad static void vlv_update_gamma(const struct intel_plane_state *plane_state) 988 1.1 riastrad { 989 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 990 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 991 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 992 1.1 riastrad enum pipe pipe = plane->pipe; 993 1.1 riastrad enum plane_id plane_id = plane->id; 994 1.1 riastrad u16 gamma[8]; 995 1.1 riastrad int i; 996 1.1 riastrad 997 1.1 riastrad /* Seems RGB data bypasses the gamma always */ 998 1.1 riastrad if (!fb->format->is_yuv) 999 1.1 riastrad return; 1000 1.1 riastrad 1001 1.1 riastrad i9xx_plane_linear_gamma(gamma); 1002 1.1 riastrad 1003 1.1 riastrad /* FIXME these register are single buffered :( */ 1004 1.1 riastrad /* The two end points are implicit (0.0 and 1.0) */ 1005 1.1 riastrad for (i = 1; i < 8 - 1; i++) 1006 1.1 riastrad I915_WRITE_FW(SPGAMC(pipe, plane_id, i - 1), 1007 1.1 riastrad gamma[i] << 16 | 1008 1.1 riastrad gamma[i] << 8 | 1009 1.1 riastrad gamma[i]); 1010 1.1 riastrad } 1011 1.1 riastrad 1012 1.1 riastrad static void 1013 1.1 riastrad vlv_update_plane(struct intel_plane *plane, 1014 1.1 riastrad const struct intel_crtc_state *crtc_state, 1015 1.1 riastrad const struct intel_plane_state *plane_state) 1016 1.1 riastrad { 1017 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1018 1.1 riastrad enum pipe pipe = plane->pipe; 1019 1.1 riastrad enum plane_id plane_id = plane->id; 1020 1.1 riastrad u32 sprsurf_offset = plane_state->color_plane[0].offset; 1021 1.1 riastrad u32 linear_offset; 1022 1.1 riastrad const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1023 1.1 riastrad int crtc_x = plane_state->uapi.dst.x1; 1024 1.1 riastrad int crtc_y = plane_state->uapi.dst.y1; 1025 1.1 riastrad u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1026 1.1 riastrad u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1027 1.1 riastrad u32 x = plane_state->color_plane[0].x; 1028 1.1 riastrad u32 y = plane_state->color_plane[0].y; 1029 1.1 riastrad unsigned long irqflags; 1030 1.1 riastrad u32 sprctl; 1031 1.1 riastrad 1032 1.1 riastrad sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state); 1033 1.1 riastrad 1034 1.1 riastrad /* Sizes are 0 based */ 1035 1.1 riastrad crtc_w--; 1036 1.1 riastrad crtc_h--; 1037 1.1 riastrad 1038 1.1 riastrad linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1039 1.1 riastrad 1040 1.1 riastrad spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1041 1.1 riastrad 1042 1.1 riastrad I915_WRITE_FW(SPSTRIDE(pipe, plane_id), 1043 1.1 riastrad plane_state->color_plane[0].stride); 1044 1.1 riastrad I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x); 1045 1.1 riastrad I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w); 1046 1.1 riastrad I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0); 1047 1.1 riastrad 1048 1.1 riastrad if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) 1049 1.1 riastrad chv_update_csc(plane_state); 1050 1.1 riastrad 1051 1.1 riastrad if (key->flags) { 1052 1.1 riastrad I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value); 1053 1.1 riastrad I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask); 1054 1.1 riastrad I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value); 1055 1.1 riastrad } 1056 1.1 riastrad 1057 1.1 riastrad I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset); 1058 1.1 riastrad I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x); 1059 1.1 riastrad 1060 1.1 riastrad /* 1061 1.1 riastrad * The control register self-arms if the plane was previously 1062 1.1 riastrad * disabled. Try to make the plane enable atomic by writing 1063 1.1 riastrad * the control register just before the surface register. 1064 1.1 riastrad */ 1065 1.1 riastrad I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl); 1066 1.1 riastrad I915_WRITE_FW(SPSURF(pipe, plane_id), 1067 1.1 riastrad intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 1068 1.1 riastrad 1069 1.1 riastrad vlv_update_clrc(plane_state); 1070 1.1 riastrad vlv_update_gamma(plane_state); 1071 1.1 riastrad 1072 1.1 riastrad spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1073 1.1 riastrad } 1074 1.1 riastrad 1075 1.1 riastrad static void 1076 1.1 riastrad vlv_disable_plane(struct intel_plane *plane, 1077 1.1 riastrad const struct intel_crtc_state *crtc_state) 1078 1.1 riastrad { 1079 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1080 1.1 riastrad enum pipe pipe = plane->pipe; 1081 1.1 riastrad enum plane_id plane_id = plane->id; 1082 1.1 riastrad unsigned long irqflags; 1083 1.1 riastrad 1084 1.1 riastrad spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1085 1.1 riastrad 1086 1.1 riastrad I915_WRITE_FW(SPCNTR(pipe, plane_id), 0); 1087 1.1 riastrad I915_WRITE_FW(SPSURF(pipe, plane_id), 0); 1088 1.1 riastrad 1089 1.1 riastrad spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1090 1.1 riastrad } 1091 1.1 riastrad 1092 1.1 riastrad static bool 1093 1.1 riastrad vlv_plane_get_hw_state(struct intel_plane *plane, 1094 1.1 riastrad enum pipe *pipe) 1095 1.1 riastrad { 1096 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1097 1.1 riastrad enum intel_display_power_domain power_domain; 1098 1.1 riastrad enum plane_id plane_id = plane->id; 1099 1.1 riastrad intel_wakeref_t wakeref; 1100 1.1 riastrad bool ret; 1101 1.1 riastrad 1102 1.1 riastrad power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1103 1.1 riastrad wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1104 1.1 riastrad if (!wakeref) 1105 1.1 riastrad return false; 1106 1.1 riastrad 1107 1.1 riastrad ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE; 1108 1.1 riastrad 1109 1.1 riastrad *pipe = plane->pipe; 1110 1.1 riastrad 1111 1.1 riastrad intel_display_power_put(dev_priv, power_domain, wakeref); 1112 1.1 riastrad 1113 1.1 riastrad return ret; 1114 1.1 riastrad } 1115 1.1 riastrad 1116 1.1 riastrad static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state, 1117 1.1 riastrad const struct intel_plane_state *plane_state, 1118 1.1 riastrad unsigned int *num, unsigned int *den) 1119 1.1 riastrad { 1120 1.1 riastrad u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 1121 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1122 1.1 riastrad unsigned int cpp = fb->format->cpp[0]; 1123 1.1 riastrad 1124 1.1 riastrad if (hweight8(active_planes) == 2) { 1125 1.1 riastrad switch (cpp) { 1126 1.1 riastrad case 8: 1127 1.1 riastrad *num = 10; 1128 1.1 riastrad *den = 8; 1129 1.1 riastrad break; 1130 1.1 riastrad case 4: 1131 1.1 riastrad *num = 17; 1132 1.1 riastrad *den = 16; 1133 1.1 riastrad break; 1134 1.1 riastrad default: 1135 1.1 riastrad *num = 1; 1136 1.1 riastrad *den = 1; 1137 1.1 riastrad break; 1138 1.1 riastrad } 1139 1.1 riastrad } else { 1140 1.1 riastrad switch (cpp) { 1141 1.1 riastrad case 8: 1142 1.1 riastrad *num = 9; 1143 1.1 riastrad *den = 8; 1144 1.1 riastrad break; 1145 1.1 riastrad default: 1146 1.1 riastrad *num = 1; 1147 1.1 riastrad *den = 1; 1148 1.1 riastrad break; 1149 1.1 riastrad } 1150 1.1 riastrad } 1151 1.1 riastrad } 1152 1.1 riastrad 1153 1.1 riastrad static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state, 1154 1.1 riastrad const struct intel_plane_state *plane_state, 1155 1.1 riastrad unsigned int *num, unsigned int *den) 1156 1.1 riastrad { 1157 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1158 1.1 riastrad unsigned int cpp = fb->format->cpp[0]; 1159 1.1 riastrad 1160 1.1 riastrad switch (cpp) { 1161 1.1 riastrad case 8: 1162 1.1 riastrad *num = 12; 1163 1.1 riastrad *den = 8; 1164 1.1 riastrad break; 1165 1.1 riastrad case 4: 1166 1.1 riastrad *num = 19; 1167 1.1 riastrad *den = 16; 1168 1.1 riastrad break; 1169 1.1 riastrad case 2: 1170 1.1 riastrad *num = 33; 1171 1.1 riastrad *den = 32; 1172 1.1 riastrad break; 1173 1.1 riastrad default: 1174 1.1 riastrad *num = 1; 1175 1.1 riastrad *den = 1; 1176 1.1 riastrad break; 1177 1.1 riastrad } 1178 1.1 riastrad } 1179 1.1 riastrad 1180 1.1 riastrad int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 1181 1.1 riastrad const struct intel_plane_state *plane_state) 1182 1.1 riastrad { 1183 1.1 riastrad unsigned int pixel_rate; 1184 1.1 riastrad unsigned int num, den; 1185 1.1 riastrad 1186 1.1 riastrad /* 1187 1.1 riastrad * Note that crtc_state->pixel_rate accounts for both 1188 1.1 riastrad * horizontal and vertical panel fitter downscaling factors. 1189 1.1 riastrad * Pre-HSW bspec tells us to only consider the horizontal 1190 1.1 riastrad * downscaling factor here. We ignore that and just consider 1191 1.1 riastrad * both for simplicity. 1192 1.1 riastrad */ 1193 1.1 riastrad pixel_rate = crtc_state->pixel_rate; 1194 1.1 riastrad 1195 1.1 riastrad ivb_plane_ratio(crtc_state, plane_state, &num, &den); 1196 1.1 riastrad 1197 1.1 riastrad return DIV_ROUND_UP(pixel_rate * num, den); 1198 1.1 riastrad } 1199 1.1 riastrad 1200 1.1 riastrad static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state, 1201 1.1 riastrad const struct intel_plane_state *plane_state) 1202 1.1 riastrad { 1203 1.1 riastrad unsigned int src_w, dst_w, pixel_rate; 1204 1.1 riastrad unsigned int num, den; 1205 1.1 riastrad 1206 1.1 riastrad /* 1207 1.1 riastrad * Note that crtc_state->pixel_rate accounts for both 1208 1.1 riastrad * horizontal and vertical panel fitter downscaling factors. 1209 1.1 riastrad * Pre-HSW bspec tells us to only consider the horizontal 1210 1.1 riastrad * downscaling factor here. We ignore that and just consider 1211 1.1 riastrad * both for simplicity. 1212 1.1 riastrad */ 1213 1.1 riastrad pixel_rate = crtc_state->pixel_rate; 1214 1.1 riastrad 1215 1.1 riastrad src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1216 1.1 riastrad dst_w = drm_rect_width(&plane_state->uapi.dst); 1217 1.1 riastrad 1218 1.1 riastrad if (src_w != dst_w) 1219 1.1 riastrad ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den); 1220 1.1 riastrad else 1221 1.1 riastrad ivb_plane_ratio(crtc_state, plane_state, &num, &den); 1222 1.1 riastrad 1223 1.1 riastrad /* Horizontal downscaling limits the maximum pixel rate */ 1224 1.1 riastrad dst_w = min(src_w, dst_w); 1225 1.1 riastrad 1226 1.1 riastrad return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w), 1227 1.1 riastrad den * dst_w); 1228 1.1 riastrad } 1229 1.1 riastrad 1230 1.1 riastrad static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state, 1231 1.1 riastrad const struct intel_plane_state *plane_state, 1232 1.1 riastrad unsigned int *num, unsigned int *den) 1233 1.1 riastrad { 1234 1.1 riastrad u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); 1235 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1236 1.1 riastrad unsigned int cpp = fb->format->cpp[0]; 1237 1.1 riastrad 1238 1.1 riastrad if (hweight8(active_planes) == 2) { 1239 1.1 riastrad switch (cpp) { 1240 1.1 riastrad case 8: 1241 1.1 riastrad *num = 10; 1242 1.1 riastrad *den = 8; 1243 1.1 riastrad break; 1244 1.1 riastrad default: 1245 1.1 riastrad *num = 1; 1246 1.1 riastrad *den = 1; 1247 1.1 riastrad break; 1248 1.1 riastrad } 1249 1.1 riastrad } else { 1250 1.1 riastrad switch (cpp) { 1251 1.1 riastrad case 8: 1252 1.1 riastrad *num = 9; 1253 1.1 riastrad *den = 8; 1254 1.1 riastrad break; 1255 1.1 riastrad default: 1256 1.1 riastrad *num = 1; 1257 1.1 riastrad *den = 1; 1258 1.1 riastrad break; 1259 1.1 riastrad } 1260 1.1 riastrad } 1261 1.1 riastrad } 1262 1.1 riastrad 1263 1.1 riastrad int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state, 1264 1.1 riastrad const struct intel_plane_state *plane_state) 1265 1.1 riastrad { 1266 1.1 riastrad unsigned int pixel_rate = crtc_state->pixel_rate; 1267 1.1 riastrad unsigned int num, den; 1268 1.1 riastrad 1269 1.1 riastrad hsw_plane_ratio(crtc_state, plane_state, &num, &den); 1270 1.1 riastrad 1271 1.1 riastrad return DIV_ROUND_UP(pixel_rate * num, den); 1272 1.1 riastrad } 1273 1.1 riastrad 1274 1.1 riastrad static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 1275 1.1 riastrad { 1276 1.1 riastrad u32 sprctl = 0; 1277 1.1 riastrad 1278 1.1 riastrad if (crtc_state->gamma_enable) 1279 1.1 riastrad sprctl |= SPRITE_GAMMA_ENABLE; 1280 1.1 riastrad 1281 1.1 riastrad if (crtc_state->csc_enable) 1282 1.1 riastrad sprctl |= SPRITE_PIPE_CSC_ENABLE; 1283 1.1 riastrad 1284 1.1 riastrad return sprctl; 1285 1.1 riastrad } 1286 1.1 riastrad 1287 1.1 riastrad static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state) 1288 1.1 riastrad { 1289 1.1 riastrad struct drm_i915_private *dev_priv = 1290 1.1 riastrad to_i915(plane_state->uapi.plane->dev); 1291 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1292 1.1 riastrad 1293 1.1 riastrad return fb->format->cpp[0] == 8 && 1294 1.1 riastrad (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)); 1295 1.1 riastrad } 1296 1.1 riastrad 1297 1.1 riastrad static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, 1298 1.1 riastrad const struct intel_plane_state *plane_state) 1299 1.1 riastrad { 1300 1.1 riastrad struct drm_i915_private *dev_priv = 1301 1.1 riastrad to_i915(plane_state->uapi.plane->dev); 1302 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1303 1.1 riastrad unsigned int rotation = plane_state->hw.rotation; 1304 1.1 riastrad const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1305 1.1 riastrad u32 sprctl; 1306 1.1 riastrad 1307 1.1 riastrad sprctl = SPRITE_ENABLE; 1308 1.1 riastrad 1309 1.1 riastrad if (IS_IVYBRIDGE(dev_priv)) 1310 1.1 riastrad sprctl |= SPRITE_TRICKLE_FEED_DISABLE; 1311 1.1 riastrad 1312 1.1 riastrad switch (fb->format->format) { 1313 1.1 riastrad case DRM_FORMAT_XBGR8888: 1314 1.1 riastrad sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; 1315 1.1 riastrad break; 1316 1.1 riastrad case DRM_FORMAT_XRGB8888: 1317 1.1 riastrad sprctl |= SPRITE_FORMAT_RGBX888; 1318 1.1 riastrad break; 1319 1.1 riastrad case DRM_FORMAT_XBGR2101010: 1320 1.1 riastrad sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX; 1321 1.1 riastrad break; 1322 1.1 riastrad case DRM_FORMAT_XRGB2101010: 1323 1.1 riastrad sprctl |= SPRITE_FORMAT_RGBX101010; 1324 1.1 riastrad break; 1325 1.1 riastrad case DRM_FORMAT_XBGR16161616F: 1326 1.1 riastrad sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX; 1327 1.1 riastrad break; 1328 1.1 riastrad case DRM_FORMAT_XRGB16161616F: 1329 1.1 riastrad sprctl |= SPRITE_FORMAT_RGBX161616; 1330 1.1 riastrad break; 1331 1.1 riastrad case DRM_FORMAT_YUYV: 1332 1.1 riastrad sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; 1333 1.1 riastrad break; 1334 1.1 riastrad case DRM_FORMAT_YVYU: 1335 1.1 riastrad sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; 1336 1.1 riastrad break; 1337 1.1 riastrad case DRM_FORMAT_UYVY: 1338 1.1 riastrad sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; 1339 1.1 riastrad break; 1340 1.1 riastrad case DRM_FORMAT_VYUY: 1341 1.1 riastrad sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; 1342 1.1 riastrad break; 1343 1.1 riastrad default: 1344 1.1 riastrad MISSING_CASE(fb->format->format); 1345 1.1 riastrad return 0; 1346 1.1 riastrad } 1347 1.1 riastrad 1348 1.1 riastrad if (!ivb_need_sprite_gamma(plane_state)) 1349 1.1 riastrad sprctl |= SPRITE_INT_GAMMA_DISABLE; 1350 1.1 riastrad 1351 1.1 riastrad if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 1352 1.1 riastrad sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; 1353 1.1 riastrad 1354 1.1 riastrad if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 1355 1.1 riastrad sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE; 1356 1.1 riastrad 1357 1.1 riastrad if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1358 1.1 riastrad sprctl |= SPRITE_TILED; 1359 1.1 riastrad 1360 1.1 riastrad if (rotation & DRM_MODE_ROTATE_180) 1361 1.1 riastrad sprctl |= SPRITE_ROTATE_180; 1362 1.1 riastrad 1363 1.1 riastrad if (key->flags & I915_SET_COLORKEY_DESTINATION) 1364 1.1 riastrad sprctl |= SPRITE_DEST_KEY; 1365 1.1 riastrad else if (key->flags & I915_SET_COLORKEY_SOURCE) 1366 1.1 riastrad sprctl |= SPRITE_SOURCE_KEY; 1367 1.1 riastrad 1368 1.1 riastrad return sprctl; 1369 1.1 riastrad } 1370 1.1 riastrad 1371 1.1 riastrad static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state, 1372 1.1 riastrad u16 gamma[18]) 1373 1.1 riastrad { 1374 1.1 riastrad int scale, i; 1375 1.1 riastrad 1376 1.1 riastrad /* 1377 1.1 riastrad * WaFP16GammaEnabling:ivb,hsw 1378 1.1 riastrad * "Workaround : When using the 64-bit format, the sprite output 1379 1.1 riastrad * on each color channel has one quarter amplitude. It can be 1380 1.1 riastrad * brought up to full amplitude by using sprite internal gamma 1381 1.1 riastrad * correction, pipe gamma correction, or pipe color space 1382 1.1 riastrad * conversion to multiply the sprite output by four." 1383 1.1 riastrad */ 1384 1.1 riastrad scale = 4; 1385 1.1 riastrad 1386 1.1 riastrad for (i = 0; i < 16; i++) 1387 1.1 riastrad gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1); 1388 1.1 riastrad 1389 1.1 riastrad gamma[i] = min((scale * i << 10) / 16, 1 << 10); 1390 1.1 riastrad i++; 1391 1.1 riastrad 1392 1.1 riastrad gamma[i] = 3 << 10; 1393 1.1 riastrad i++; 1394 1.1 riastrad } 1395 1.1 riastrad 1396 1.1 riastrad static void ivb_update_gamma(const struct intel_plane_state *plane_state) 1397 1.1 riastrad { 1398 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1399 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1400 1.1 riastrad enum pipe pipe = plane->pipe; 1401 1.1 riastrad u16 gamma[18]; 1402 1.1 riastrad int i; 1403 1.1 riastrad 1404 1.1 riastrad if (!ivb_need_sprite_gamma(plane_state)) 1405 1.1 riastrad return; 1406 1.1 riastrad 1407 1.1 riastrad ivb_sprite_linear_gamma(plane_state, gamma); 1408 1.1 riastrad 1409 1.1 riastrad /* FIXME these register are single buffered :( */ 1410 1.1 riastrad for (i = 0; i < 16; i++) 1411 1.1 riastrad I915_WRITE_FW(SPRGAMC(pipe, i), 1412 1.1 riastrad gamma[i] << 20 | 1413 1.1 riastrad gamma[i] << 10 | 1414 1.1 riastrad gamma[i]); 1415 1.1 riastrad 1416 1.1 riastrad I915_WRITE_FW(SPRGAMC16(pipe, 0), gamma[i]); 1417 1.1 riastrad I915_WRITE_FW(SPRGAMC16(pipe, 1), gamma[i]); 1418 1.1 riastrad I915_WRITE_FW(SPRGAMC16(pipe, 2), gamma[i]); 1419 1.1 riastrad i++; 1420 1.1 riastrad 1421 1.1 riastrad I915_WRITE_FW(SPRGAMC17(pipe, 0), gamma[i]); 1422 1.1 riastrad I915_WRITE_FW(SPRGAMC17(pipe, 1), gamma[i]); 1423 1.1 riastrad I915_WRITE_FW(SPRGAMC17(pipe, 2), gamma[i]); 1424 1.1 riastrad i++; 1425 1.1 riastrad } 1426 1.1 riastrad 1427 1.1 riastrad static void 1428 1.1 riastrad ivb_update_plane(struct intel_plane *plane, 1429 1.1 riastrad const struct intel_crtc_state *crtc_state, 1430 1.1 riastrad const struct intel_plane_state *plane_state) 1431 1.1 riastrad { 1432 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1433 1.1 riastrad enum pipe pipe = plane->pipe; 1434 1.1 riastrad u32 sprsurf_offset = plane_state->color_plane[0].offset; 1435 1.1 riastrad u32 linear_offset; 1436 1.1 riastrad const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1437 1.1 riastrad int crtc_x = plane_state->uapi.dst.x1; 1438 1.1 riastrad int crtc_y = plane_state->uapi.dst.y1; 1439 1.1 riastrad u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1440 1.1 riastrad u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1441 1.1 riastrad u32 x = plane_state->color_plane[0].x; 1442 1.1 riastrad u32 y = plane_state->color_plane[0].y; 1443 1.1 riastrad u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1444 1.1 riastrad u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 1445 1.1 riastrad u32 sprctl, sprscale = 0; 1446 1.1 riastrad unsigned long irqflags; 1447 1.1 riastrad 1448 1.1 riastrad sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state); 1449 1.1 riastrad 1450 1.1 riastrad /* Sizes are 0 based */ 1451 1.1 riastrad src_w--; 1452 1.1 riastrad src_h--; 1453 1.1 riastrad crtc_w--; 1454 1.1 riastrad crtc_h--; 1455 1.1 riastrad 1456 1.1 riastrad if (crtc_w != src_w || crtc_h != src_h) 1457 1.1 riastrad sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; 1458 1.1 riastrad 1459 1.1 riastrad linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1460 1.1 riastrad 1461 1.1 riastrad spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1462 1.1 riastrad 1463 1.1 riastrad I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride); 1464 1.1 riastrad I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 1465 1.1 riastrad I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 1466 1.1 riastrad if (IS_IVYBRIDGE(dev_priv)) 1467 1.1 riastrad I915_WRITE_FW(SPRSCALE(pipe), sprscale); 1468 1.1 riastrad 1469 1.1 riastrad if (key->flags) { 1470 1.1 riastrad I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value); 1471 1.1 riastrad I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask); 1472 1.1 riastrad I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value); 1473 1.1 riastrad } 1474 1.1 riastrad 1475 1.1 riastrad /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 1476 1.1 riastrad * register */ 1477 1.1 riastrad if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 1478 1.1 riastrad I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x); 1479 1.1 riastrad } else { 1480 1.1 riastrad I915_WRITE_FW(SPRLINOFF(pipe), linear_offset); 1481 1.1 riastrad I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x); 1482 1.1 riastrad } 1483 1.1 riastrad 1484 1.1 riastrad /* 1485 1.1 riastrad * The control register self-arms if the plane was previously 1486 1.1 riastrad * disabled. Try to make the plane enable atomic by writing 1487 1.1 riastrad * the control register just before the surface register. 1488 1.1 riastrad */ 1489 1.1 riastrad I915_WRITE_FW(SPRCTL(pipe), sprctl); 1490 1.1 riastrad I915_WRITE_FW(SPRSURF(pipe), 1491 1.1 riastrad intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 1492 1.1 riastrad 1493 1.1 riastrad ivb_update_gamma(plane_state); 1494 1.1 riastrad 1495 1.1 riastrad spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1496 1.1 riastrad } 1497 1.1 riastrad 1498 1.1 riastrad static void 1499 1.1 riastrad ivb_disable_plane(struct intel_plane *plane, 1500 1.1 riastrad const struct intel_crtc_state *crtc_state) 1501 1.1 riastrad { 1502 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1503 1.1 riastrad enum pipe pipe = plane->pipe; 1504 1.1 riastrad unsigned long irqflags; 1505 1.1 riastrad 1506 1.1 riastrad spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1507 1.1 riastrad 1508 1.1 riastrad I915_WRITE_FW(SPRCTL(pipe), 0); 1509 1.1 riastrad /* Disable the scaler */ 1510 1.1 riastrad if (IS_IVYBRIDGE(dev_priv)) 1511 1.1 riastrad I915_WRITE_FW(SPRSCALE(pipe), 0); 1512 1.1 riastrad I915_WRITE_FW(SPRSURF(pipe), 0); 1513 1.1 riastrad 1514 1.1 riastrad spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1515 1.1 riastrad } 1516 1.1 riastrad 1517 1.1 riastrad static bool 1518 1.1 riastrad ivb_plane_get_hw_state(struct intel_plane *plane, 1519 1.1 riastrad enum pipe *pipe) 1520 1.1 riastrad { 1521 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1522 1.1 riastrad enum intel_display_power_domain power_domain; 1523 1.1 riastrad intel_wakeref_t wakeref; 1524 1.1 riastrad bool ret; 1525 1.1 riastrad 1526 1.1 riastrad power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1527 1.1 riastrad wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1528 1.1 riastrad if (!wakeref) 1529 1.1 riastrad return false; 1530 1.1 riastrad 1531 1.1 riastrad ret = I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE; 1532 1.1 riastrad 1533 1.1 riastrad *pipe = plane->pipe; 1534 1.1 riastrad 1535 1.1 riastrad intel_display_power_put(dev_priv, power_domain, wakeref); 1536 1.1 riastrad 1537 1.1 riastrad return ret; 1538 1.1 riastrad } 1539 1.1 riastrad 1540 1.1 riastrad static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state, 1541 1.1 riastrad const struct intel_plane_state *plane_state) 1542 1.1 riastrad { 1543 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1544 1.1 riastrad unsigned int hscale, pixel_rate; 1545 1.1 riastrad unsigned int limit, decimate; 1546 1.1 riastrad 1547 1.1 riastrad /* 1548 1.1 riastrad * Note that crtc_state->pixel_rate accounts for both 1549 1.1 riastrad * horizontal and vertical panel fitter downscaling factors. 1550 1.1 riastrad * Pre-HSW bspec tells us to only consider the horizontal 1551 1.1 riastrad * downscaling factor here. We ignore that and just consider 1552 1.1 riastrad * both for simplicity. 1553 1.1 riastrad */ 1554 1.1 riastrad pixel_rate = crtc_state->pixel_rate; 1555 1.1 riastrad 1556 1.1 riastrad /* Horizontal downscaling limits the maximum pixel rate */ 1557 1.1 riastrad hscale = drm_rect_calc_hscale(&plane_state->uapi.src, 1558 1.1 riastrad &plane_state->uapi.dst, 1559 1.1 riastrad 0, INT_MAX); 1560 1.1 riastrad if (hscale < 0x10000) 1561 1.1 riastrad return pixel_rate; 1562 1.1 riastrad 1563 1.1 riastrad /* Decimation steps at 2x,4x,8x,16x */ 1564 1.1 riastrad decimate = ilog2(hscale >> 16); 1565 1.1 riastrad hscale >>= decimate; 1566 1.1 riastrad 1567 1.1 riastrad /* Starting limit is 90% of cdclk */ 1568 1.1 riastrad limit = 9; 1569 1.1 riastrad 1570 1.1 riastrad /* -10% per decimation step */ 1571 1.1 riastrad limit -= decimate; 1572 1.1 riastrad 1573 1.1 riastrad /* -10% for RGB */ 1574 1.1 riastrad if (fb->format->cpp[0] >= 4) 1575 1.1 riastrad limit--; /* -10% for RGB */ 1576 1.1 riastrad 1577 1.1 riastrad /* 1578 1.1 riastrad * We should also do -10% if sprite scaling is enabled 1579 1.1 riastrad * on the other pipe, but we can't really check for that, 1580 1.1 riastrad * so we ignore it. 1581 1.1 riastrad */ 1582 1.1 riastrad 1583 1.1 riastrad return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale), 1584 1.1 riastrad limit << 16); 1585 1.1 riastrad } 1586 1.1 riastrad 1587 1.1 riastrad static unsigned int 1588 1.1 riastrad g4x_sprite_max_stride(struct intel_plane *plane, 1589 1.1 riastrad u32 pixel_format, u64 modifier, 1590 1.1 riastrad unsigned int rotation) 1591 1.1 riastrad { 1592 1.1 riastrad return 16384; 1593 1.1 riastrad } 1594 1.1 riastrad 1595 1.1 riastrad static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) 1596 1.1 riastrad { 1597 1.1 riastrad u32 dvscntr = 0; 1598 1.1 riastrad 1599 1.1 riastrad if (crtc_state->gamma_enable) 1600 1.1 riastrad dvscntr |= DVS_GAMMA_ENABLE; 1601 1.1 riastrad 1602 1.1 riastrad if (crtc_state->csc_enable) 1603 1.1 riastrad dvscntr |= DVS_PIPE_CSC_ENABLE; 1604 1.1 riastrad 1605 1.1 riastrad return dvscntr; 1606 1.1 riastrad } 1607 1.1 riastrad 1608 1.1 riastrad static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, 1609 1.1 riastrad const struct intel_plane_state *plane_state) 1610 1.1 riastrad { 1611 1.1 riastrad struct drm_i915_private *dev_priv = 1612 1.1 riastrad to_i915(plane_state->uapi.plane->dev); 1613 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1614 1.1 riastrad unsigned int rotation = plane_state->hw.rotation; 1615 1.1 riastrad const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1616 1.1 riastrad u32 dvscntr; 1617 1.1 riastrad 1618 1.1 riastrad dvscntr = DVS_ENABLE; 1619 1.1 riastrad 1620 1.1 riastrad if (IS_GEN(dev_priv, 6)) 1621 1.1 riastrad dvscntr |= DVS_TRICKLE_FEED_DISABLE; 1622 1.1 riastrad 1623 1.1 riastrad switch (fb->format->format) { 1624 1.1 riastrad case DRM_FORMAT_XBGR8888: 1625 1.1 riastrad dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; 1626 1.1 riastrad break; 1627 1.1 riastrad case DRM_FORMAT_XRGB8888: 1628 1.1 riastrad dvscntr |= DVS_FORMAT_RGBX888; 1629 1.1 riastrad break; 1630 1.1 riastrad case DRM_FORMAT_XBGR2101010: 1631 1.1 riastrad dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR; 1632 1.1 riastrad break; 1633 1.1 riastrad case DRM_FORMAT_XRGB2101010: 1634 1.1 riastrad dvscntr |= DVS_FORMAT_RGBX101010; 1635 1.1 riastrad break; 1636 1.1 riastrad case DRM_FORMAT_XBGR16161616F: 1637 1.1 riastrad dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR; 1638 1.1 riastrad break; 1639 1.1 riastrad case DRM_FORMAT_XRGB16161616F: 1640 1.1 riastrad dvscntr |= DVS_FORMAT_RGBX161616; 1641 1.1 riastrad break; 1642 1.1 riastrad case DRM_FORMAT_YUYV: 1643 1.1 riastrad dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; 1644 1.1 riastrad break; 1645 1.1 riastrad case DRM_FORMAT_YVYU: 1646 1.1 riastrad dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; 1647 1.1 riastrad break; 1648 1.1 riastrad case DRM_FORMAT_UYVY: 1649 1.1 riastrad dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; 1650 1.1 riastrad break; 1651 1.1 riastrad case DRM_FORMAT_VYUY: 1652 1.1 riastrad dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; 1653 1.1 riastrad break; 1654 1.1 riastrad default: 1655 1.1 riastrad MISSING_CASE(fb->format->format); 1656 1.1 riastrad return 0; 1657 1.1 riastrad } 1658 1.1 riastrad 1659 1.1 riastrad if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709) 1660 1.1 riastrad dvscntr |= DVS_YUV_FORMAT_BT709; 1661 1.1 riastrad 1662 1.1 riastrad if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE) 1663 1.1 riastrad dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE; 1664 1.1 riastrad 1665 1.1 riastrad if (fb->modifier == I915_FORMAT_MOD_X_TILED) 1666 1.1 riastrad dvscntr |= DVS_TILED; 1667 1.1 riastrad 1668 1.1 riastrad if (rotation & DRM_MODE_ROTATE_180) 1669 1.1 riastrad dvscntr |= DVS_ROTATE_180; 1670 1.1 riastrad 1671 1.1 riastrad if (key->flags & I915_SET_COLORKEY_DESTINATION) 1672 1.1 riastrad dvscntr |= DVS_DEST_KEY; 1673 1.1 riastrad else if (key->flags & I915_SET_COLORKEY_SOURCE) 1674 1.1 riastrad dvscntr |= DVS_SOURCE_KEY; 1675 1.1 riastrad 1676 1.1 riastrad return dvscntr; 1677 1.1 riastrad } 1678 1.1 riastrad 1679 1.1 riastrad static void g4x_update_gamma(const struct intel_plane_state *plane_state) 1680 1.1 riastrad { 1681 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1682 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1683 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1684 1.1 riastrad enum pipe pipe = plane->pipe; 1685 1.1 riastrad u16 gamma[8]; 1686 1.1 riastrad int i; 1687 1.1 riastrad 1688 1.1 riastrad /* Seems RGB data bypasses the gamma always */ 1689 1.1 riastrad if (!fb->format->is_yuv) 1690 1.1 riastrad return; 1691 1.1 riastrad 1692 1.1 riastrad i9xx_plane_linear_gamma(gamma); 1693 1.1 riastrad 1694 1.1 riastrad /* FIXME these register are single buffered :( */ 1695 1.1 riastrad /* The two end points are implicit (0.0 and 1.0) */ 1696 1.1 riastrad for (i = 1; i < 8 - 1; i++) 1697 1.1 riastrad I915_WRITE_FW(DVSGAMC_G4X(pipe, i - 1), 1698 1.1 riastrad gamma[i] << 16 | 1699 1.1 riastrad gamma[i] << 8 | 1700 1.1 riastrad gamma[i]); 1701 1.1 riastrad } 1702 1.1 riastrad 1703 1.1 riastrad static void ilk_sprite_linear_gamma(u16 gamma[17]) 1704 1.1 riastrad { 1705 1.1 riastrad int i; 1706 1.1 riastrad 1707 1.1 riastrad for (i = 0; i < 17; i++) 1708 1.1 riastrad gamma[i] = (i << 10) / 16; 1709 1.1 riastrad } 1710 1.1 riastrad 1711 1.1 riastrad static void ilk_update_gamma(const struct intel_plane_state *plane_state) 1712 1.1 riastrad { 1713 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1714 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1715 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1716 1.1 riastrad enum pipe pipe = plane->pipe; 1717 1.1 riastrad u16 gamma[17]; 1718 1.1 riastrad int i; 1719 1.1 riastrad 1720 1.1 riastrad /* Seems RGB data bypasses the gamma always */ 1721 1.1 riastrad if (!fb->format->is_yuv) 1722 1.1 riastrad return; 1723 1.1 riastrad 1724 1.1 riastrad ilk_sprite_linear_gamma(gamma); 1725 1.1 riastrad 1726 1.1 riastrad /* FIXME these register are single buffered :( */ 1727 1.1 riastrad for (i = 0; i < 16; i++) 1728 1.1 riastrad I915_WRITE_FW(DVSGAMC_ILK(pipe, i), 1729 1.1 riastrad gamma[i] << 20 | 1730 1.1 riastrad gamma[i] << 10 | 1731 1.1 riastrad gamma[i]); 1732 1.1 riastrad 1733 1.1 riastrad I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 0), gamma[i]); 1734 1.1 riastrad I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 1), gamma[i]); 1735 1.1 riastrad I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 2), gamma[i]); 1736 1.1 riastrad i++; 1737 1.1 riastrad } 1738 1.1 riastrad 1739 1.1 riastrad static void 1740 1.1 riastrad g4x_update_plane(struct intel_plane *plane, 1741 1.1 riastrad const struct intel_crtc_state *crtc_state, 1742 1.1 riastrad const struct intel_plane_state *plane_state) 1743 1.1 riastrad { 1744 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1745 1.1 riastrad enum pipe pipe = plane->pipe; 1746 1.1 riastrad u32 dvssurf_offset = plane_state->color_plane[0].offset; 1747 1.1 riastrad u32 linear_offset; 1748 1.1 riastrad const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 1749 1.1 riastrad int crtc_x = plane_state->uapi.dst.x1; 1750 1.1 riastrad int crtc_y = plane_state->uapi.dst.y1; 1751 1.1 riastrad u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); 1752 1.1 riastrad u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); 1753 1.1 riastrad u32 x = plane_state->color_plane[0].x; 1754 1.1 riastrad u32 y = plane_state->color_plane[0].y; 1755 1.1 riastrad u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 1756 1.1 riastrad u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; 1757 1.1 riastrad u32 dvscntr, dvsscale = 0; 1758 1.1 riastrad unsigned long irqflags; 1759 1.1 riastrad 1760 1.1 riastrad dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state); 1761 1.1 riastrad 1762 1.1 riastrad /* Sizes are 0 based */ 1763 1.1 riastrad src_w--; 1764 1.1 riastrad src_h--; 1765 1.1 riastrad crtc_w--; 1766 1.1 riastrad crtc_h--; 1767 1.1 riastrad 1768 1.1 riastrad if (crtc_w != src_w || crtc_h != src_h) 1769 1.1 riastrad dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; 1770 1.1 riastrad 1771 1.1 riastrad linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0); 1772 1.1 riastrad 1773 1.1 riastrad spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1774 1.1 riastrad 1775 1.1 riastrad I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride); 1776 1.1 riastrad I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 1777 1.1 riastrad I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 1778 1.1 riastrad I915_WRITE_FW(DVSSCALE(pipe), dvsscale); 1779 1.1 riastrad 1780 1.1 riastrad if (key->flags) { 1781 1.1 riastrad I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value); 1782 1.1 riastrad I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask); 1783 1.1 riastrad I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value); 1784 1.1 riastrad } 1785 1.1 riastrad 1786 1.1 riastrad I915_WRITE_FW(DVSLINOFF(pipe), linear_offset); 1787 1.1 riastrad I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x); 1788 1.1 riastrad 1789 1.1 riastrad /* 1790 1.1 riastrad * The control register self-arms if the plane was previously 1791 1.1 riastrad * disabled. Try to make the plane enable atomic by writing 1792 1.1 riastrad * the control register just before the surface register. 1793 1.1 riastrad */ 1794 1.1 riastrad I915_WRITE_FW(DVSCNTR(pipe), dvscntr); 1795 1.1 riastrad I915_WRITE_FW(DVSSURF(pipe), 1796 1.1 riastrad intel_plane_ggtt_offset(plane_state) + dvssurf_offset); 1797 1.1 riastrad 1798 1.1 riastrad if (IS_G4X(dev_priv)) 1799 1.1 riastrad g4x_update_gamma(plane_state); 1800 1.1 riastrad else 1801 1.1 riastrad ilk_update_gamma(plane_state); 1802 1.1 riastrad 1803 1.1 riastrad spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1804 1.1 riastrad } 1805 1.1 riastrad 1806 1.1 riastrad static void 1807 1.1 riastrad g4x_disable_plane(struct intel_plane *plane, 1808 1.1 riastrad const struct intel_crtc_state *crtc_state) 1809 1.1 riastrad { 1810 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1811 1.1 riastrad enum pipe pipe = plane->pipe; 1812 1.1 riastrad unsigned long irqflags; 1813 1.1 riastrad 1814 1.1 riastrad spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1815 1.1 riastrad 1816 1.1 riastrad I915_WRITE_FW(DVSCNTR(pipe), 0); 1817 1.1 riastrad /* Disable the scaler */ 1818 1.1 riastrad I915_WRITE_FW(DVSSCALE(pipe), 0); 1819 1.1 riastrad I915_WRITE_FW(DVSSURF(pipe), 0); 1820 1.1 riastrad 1821 1.1 riastrad spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 1822 1.1 riastrad } 1823 1.1 riastrad 1824 1.1 riastrad static bool 1825 1.1 riastrad g4x_plane_get_hw_state(struct intel_plane *plane, 1826 1.1 riastrad enum pipe *pipe) 1827 1.1 riastrad { 1828 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1829 1.1 riastrad enum intel_display_power_domain power_domain; 1830 1.1 riastrad intel_wakeref_t wakeref; 1831 1.1 riastrad bool ret; 1832 1.1 riastrad 1833 1.1 riastrad power_domain = POWER_DOMAIN_PIPE(plane->pipe); 1834 1.1 riastrad wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); 1835 1.1 riastrad if (!wakeref) 1836 1.1 riastrad return false; 1837 1.1 riastrad 1838 1.1 riastrad ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE; 1839 1.1 riastrad 1840 1.1 riastrad *pipe = plane->pipe; 1841 1.1 riastrad 1842 1.1 riastrad intel_display_power_put(dev_priv, power_domain, wakeref); 1843 1.1 riastrad 1844 1.1 riastrad return ret; 1845 1.1 riastrad } 1846 1.1 riastrad 1847 1.1 riastrad static bool intel_fb_scalable(const struct drm_framebuffer *fb) 1848 1.1 riastrad { 1849 1.1 riastrad if (!fb) 1850 1.1 riastrad return false; 1851 1.1 riastrad 1852 1.1 riastrad switch (fb->format->format) { 1853 1.1 riastrad case DRM_FORMAT_C8: 1854 1.1 riastrad return false; 1855 1.1 riastrad case DRM_FORMAT_XRGB16161616F: 1856 1.1 riastrad case DRM_FORMAT_ARGB16161616F: 1857 1.1 riastrad case DRM_FORMAT_XBGR16161616F: 1858 1.1 riastrad case DRM_FORMAT_ABGR16161616F: 1859 1.1 riastrad return INTEL_GEN(to_i915(fb->dev)) >= 11; 1860 1.1 riastrad default: 1861 1.1 riastrad return true; 1862 1.1 riastrad } 1863 1.1 riastrad } 1864 1.1 riastrad 1865 1.1 riastrad static int 1866 1.1 riastrad g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state, 1867 1.1 riastrad struct intel_plane_state *plane_state) 1868 1.1 riastrad { 1869 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 1870 1.1 riastrad const struct drm_rect *src = &plane_state->uapi.src; 1871 1.1 riastrad const struct drm_rect *dst = &plane_state->uapi.dst; 1872 1.1 riastrad int src_x, src_w, src_h, crtc_w, crtc_h; 1873 1.1 riastrad const struct drm_display_mode *adjusted_mode = 1874 1.1 riastrad &crtc_state->hw.adjusted_mode; 1875 1.1 riastrad unsigned int stride = plane_state->color_plane[0].stride; 1876 1.1 riastrad unsigned int cpp = fb->format->cpp[0]; 1877 1.1 riastrad unsigned int width_bytes; 1878 1.1 riastrad int min_width, min_height; 1879 1.1 riastrad 1880 1.1 riastrad crtc_w = drm_rect_width(dst); 1881 1.1 riastrad crtc_h = drm_rect_height(dst); 1882 1.1 riastrad 1883 1.1 riastrad src_x = src->x1 >> 16; 1884 1.1 riastrad src_w = drm_rect_width(src) >> 16; 1885 1.1 riastrad src_h = drm_rect_height(src) >> 16; 1886 1.1 riastrad 1887 1.1 riastrad if (src_w == crtc_w && src_h == crtc_h) 1888 1.1 riastrad return 0; 1889 1.1 riastrad 1890 1.1 riastrad min_width = 3; 1891 1.1 riastrad 1892 1.1 riastrad if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 1893 1.1 riastrad if (src_h & 1) { 1894 1.1 riastrad DRM_DEBUG_KMS("Source height must be even with interlaced modes\n"); 1895 1.1 riastrad return -EINVAL; 1896 1.1 riastrad } 1897 1.1 riastrad min_height = 6; 1898 1.1 riastrad } else { 1899 1.1 riastrad min_height = 3; 1900 1.1 riastrad } 1901 1.1 riastrad 1902 1.1 riastrad width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 1903 1.1 riastrad 1904 1.1 riastrad if (src_w < min_width || src_h < min_height || 1905 1.1 riastrad src_w > 2048 || src_h > 2048) { 1906 1.1 riastrad DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n", 1907 1.1 riastrad src_w, src_h, min_width, min_height, 2048, 2048); 1908 1.1 riastrad return -EINVAL; 1909 1.1 riastrad } 1910 1.1 riastrad 1911 1.1 riastrad if (width_bytes > 4096) { 1912 1.1 riastrad DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n", 1913 1.1 riastrad width_bytes, 4096); 1914 1.1 riastrad return -EINVAL; 1915 1.1 riastrad } 1916 1.1 riastrad 1917 1.1 riastrad if (stride > 4096) { 1918 1.1 riastrad DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n", 1919 1.1 riastrad stride, 4096); 1920 1.1 riastrad return -EINVAL; 1921 1.1 riastrad } 1922 1.1 riastrad 1923 1.1 riastrad return 0; 1924 1.1 riastrad } 1925 1.1 riastrad 1926 1.1 riastrad static int 1927 1.1 riastrad g4x_sprite_check(struct intel_crtc_state *crtc_state, 1928 1.1 riastrad struct intel_plane_state *plane_state) 1929 1.1 riastrad { 1930 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1931 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1932 1.1 riastrad int min_scale = DRM_PLANE_HELPER_NO_SCALING; 1933 1.1 riastrad int max_scale = DRM_PLANE_HELPER_NO_SCALING; 1934 1.1 riastrad int ret; 1935 1.1 riastrad 1936 1.1 riastrad if (intel_fb_scalable(plane_state->hw.fb)) { 1937 1.1 riastrad if (INTEL_GEN(dev_priv) < 7) { 1938 1.1 riastrad min_scale = 1; 1939 1.1 riastrad max_scale = 16 << 16; 1940 1.1 riastrad } else if (IS_IVYBRIDGE(dev_priv)) { 1941 1.1 riastrad min_scale = 1; 1942 1.1 riastrad max_scale = 2 << 16; 1943 1.1 riastrad } 1944 1.1 riastrad } 1945 1.1 riastrad 1946 1.1 riastrad ret = drm_atomic_helper_check_plane_state(&plane_state->uapi, 1947 1.1 riastrad &crtc_state->uapi, 1948 1.1 riastrad min_scale, max_scale, 1949 1.1 riastrad true, true); 1950 1.1 riastrad if (ret) 1951 1.1 riastrad return ret; 1952 1.1 riastrad 1953 1.1 riastrad ret = i9xx_check_plane_surface(plane_state); 1954 1.1 riastrad if (ret) 1955 1.1 riastrad return ret; 1956 1.1 riastrad 1957 1.1 riastrad if (!plane_state->uapi.visible) 1958 1.1 riastrad return 0; 1959 1.1 riastrad 1960 1.1 riastrad ret = intel_plane_check_src_coordinates(plane_state); 1961 1.1 riastrad if (ret) 1962 1.1 riastrad return ret; 1963 1.1 riastrad 1964 1.1 riastrad ret = g4x_sprite_check_scaling(crtc_state, plane_state); 1965 1.1 riastrad if (ret) 1966 1.1 riastrad return ret; 1967 1.1 riastrad 1968 1.1 riastrad if (INTEL_GEN(dev_priv) >= 7) 1969 1.1 riastrad plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state); 1970 1.1 riastrad else 1971 1.1 riastrad plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state); 1972 1.1 riastrad 1973 1.1 riastrad return 0; 1974 1.1 riastrad } 1975 1.1 riastrad 1976 1.1 riastrad int chv_plane_check_rotation(const struct intel_plane_state *plane_state) 1977 1.1 riastrad { 1978 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1979 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1980 1.1 riastrad unsigned int rotation = plane_state->hw.rotation; 1981 1.1 riastrad 1982 1.1 riastrad /* CHV ignores the mirror bit when the rotate bit is set :( */ 1983 1.1 riastrad if (IS_CHERRYVIEW(dev_priv) && 1984 1.1 riastrad rotation & DRM_MODE_ROTATE_180 && 1985 1.1 riastrad rotation & DRM_MODE_REFLECT_X) { 1986 1.1 riastrad DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n"); 1987 1.1 riastrad return -EINVAL; 1988 1.1 riastrad } 1989 1.1 riastrad 1990 1.1 riastrad return 0; 1991 1.1 riastrad } 1992 1.1 riastrad 1993 1.1 riastrad static int 1994 1.1 riastrad vlv_sprite_check(struct intel_crtc_state *crtc_state, 1995 1.1 riastrad struct intel_plane_state *plane_state) 1996 1.1 riastrad { 1997 1.1 riastrad int ret; 1998 1.1 riastrad 1999 1.1 riastrad ret = chv_plane_check_rotation(plane_state); 2000 1.1 riastrad if (ret) 2001 1.1 riastrad return ret; 2002 1.1 riastrad 2003 1.1 riastrad ret = drm_atomic_helper_check_plane_state(&plane_state->uapi, 2004 1.1 riastrad &crtc_state->uapi, 2005 1.1 riastrad DRM_PLANE_HELPER_NO_SCALING, 2006 1.1 riastrad DRM_PLANE_HELPER_NO_SCALING, 2007 1.1 riastrad true, true); 2008 1.1 riastrad if (ret) 2009 1.1 riastrad return ret; 2010 1.1 riastrad 2011 1.1 riastrad ret = i9xx_check_plane_surface(plane_state); 2012 1.1 riastrad if (ret) 2013 1.1 riastrad return ret; 2014 1.1 riastrad 2015 1.1 riastrad if (!plane_state->uapi.visible) 2016 1.1 riastrad return 0; 2017 1.1 riastrad 2018 1.1 riastrad ret = intel_plane_check_src_coordinates(plane_state); 2019 1.1 riastrad if (ret) 2020 1.1 riastrad return ret; 2021 1.1 riastrad 2022 1.1 riastrad plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state); 2023 1.1 riastrad 2024 1.1 riastrad return 0; 2025 1.1 riastrad } 2026 1.1 riastrad 2027 1.1 riastrad static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, 2028 1.1 riastrad const struct intel_plane_state *plane_state) 2029 1.1 riastrad { 2030 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 2031 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 2032 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 2033 1.1 riastrad unsigned int rotation = plane_state->hw.rotation; 2034 1.1 riastrad struct drm_format_name_buf format_name; 2035 1.1 riastrad 2036 1.1 riastrad if (!fb) 2037 1.1 riastrad return 0; 2038 1.1 riastrad 2039 1.1 riastrad if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) && 2040 1.1 riastrad is_ccs_modifier(fb->modifier)) { 2041 1.1 riastrad DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n", 2042 1.1 riastrad rotation); 2043 1.1 riastrad return -EINVAL; 2044 1.1 riastrad } 2045 1.1 riastrad 2046 1.1 riastrad if (rotation & DRM_MODE_REFLECT_X && 2047 1.1 riastrad fb->modifier == DRM_FORMAT_MOD_LINEAR) { 2048 1.1 riastrad DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n"); 2049 1.1 riastrad return -EINVAL; 2050 1.1 riastrad } 2051 1.1 riastrad 2052 1.1 riastrad if (drm_rotation_90_or_270(rotation)) { 2053 1.1 riastrad if (fb->modifier != I915_FORMAT_MOD_Y_TILED && 2054 1.1 riastrad fb->modifier != I915_FORMAT_MOD_Yf_TILED) { 2055 1.1 riastrad DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n"); 2056 1.1 riastrad return -EINVAL; 2057 1.1 riastrad } 2058 1.1 riastrad 2059 1.1 riastrad /* 2060 1.1 riastrad * 90/270 is not allowed with RGB64 16:16:16:16 and 2061 1.1 riastrad * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards. 2062 1.1 riastrad */ 2063 1.1 riastrad switch (fb->format->format) { 2064 1.1 riastrad case DRM_FORMAT_RGB565: 2065 1.1 riastrad if (INTEL_GEN(dev_priv) >= 11) 2066 1.1 riastrad break; 2067 1.1 riastrad /* fall through */ 2068 1.1 riastrad case DRM_FORMAT_C8: 2069 1.1 riastrad case DRM_FORMAT_XRGB16161616F: 2070 1.1 riastrad case DRM_FORMAT_XBGR16161616F: 2071 1.1 riastrad case DRM_FORMAT_ARGB16161616F: 2072 1.1 riastrad case DRM_FORMAT_ABGR16161616F: 2073 1.1 riastrad case DRM_FORMAT_Y210: 2074 1.1 riastrad case DRM_FORMAT_Y212: 2075 1.1 riastrad case DRM_FORMAT_Y216: 2076 1.1 riastrad case DRM_FORMAT_XVYU12_16161616: 2077 1.1 riastrad case DRM_FORMAT_XVYU16161616: 2078 1.1 riastrad DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", 2079 1.1 riastrad drm_get_format_name(fb->format->format, 2080 1.1 riastrad &format_name)); 2081 1.1 riastrad return -EINVAL; 2082 1.1 riastrad default: 2083 1.1 riastrad break; 2084 1.1 riastrad } 2085 1.1 riastrad } 2086 1.1 riastrad 2087 1.1 riastrad /* Y-tiling is not supported in IF-ID Interlace mode */ 2088 1.1 riastrad if (crtc_state->hw.enable && 2089 1.1 riastrad crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE && 2090 1.1 riastrad (fb->modifier == I915_FORMAT_MOD_Y_TILED || 2091 1.1 riastrad fb->modifier == I915_FORMAT_MOD_Yf_TILED || 2092 1.1 riastrad fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || 2093 1.1 riastrad fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS || 2094 1.1 riastrad fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || 2095 1.1 riastrad fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)) { 2096 1.1 riastrad DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n"); 2097 1.1 riastrad return -EINVAL; 2098 1.1 riastrad } 2099 1.1 riastrad 2100 1.1 riastrad return 0; 2101 1.1 riastrad } 2102 1.1 riastrad 2103 1.1 riastrad static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state, 2104 1.1 riastrad const struct intel_plane_state *plane_state) 2105 1.1 riastrad { 2106 1.1 riastrad struct drm_i915_private *dev_priv = 2107 1.1 riastrad to_i915(plane_state->uapi.plane->dev); 2108 1.1 riastrad int crtc_x = plane_state->uapi.dst.x1; 2109 1.1 riastrad int crtc_w = drm_rect_width(&plane_state->uapi.dst); 2110 1.1 riastrad int pipe_src_w = crtc_state->pipe_src_w; 2111 1.1 riastrad 2112 1.1 riastrad /* 2113 1.1 riastrad * Display WA #1175: cnl,glk 2114 1.1 riastrad * Planes other than the cursor may cause FIFO underflow and display 2115 1.1 riastrad * corruption if starting less than 4 pixels from the right edge of 2116 1.1 riastrad * the screen. 2117 1.1 riastrad * Besides the above WA fix the similar problem, where planes other 2118 1.1 riastrad * than the cursor ending less than 4 pixels from the left edge of the 2119 1.1 riastrad * screen may cause FIFO underflow and display corruption. 2120 1.1 riastrad */ 2121 1.1 riastrad if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) && 2122 1.1 riastrad (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) { 2123 1.1 riastrad DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n", 2124 1.1 riastrad crtc_x + crtc_w < 4 ? "end" : "start", 2125 1.1 riastrad crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x, 2126 1.1 riastrad 4, pipe_src_w - 4); 2127 1.1 riastrad return -ERANGE; 2128 1.1 riastrad } 2129 1.1 riastrad 2130 1.1 riastrad return 0; 2131 1.1 riastrad } 2132 1.1 riastrad 2133 1.1 riastrad static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state) 2134 1.1 riastrad { 2135 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 2136 1.1 riastrad unsigned int rotation = plane_state->hw.rotation; 2137 1.1 riastrad int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; 2138 1.1 riastrad 2139 1.1 riastrad /* Display WA #1106 */ 2140 1.1 riastrad if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 2141 1.1 riastrad src_w & 3 && 2142 1.1 riastrad (rotation == DRM_MODE_ROTATE_270 || 2143 1.1 riastrad rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { 2144 1.1 riastrad DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n"); 2145 1.1 riastrad return -EINVAL; 2146 1.1 riastrad } 2147 1.1 riastrad 2148 1.1 riastrad return 0; 2149 1.1 riastrad } 2150 1.1 riastrad 2151 1.1 riastrad static int skl_plane_max_scale(struct drm_i915_private *dev_priv, 2152 1.1 riastrad const struct drm_framebuffer *fb) 2153 1.1 riastrad { 2154 1.1 riastrad /* 2155 1.1 riastrad * We don't yet know the final source width nor 2156 1.1 riastrad * whether we can use the HQ scaler mode. Assume 2157 1.1 riastrad * the best case. 2158 1.1 riastrad * FIXME need to properly check this later. 2159 1.1 riastrad */ 2160 1.1 riastrad if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) || 2161 1.1 riastrad !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) 2162 1.1 riastrad return 0x30000 - 1; 2163 1.1 riastrad else 2164 1.1 riastrad return 0x20000 - 1; 2165 1.1 riastrad } 2166 1.1 riastrad 2167 1.1 riastrad static int skl_plane_check(struct intel_crtc_state *crtc_state, 2168 1.1 riastrad struct intel_plane_state *plane_state) 2169 1.1 riastrad { 2170 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 2171 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 2172 1.1 riastrad const struct drm_framebuffer *fb = plane_state->hw.fb; 2173 1.1 riastrad int min_scale = DRM_PLANE_HELPER_NO_SCALING; 2174 1.1 riastrad int max_scale = DRM_PLANE_HELPER_NO_SCALING; 2175 1.1 riastrad int ret; 2176 1.1 riastrad 2177 1.1 riastrad ret = skl_plane_check_fb(crtc_state, plane_state); 2178 1.1 riastrad if (ret) 2179 1.1 riastrad return ret; 2180 1.1 riastrad 2181 1.1 riastrad /* use scaler when colorkey is not required */ 2182 1.1 riastrad if (!plane_state->ckey.flags && intel_fb_scalable(fb)) { 2183 1.1 riastrad min_scale = 1; 2184 1.1 riastrad max_scale = skl_plane_max_scale(dev_priv, fb); 2185 1.1 riastrad } 2186 1.1 riastrad 2187 1.1 riastrad ret = drm_atomic_helper_check_plane_state(&plane_state->uapi, 2188 1.1 riastrad &crtc_state->uapi, 2189 1.1 riastrad min_scale, max_scale, 2190 1.1 riastrad true, true); 2191 1.1 riastrad if (ret) 2192 1.1 riastrad return ret; 2193 1.1 riastrad 2194 1.1 riastrad ret = skl_check_plane_surface(plane_state); 2195 1.1 riastrad if (ret) 2196 1.1 riastrad return ret; 2197 1.1 riastrad 2198 1.1 riastrad if (!plane_state->uapi.visible) 2199 1.1 riastrad return 0; 2200 1.1 riastrad 2201 1.1 riastrad ret = skl_plane_check_dst_coordinates(crtc_state, plane_state); 2202 1.1 riastrad if (ret) 2203 1.1 riastrad return ret; 2204 1.1 riastrad 2205 1.1 riastrad ret = intel_plane_check_src_coordinates(plane_state); 2206 1.1 riastrad if (ret) 2207 1.1 riastrad return ret; 2208 1.1 riastrad 2209 1.1 riastrad ret = skl_plane_check_nv12_rotation(plane_state); 2210 1.1 riastrad if (ret) 2211 1.1 riastrad return ret; 2212 1.1 riastrad 2213 1.1 riastrad /* HW only has 8 bits pixel precision, disable plane if invisible */ 2214 1.1 riastrad if (!(plane_state->hw.alpha >> 8)) 2215 1.1 riastrad plane_state->uapi.visible = false; 2216 1.1 riastrad 2217 1.1 riastrad plane_state->ctl = skl_plane_ctl(crtc_state, plane_state); 2218 1.1 riastrad 2219 1.1 riastrad if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 2220 1.1 riastrad plane_state->color_ctl = glk_plane_color_ctl(crtc_state, 2221 1.1 riastrad plane_state); 2222 1.1 riastrad 2223 1.1 riastrad if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && 2224 1.1 riastrad icl_is_hdr_plane(dev_priv, plane->id)) 2225 1.1 riastrad /* Enable and use MPEG-2 chroma siting */ 2226 1.1 riastrad plane_state->cus_ctl = PLANE_CUS_ENABLE | 2227 1.1 riastrad PLANE_CUS_HPHASE_0 | 2228 1.1 riastrad PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25; 2229 1.1 riastrad else 2230 1.1 riastrad plane_state->cus_ctl = 0; 2231 1.1 riastrad 2232 1.1 riastrad return 0; 2233 1.1 riastrad } 2234 1.1 riastrad 2235 1.1 riastrad static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv) 2236 1.1 riastrad { 2237 1.1 riastrad return INTEL_GEN(dev_priv) >= 9; 2238 1.1 riastrad } 2239 1.1 riastrad 2240 1.1 riastrad static void intel_plane_set_ckey(struct intel_plane_state *plane_state, 2241 1.1 riastrad const struct drm_intel_sprite_colorkey *set) 2242 1.1 riastrad { 2243 1.1 riastrad struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 2244 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 2245 1.1 riastrad struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 2246 1.1 riastrad 2247 1.1 riastrad *key = *set; 2248 1.1 riastrad 2249 1.1 riastrad /* 2250 1.1 riastrad * We want src key enabled on the 2251 1.1 riastrad * sprite and not on the primary. 2252 1.1 riastrad */ 2253 1.1 riastrad if (plane->id == PLANE_PRIMARY && 2254 1.1 riastrad set->flags & I915_SET_COLORKEY_SOURCE) 2255 1.1 riastrad key->flags = 0; 2256 1.1 riastrad 2257 1.1 riastrad /* 2258 1.1 riastrad * On SKL+ we want dst key enabled on 2259 1.1 riastrad * the primary and not on the sprite. 2260 1.1 riastrad */ 2261 1.1 riastrad if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY && 2262 1.1 riastrad set->flags & I915_SET_COLORKEY_DESTINATION) 2263 1.1 riastrad key->flags = 0; 2264 1.1 riastrad } 2265 1.1 riastrad 2266 1.1 riastrad int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, 2267 1.1 riastrad struct drm_file *file_priv) 2268 1.1 riastrad { 2269 1.1 riastrad struct drm_i915_private *dev_priv = to_i915(dev); 2270 1.1 riastrad struct drm_intel_sprite_colorkey *set = data; 2271 1.1 riastrad struct drm_plane *plane; 2272 1.1 riastrad struct drm_plane_state *plane_state; 2273 1.1 riastrad struct drm_atomic_state *state; 2274 1.1 riastrad struct drm_modeset_acquire_ctx ctx; 2275 1.1 riastrad int ret = 0; 2276 1.1 riastrad 2277 1.1 riastrad /* ignore the pointless "none" flag */ 2278 1.1 riastrad set->flags &= ~I915_SET_COLORKEY_NONE; 2279 1.1 riastrad 2280 1.1 riastrad if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 2281 1.1 riastrad return -EINVAL; 2282 1.1 riastrad 2283 1.1 riastrad /* Make sure we don't try to enable both src & dest simultaneously */ 2284 1.1 riastrad if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) 2285 1.1 riastrad return -EINVAL; 2286 1.1 riastrad 2287 1.1 riastrad if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && 2288 1.1 riastrad set->flags & I915_SET_COLORKEY_DESTINATION) 2289 1.1 riastrad return -EINVAL; 2290 1.1 riastrad 2291 1.1 riastrad plane = drm_plane_find(dev, file_priv, set->plane_id); 2292 1.1 riastrad if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) 2293 1.1 riastrad return -ENOENT; 2294 1.1 riastrad 2295 1.1 riastrad /* 2296 1.1 riastrad * SKL+ only plane 2 can do destination keying against plane 1. 2297 1.1 riastrad * Also multiple planes can't do destination keying on the same 2298 1.1 riastrad * pipe simultaneously. 2299 1.1 riastrad */ 2300 1.1 riastrad if (INTEL_GEN(dev_priv) >= 9 && 2301 1.1 riastrad to_intel_plane(plane)->id >= PLANE_SPRITE1 && 2302 1.1 riastrad set->flags & I915_SET_COLORKEY_DESTINATION) 2303 1.1 riastrad return -EINVAL; 2304 1.1 riastrad 2305 1.1 riastrad drm_modeset_acquire_init(&ctx, 0); 2306 1.1 riastrad 2307 1.1 riastrad state = drm_atomic_state_alloc(plane->dev); 2308 1.1 riastrad if (!state) { 2309 1.1 riastrad ret = -ENOMEM; 2310 1.1 riastrad goto out; 2311 1.1 riastrad } 2312 1.1 riastrad state->acquire_ctx = &ctx; 2313 1.1 riastrad 2314 1.1 riastrad while (1) { 2315 1.1 riastrad plane_state = drm_atomic_get_plane_state(state, plane); 2316 1.1 riastrad ret = PTR_ERR_OR_ZERO(plane_state); 2317 1.1 riastrad if (!ret) 2318 1.1 riastrad intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 2319 1.1 riastrad 2320 1.1 riastrad /* 2321 1.1 riastrad * On some platforms we have to configure 2322 1.1 riastrad * the dst colorkey on the primary plane. 2323 1.1 riastrad */ 2324 1.1 riastrad if (!ret && has_dst_key_in_primary_plane(dev_priv)) { 2325 1.1 riastrad struct intel_crtc *crtc = 2326 1.1 riastrad intel_get_crtc_for_pipe(dev_priv, 2327 1.1 riastrad to_intel_plane(plane)->pipe); 2328 1.1 riastrad 2329 1.1 riastrad plane_state = drm_atomic_get_plane_state(state, 2330 1.1 riastrad crtc->base.primary); 2331 1.1 riastrad ret = PTR_ERR_OR_ZERO(plane_state); 2332 1.1 riastrad if (!ret) 2333 1.1 riastrad intel_plane_set_ckey(to_intel_plane_state(plane_state), set); 2334 1.1 riastrad } 2335 1.1 riastrad 2336 1.1 riastrad if (!ret) 2337 1.1 riastrad ret = drm_atomic_commit(state); 2338 1.1 riastrad 2339 1.1 riastrad if (ret != -EDEADLK) 2340 1.1 riastrad break; 2341 1.1 riastrad 2342 1.1 riastrad drm_atomic_state_clear(state); 2343 1.1 riastrad drm_modeset_backoff(&ctx); 2344 1.1 riastrad } 2345 1.1 riastrad 2346 1.1 riastrad drm_atomic_state_put(state); 2347 1.1 riastrad out: 2348 1.1 riastrad drm_modeset_drop_locks(&ctx); 2349 1.1 riastrad drm_modeset_acquire_fini(&ctx); 2350 1.1 riastrad return ret; 2351 1.1 riastrad } 2352 1.1 riastrad 2353 1.1 riastrad static const u32 g4x_plane_formats[] = { 2354 1.1 riastrad DRM_FORMAT_XRGB8888, 2355 1.1 riastrad DRM_FORMAT_YUYV, 2356 1.1 riastrad DRM_FORMAT_YVYU, 2357 1.1 riastrad DRM_FORMAT_UYVY, 2358 1.1 riastrad DRM_FORMAT_VYUY, 2359 1.1 riastrad }; 2360 1.1 riastrad 2361 1.1 riastrad static const u64 i9xx_plane_format_modifiers[] = { 2362 1.1 riastrad I915_FORMAT_MOD_X_TILED, 2363 1.1 riastrad DRM_FORMAT_MOD_LINEAR, 2364 1.1 riastrad DRM_FORMAT_MOD_INVALID 2365 1.1 riastrad }; 2366 1.1 riastrad 2367 1.1 riastrad static const u32 snb_plane_formats[] = { 2368 1.1 riastrad DRM_FORMAT_XRGB8888, 2369 1.1 riastrad DRM_FORMAT_XBGR8888, 2370 1.1 riastrad DRM_FORMAT_XRGB2101010, 2371 1.1 riastrad DRM_FORMAT_XBGR2101010, 2372 1.1 riastrad DRM_FORMAT_XRGB16161616F, 2373 1.1 riastrad DRM_FORMAT_XBGR16161616F, 2374 1.1 riastrad DRM_FORMAT_YUYV, 2375 1.1 riastrad DRM_FORMAT_YVYU, 2376 1.1 riastrad DRM_FORMAT_UYVY, 2377 1.1 riastrad DRM_FORMAT_VYUY, 2378 1.1 riastrad }; 2379 1.1 riastrad 2380 1.1 riastrad static const u32 vlv_plane_formats[] = { 2381 1.1 riastrad DRM_FORMAT_C8, 2382 1.1 riastrad DRM_FORMAT_RGB565, 2383 1.1 riastrad DRM_FORMAT_XRGB8888, 2384 1.1 riastrad DRM_FORMAT_XBGR8888, 2385 1.1 riastrad DRM_FORMAT_ARGB8888, 2386 1.1 riastrad DRM_FORMAT_ABGR8888, 2387 1.1 riastrad DRM_FORMAT_XBGR2101010, 2388 1.1 riastrad DRM_FORMAT_ABGR2101010, 2389 1.1 riastrad DRM_FORMAT_YUYV, 2390 1.1 riastrad DRM_FORMAT_YVYU, 2391 1.1 riastrad DRM_FORMAT_UYVY, 2392 1.1 riastrad DRM_FORMAT_VYUY, 2393 1.1 riastrad }; 2394 1.1 riastrad 2395 1.1 riastrad static const u32 chv_pipe_b_sprite_formats[] = { 2396 1.1 riastrad DRM_FORMAT_C8, 2397 1.1 riastrad DRM_FORMAT_RGB565, 2398 1.1 riastrad DRM_FORMAT_XRGB8888, 2399 1.1 riastrad DRM_FORMAT_XBGR8888, 2400 1.1 riastrad DRM_FORMAT_ARGB8888, 2401 1.1 riastrad DRM_FORMAT_ABGR8888, 2402 1.1 riastrad DRM_FORMAT_XRGB2101010, 2403 1.1 riastrad DRM_FORMAT_XBGR2101010, 2404 1.1 riastrad DRM_FORMAT_ARGB2101010, 2405 1.1 riastrad DRM_FORMAT_ABGR2101010, 2406 1.1 riastrad DRM_FORMAT_YUYV, 2407 1.1 riastrad DRM_FORMAT_YVYU, 2408 1.1 riastrad DRM_FORMAT_UYVY, 2409 1.1 riastrad DRM_FORMAT_VYUY, 2410 1.1 riastrad }; 2411 1.1 riastrad 2412 1.1 riastrad static const u32 skl_plane_formats[] = { 2413 1.1 riastrad DRM_FORMAT_C8, 2414 1.1 riastrad DRM_FORMAT_RGB565, 2415 1.1 riastrad DRM_FORMAT_XRGB8888, 2416 1.1 riastrad DRM_FORMAT_XBGR8888, 2417 1.1 riastrad DRM_FORMAT_ARGB8888, 2418 1.1 riastrad DRM_FORMAT_ABGR8888, 2419 1.1 riastrad DRM_FORMAT_XRGB2101010, 2420 1.1 riastrad DRM_FORMAT_XBGR2101010, 2421 1.1 riastrad DRM_FORMAT_XRGB16161616F, 2422 1.1 riastrad DRM_FORMAT_XBGR16161616F, 2423 1.1 riastrad DRM_FORMAT_YUYV, 2424 1.1 riastrad DRM_FORMAT_YVYU, 2425 1.1 riastrad DRM_FORMAT_UYVY, 2426 1.1 riastrad DRM_FORMAT_VYUY, 2427 1.1 riastrad }; 2428 1.1 riastrad 2429 1.1 riastrad static const u32 skl_planar_formats[] = { 2430 1.1 riastrad DRM_FORMAT_C8, 2431 1.1 riastrad DRM_FORMAT_RGB565, 2432 1.1 riastrad DRM_FORMAT_XRGB8888, 2433 1.1 riastrad DRM_FORMAT_XBGR8888, 2434 1.1 riastrad DRM_FORMAT_ARGB8888, 2435 1.1 riastrad DRM_FORMAT_ABGR8888, 2436 1.1 riastrad DRM_FORMAT_XRGB2101010, 2437 1.1 riastrad DRM_FORMAT_XBGR2101010, 2438 1.1 riastrad DRM_FORMAT_XRGB16161616F, 2439 1.1 riastrad DRM_FORMAT_XBGR16161616F, 2440 1.1 riastrad DRM_FORMAT_YUYV, 2441 1.1 riastrad DRM_FORMAT_YVYU, 2442 1.1 riastrad DRM_FORMAT_UYVY, 2443 1.1 riastrad DRM_FORMAT_VYUY, 2444 1.1 riastrad DRM_FORMAT_NV12, 2445 1.1 riastrad }; 2446 1.1 riastrad 2447 1.1 riastrad static const u32 glk_planar_formats[] = { 2448 1.1 riastrad DRM_FORMAT_C8, 2449 1.1 riastrad DRM_FORMAT_RGB565, 2450 1.1 riastrad DRM_FORMAT_XRGB8888, 2451 1.1 riastrad DRM_FORMAT_XBGR8888, 2452 1.1 riastrad DRM_FORMAT_ARGB8888, 2453 1.1 riastrad DRM_FORMAT_ABGR8888, 2454 1.1 riastrad DRM_FORMAT_XRGB2101010, 2455 1.1 riastrad DRM_FORMAT_XBGR2101010, 2456 1.1 riastrad DRM_FORMAT_XRGB16161616F, 2457 1.1 riastrad DRM_FORMAT_XBGR16161616F, 2458 1.1 riastrad DRM_FORMAT_YUYV, 2459 1.1 riastrad DRM_FORMAT_YVYU, 2460 1.1 riastrad DRM_FORMAT_UYVY, 2461 1.1 riastrad DRM_FORMAT_VYUY, 2462 1.1 riastrad DRM_FORMAT_NV12, 2463 1.1 riastrad DRM_FORMAT_P010, 2464 1.1 riastrad DRM_FORMAT_P012, 2465 1.1 riastrad DRM_FORMAT_P016, 2466 1.1 riastrad }; 2467 1.1 riastrad 2468 1.1 riastrad static const u32 icl_sdr_y_plane_formats[] = { 2469 1.1 riastrad DRM_FORMAT_C8, 2470 1.1 riastrad DRM_FORMAT_RGB565, 2471 1.1 riastrad DRM_FORMAT_XRGB8888, 2472 1.1 riastrad DRM_FORMAT_XBGR8888, 2473 1.1 riastrad DRM_FORMAT_ARGB8888, 2474 1.1 riastrad DRM_FORMAT_ABGR8888, 2475 1.1 riastrad DRM_FORMAT_XRGB2101010, 2476 1.1 riastrad DRM_FORMAT_XBGR2101010, 2477 1.1 riastrad DRM_FORMAT_ARGB2101010, 2478 1.1 riastrad DRM_FORMAT_ABGR2101010, 2479 1.1 riastrad DRM_FORMAT_YUYV, 2480 1.1 riastrad DRM_FORMAT_YVYU, 2481 1.1 riastrad DRM_FORMAT_UYVY, 2482 1.1 riastrad DRM_FORMAT_VYUY, 2483 1.1 riastrad DRM_FORMAT_Y210, 2484 1.1 riastrad DRM_FORMAT_Y212, 2485 1.1 riastrad DRM_FORMAT_Y216, 2486 1.1 riastrad DRM_FORMAT_XVYU2101010, 2487 1.1 riastrad DRM_FORMAT_XVYU12_16161616, 2488 1.1 riastrad DRM_FORMAT_XVYU16161616, 2489 1.1 riastrad }; 2490 1.1 riastrad 2491 1.1 riastrad static const u32 icl_sdr_uv_plane_formats[] = { 2492 1.1 riastrad DRM_FORMAT_C8, 2493 1.1 riastrad DRM_FORMAT_RGB565, 2494 1.1 riastrad DRM_FORMAT_XRGB8888, 2495 1.1 riastrad DRM_FORMAT_XBGR8888, 2496 1.1 riastrad DRM_FORMAT_ARGB8888, 2497 1.1 riastrad DRM_FORMAT_ABGR8888, 2498 1.1 riastrad DRM_FORMAT_XRGB2101010, 2499 1.1 riastrad DRM_FORMAT_XBGR2101010, 2500 1.1 riastrad DRM_FORMAT_ARGB2101010, 2501 1.1 riastrad DRM_FORMAT_ABGR2101010, 2502 1.1 riastrad DRM_FORMAT_YUYV, 2503 1.1 riastrad DRM_FORMAT_YVYU, 2504 1.1 riastrad DRM_FORMAT_UYVY, 2505 1.1 riastrad DRM_FORMAT_VYUY, 2506 1.1 riastrad DRM_FORMAT_NV12, 2507 1.1 riastrad DRM_FORMAT_P010, 2508 1.1 riastrad DRM_FORMAT_P012, 2509 1.1 riastrad DRM_FORMAT_P016, 2510 1.1 riastrad DRM_FORMAT_Y210, 2511 1.1 riastrad DRM_FORMAT_Y212, 2512 1.1 riastrad DRM_FORMAT_Y216, 2513 1.1 riastrad DRM_FORMAT_XVYU2101010, 2514 1.1 riastrad DRM_FORMAT_XVYU12_16161616, 2515 1.1 riastrad DRM_FORMAT_XVYU16161616, 2516 1.1 riastrad }; 2517 1.1 riastrad 2518 1.1 riastrad static const u32 icl_hdr_plane_formats[] = { 2519 1.1 riastrad DRM_FORMAT_C8, 2520 1.1 riastrad DRM_FORMAT_RGB565, 2521 1.1 riastrad DRM_FORMAT_XRGB8888, 2522 1.1 riastrad DRM_FORMAT_XBGR8888, 2523 1.1 riastrad DRM_FORMAT_ARGB8888, 2524 1.1 riastrad DRM_FORMAT_ABGR8888, 2525 1.1 riastrad DRM_FORMAT_XRGB2101010, 2526 1.1 riastrad DRM_FORMAT_XBGR2101010, 2527 1.1 riastrad DRM_FORMAT_ARGB2101010, 2528 1.1 riastrad DRM_FORMAT_ABGR2101010, 2529 1.1 riastrad DRM_FORMAT_XRGB16161616F, 2530 1.1 riastrad DRM_FORMAT_XBGR16161616F, 2531 1.1 riastrad DRM_FORMAT_ARGB16161616F, 2532 1.1 riastrad DRM_FORMAT_ABGR16161616F, 2533 1.1 riastrad DRM_FORMAT_YUYV, 2534 1.1 riastrad DRM_FORMAT_YVYU, 2535 1.1 riastrad DRM_FORMAT_UYVY, 2536 1.1 riastrad DRM_FORMAT_VYUY, 2537 1.1 riastrad DRM_FORMAT_NV12, 2538 1.1 riastrad DRM_FORMAT_P010, 2539 1.1 riastrad DRM_FORMAT_P012, 2540 1.1 riastrad DRM_FORMAT_P016, 2541 1.1 riastrad DRM_FORMAT_Y210, 2542 1.1 riastrad DRM_FORMAT_Y212, 2543 1.1 riastrad DRM_FORMAT_Y216, 2544 1.1 riastrad DRM_FORMAT_XVYU2101010, 2545 1.1 riastrad DRM_FORMAT_XVYU12_16161616, 2546 1.1 riastrad DRM_FORMAT_XVYU16161616, 2547 1.1 riastrad }; 2548 1.1 riastrad 2549 1.1 riastrad static const u64 skl_plane_format_modifiers_noccs[] = { 2550 1.1 riastrad I915_FORMAT_MOD_Yf_TILED, 2551 1.1 riastrad I915_FORMAT_MOD_Y_TILED, 2552 1.1 riastrad I915_FORMAT_MOD_X_TILED, 2553 1.1 riastrad DRM_FORMAT_MOD_LINEAR, 2554 1.1 riastrad DRM_FORMAT_MOD_INVALID 2555 1.1 riastrad }; 2556 1.1 riastrad 2557 1.1 riastrad static const u64 skl_plane_format_modifiers_ccs[] = { 2558 1.1 riastrad I915_FORMAT_MOD_Yf_TILED_CCS, 2559 1.1 riastrad I915_FORMAT_MOD_Y_TILED_CCS, 2560 1.1 riastrad I915_FORMAT_MOD_Yf_TILED, 2561 1.1 riastrad I915_FORMAT_MOD_Y_TILED, 2562 1.1 riastrad I915_FORMAT_MOD_X_TILED, 2563 1.1 riastrad DRM_FORMAT_MOD_LINEAR, 2564 1.1 riastrad DRM_FORMAT_MOD_INVALID 2565 1.1 riastrad }; 2566 1.1 riastrad 2567 1.1 riastrad static const u64 gen12_plane_format_modifiers_mc_ccs[] = { 2568 1.1 riastrad I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS, 2569 1.1 riastrad I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, 2570 1.1 riastrad I915_FORMAT_MOD_Y_TILED, 2571 1.1 riastrad I915_FORMAT_MOD_X_TILED, 2572 1.1 riastrad DRM_FORMAT_MOD_LINEAR, 2573 1.1 riastrad DRM_FORMAT_MOD_INVALID 2574 1.1 riastrad }; 2575 1.1 riastrad 2576 1.1 riastrad static const u64 gen12_plane_format_modifiers_rc_ccs[] = { 2577 1.1 riastrad I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, 2578 1.1 riastrad I915_FORMAT_MOD_Y_TILED, 2579 1.1 riastrad I915_FORMAT_MOD_X_TILED, 2580 1.1 riastrad DRM_FORMAT_MOD_LINEAR, 2581 1.1 riastrad DRM_FORMAT_MOD_INVALID 2582 1.1 riastrad }; 2583 1.1 riastrad 2584 1.1 riastrad static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane, 2585 1.1 riastrad u32 format, u64 modifier) 2586 1.1 riastrad { 2587 1.1 riastrad switch (modifier) { 2588 1.1 riastrad case DRM_FORMAT_MOD_LINEAR: 2589 1.1 riastrad case I915_FORMAT_MOD_X_TILED: 2590 1.1 riastrad break; 2591 1.1 riastrad default: 2592 1.1 riastrad return false; 2593 1.1 riastrad } 2594 1.1 riastrad 2595 1.1 riastrad switch (format) { 2596 1.1 riastrad case DRM_FORMAT_XRGB8888: 2597 1.1 riastrad case DRM_FORMAT_YUYV: 2598 1.1 riastrad case DRM_FORMAT_YVYU: 2599 1.1 riastrad case DRM_FORMAT_UYVY: 2600 1.1 riastrad case DRM_FORMAT_VYUY: 2601 1.1 riastrad if (modifier == DRM_FORMAT_MOD_LINEAR || 2602 1.1 riastrad modifier == I915_FORMAT_MOD_X_TILED) 2603 1.1 riastrad return true; 2604 1.1 riastrad /* fall through */ 2605 1.1 riastrad default: 2606 1.1 riastrad return false; 2607 1.1 riastrad } 2608 1.1 riastrad } 2609 1.1 riastrad 2610 1.1 riastrad static bool snb_sprite_format_mod_supported(struct drm_plane *_plane, 2611 1.1 riastrad u32 format, u64 modifier) 2612 1.1 riastrad { 2613 1.1 riastrad switch (modifier) { 2614 1.1 riastrad case DRM_FORMAT_MOD_LINEAR: 2615 1.1 riastrad case I915_FORMAT_MOD_X_TILED: 2616 1.1 riastrad break; 2617 1.1 riastrad default: 2618 1.1 riastrad return false; 2619 1.1 riastrad } 2620 1.1 riastrad 2621 1.1 riastrad switch (format) { 2622 1.1 riastrad case DRM_FORMAT_XRGB8888: 2623 1.1 riastrad case DRM_FORMAT_XBGR8888: 2624 1.1 riastrad case DRM_FORMAT_XRGB2101010: 2625 1.1 riastrad case DRM_FORMAT_XBGR2101010: 2626 1.1 riastrad case DRM_FORMAT_XRGB16161616F: 2627 1.1 riastrad case DRM_FORMAT_XBGR16161616F: 2628 1.1 riastrad case DRM_FORMAT_YUYV: 2629 1.1 riastrad case DRM_FORMAT_YVYU: 2630 1.1 riastrad case DRM_FORMAT_UYVY: 2631 1.1 riastrad case DRM_FORMAT_VYUY: 2632 1.1 riastrad if (modifier == DRM_FORMAT_MOD_LINEAR || 2633 1.1 riastrad modifier == I915_FORMAT_MOD_X_TILED) 2634 1.1 riastrad return true; 2635 1.1 riastrad /* fall through */ 2636 1.1 riastrad default: 2637 1.1 riastrad return false; 2638 1.1 riastrad } 2639 1.1 riastrad } 2640 1.1 riastrad 2641 1.1 riastrad static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane, 2642 1.1 riastrad u32 format, u64 modifier) 2643 1.1 riastrad { 2644 1.1 riastrad switch (modifier) { 2645 1.1 riastrad case DRM_FORMAT_MOD_LINEAR: 2646 1.1 riastrad case I915_FORMAT_MOD_X_TILED: 2647 1.1 riastrad break; 2648 1.1 riastrad default: 2649 1.1 riastrad return false; 2650 1.1 riastrad } 2651 1.1 riastrad 2652 1.1 riastrad switch (format) { 2653 1.1 riastrad case DRM_FORMAT_C8: 2654 1.1 riastrad case DRM_FORMAT_RGB565: 2655 1.1 riastrad case DRM_FORMAT_ABGR8888: 2656 1.1 riastrad case DRM_FORMAT_ARGB8888: 2657 1.1 riastrad case DRM_FORMAT_XBGR8888: 2658 1.1 riastrad case DRM_FORMAT_XRGB8888: 2659 1.1 riastrad case DRM_FORMAT_XBGR2101010: 2660 1.1 riastrad case DRM_FORMAT_ABGR2101010: 2661 1.1 riastrad case DRM_FORMAT_XRGB2101010: 2662 1.1 riastrad case DRM_FORMAT_ARGB2101010: 2663 1.1 riastrad case DRM_FORMAT_YUYV: 2664 1.1 riastrad case DRM_FORMAT_YVYU: 2665 1.1 riastrad case DRM_FORMAT_UYVY: 2666 1.1 riastrad case DRM_FORMAT_VYUY: 2667 1.1 riastrad if (modifier == DRM_FORMAT_MOD_LINEAR || 2668 1.1 riastrad modifier == I915_FORMAT_MOD_X_TILED) 2669 1.1 riastrad return true; 2670 1.1 riastrad /* fall through */ 2671 1.1 riastrad default: 2672 1.1 riastrad return false; 2673 1.1 riastrad } 2674 1.1 riastrad } 2675 1.1 riastrad 2676 1.1 riastrad static bool skl_plane_format_mod_supported(struct drm_plane *_plane, 2677 1.1 riastrad u32 format, u64 modifier) 2678 1.1 riastrad { 2679 1.1 riastrad struct intel_plane *plane = to_intel_plane(_plane); 2680 1.1 riastrad 2681 1.1 riastrad switch (modifier) { 2682 1.1 riastrad case DRM_FORMAT_MOD_LINEAR: 2683 1.1 riastrad case I915_FORMAT_MOD_X_TILED: 2684 1.1 riastrad case I915_FORMAT_MOD_Y_TILED: 2685 1.1 riastrad case I915_FORMAT_MOD_Yf_TILED: 2686 1.1 riastrad break; 2687 1.1 riastrad case I915_FORMAT_MOD_Y_TILED_CCS: 2688 1.1 riastrad case I915_FORMAT_MOD_Yf_TILED_CCS: 2689 1.1 riastrad if (!plane->has_ccs) 2690 1.1 riastrad return false; 2691 1.1 riastrad break; 2692 1.1 riastrad default: 2693 1.1 riastrad return false; 2694 1.1 riastrad } 2695 1.1 riastrad 2696 1.1 riastrad switch (format) { 2697 1.1 riastrad case DRM_FORMAT_XRGB8888: 2698 1.1 riastrad case DRM_FORMAT_XBGR8888: 2699 1.1 riastrad case DRM_FORMAT_ARGB8888: 2700 1.1 riastrad case DRM_FORMAT_ABGR8888: 2701 1.1 riastrad if (is_ccs_modifier(modifier)) 2702 1.1 riastrad return true; 2703 1.1 riastrad /* fall through */ 2704 1.1 riastrad case DRM_FORMAT_RGB565: 2705 1.1 riastrad case DRM_FORMAT_XRGB2101010: 2706 1.1 riastrad case DRM_FORMAT_XBGR2101010: 2707 1.1 riastrad case DRM_FORMAT_ARGB2101010: 2708 1.1 riastrad case DRM_FORMAT_ABGR2101010: 2709 1.1 riastrad case DRM_FORMAT_YUYV: 2710 1.1 riastrad case DRM_FORMAT_YVYU: 2711 1.1 riastrad case DRM_FORMAT_UYVY: 2712 1.1 riastrad case DRM_FORMAT_VYUY: 2713 1.1 riastrad case DRM_FORMAT_NV12: 2714 1.1 riastrad case DRM_FORMAT_P010: 2715 1.1 riastrad case DRM_FORMAT_P012: 2716 1.1 riastrad case DRM_FORMAT_P016: 2717 1.1 riastrad case DRM_FORMAT_XVYU2101010: 2718 1.1 riastrad if (modifier == I915_FORMAT_MOD_Yf_TILED) 2719 1.1 riastrad return true; 2720 1.1 riastrad /* fall through */ 2721 1.1 riastrad case DRM_FORMAT_C8: 2722 1.1 riastrad case DRM_FORMAT_XBGR16161616F: 2723 1.1 riastrad case DRM_FORMAT_ABGR16161616F: 2724 1.1 riastrad case DRM_FORMAT_XRGB16161616F: 2725 1.1 riastrad case DRM_FORMAT_ARGB16161616F: 2726 1.1 riastrad case DRM_FORMAT_Y210: 2727 1.1 riastrad case DRM_FORMAT_Y212: 2728 1.1 riastrad case DRM_FORMAT_Y216: 2729 1.1 riastrad case DRM_FORMAT_XVYU12_16161616: 2730 1.1 riastrad case DRM_FORMAT_XVYU16161616: 2731 1.1 riastrad if (modifier == DRM_FORMAT_MOD_LINEAR || 2732 1.1 riastrad modifier == I915_FORMAT_MOD_X_TILED || 2733 1.1 riastrad modifier == I915_FORMAT_MOD_Y_TILED) 2734 1.1 riastrad return true; 2735 1.1 riastrad /* fall through */ 2736 1.1 riastrad default: 2737 1.1 riastrad return false; 2738 1.1 riastrad } 2739 1.1 riastrad } 2740 1.1 riastrad 2741 1.1 riastrad static bool gen12_plane_supports_mc_ccs(enum plane_id plane_id) 2742 1.1 riastrad { 2743 1.1 riastrad return plane_id < PLANE_SPRITE4; 2744 1.1 riastrad } 2745 1.1 riastrad 2746 1.1 riastrad static bool gen12_plane_format_mod_supported(struct drm_plane *_plane, 2747 1.1 riastrad u32 format, u64 modifier) 2748 1.1 riastrad { 2749 1.1 riastrad struct intel_plane *plane = to_intel_plane(_plane); 2750 1.1 riastrad 2751 1.1 riastrad switch (modifier) { 2752 1.1 riastrad case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: 2753 1.1 riastrad if (!gen12_plane_supports_mc_ccs(plane->id)) 2754 1.1 riastrad return false; 2755 1.1 riastrad /* fall through */ 2756 1.1 riastrad case DRM_FORMAT_MOD_LINEAR: 2757 1.1 riastrad case I915_FORMAT_MOD_X_TILED: 2758 1.1 riastrad case I915_FORMAT_MOD_Y_TILED: 2759 1.1 riastrad case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: 2760 1.1 riastrad break; 2761 1.1 riastrad default: 2762 1.1 riastrad return false; 2763 1.1 riastrad } 2764 1.1 riastrad 2765 1.1 riastrad switch (format) { 2766 1.1 riastrad case DRM_FORMAT_XRGB8888: 2767 1.1 riastrad case DRM_FORMAT_XBGR8888: 2768 1.1 riastrad case DRM_FORMAT_ARGB8888: 2769 1.1 riastrad case DRM_FORMAT_ABGR8888: 2770 1.1 riastrad if (is_ccs_modifier(modifier)) 2771 1.1 riastrad return true; 2772 1.1 riastrad /* fall through */ 2773 1.1 riastrad case DRM_FORMAT_YUYV: 2774 1.1 riastrad case DRM_FORMAT_YVYU: 2775 1.1 riastrad case DRM_FORMAT_UYVY: 2776 1.1 riastrad case DRM_FORMAT_VYUY: 2777 1.1 riastrad case DRM_FORMAT_NV12: 2778 1.1 riastrad case DRM_FORMAT_P010: 2779 1.1 riastrad case DRM_FORMAT_P012: 2780 1.1 riastrad case DRM_FORMAT_P016: 2781 1.1 riastrad if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) 2782 1.1 riastrad return true; 2783 1.1 riastrad /* fall through */ 2784 1.1 riastrad case DRM_FORMAT_RGB565: 2785 1.1 riastrad case DRM_FORMAT_XRGB2101010: 2786 1.1 riastrad case DRM_FORMAT_XBGR2101010: 2787 1.1 riastrad case DRM_FORMAT_ARGB2101010: 2788 1.1 riastrad case DRM_FORMAT_ABGR2101010: 2789 1.1 riastrad case DRM_FORMAT_XVYU2101010: 2790 1.1 riastrad case DRM_FORMAT_C8: 2791 1.1 riastrad case DRM_FORMAT_XBGR16161616F: 2792 1.1 riastrad case DRM_FORMAT_ABGR16161616F: 2793 1.1 riastrad case DRM_FORMAT_XRGB16161616F: 2794 1.1 riastrad case DRM_FORMAT_ARGB16161616F: 2795 1.1 riastrad case DRM_FORMAT_Y210: 2796 1.1 riastrad case DRM_FORMAT_Y212: 2797 1.1 riastrad case DRM_FORMAT_Y216: 2798 1.1 riastrad case DRM_FORMAT_XVYU12_16161616: 2799 1.1 riastrad case DRM_FORMAT_XVYU16161616: 2800 1.1 riastrad if (modifier == DRM_FORMAT_MOD_LINEAR || 2801 1.1 riastrad modifier == I915_FORMAT_MOD_X_TILED || 2802 1.1 riastrad modifier == I915_FORMAT_MOD_Y_TILED) 2803 1.1 riastrad return true; 2804 1.1 riastrad /* fall through */ 2805 1.1 riastrad default: 2806 1.1 riastrad return false; 2807 1.1 riastrad } 2808 1.1 riastrad } 2809 1.1 riastrad 2810 1.1 riastrad static const struct drm_plane_funcs g4x_sprite_funcs = { 2811 1.1 riastrad .update_plane = drm_atomic_helper_update_plane, 2812 1.1 riastrad .disable_plane = drm_atomic_helper_disable_plane, 2813 1.1 riastrad .destroy = intel_plane_destroy, 2814 1.1 riastrad .atomic_duplicate_state = intel_plane_duplicate_state, 2815 1.1 riastrad .atomic_destroy_state = intel_plane_destroy_state, 2816 1.1 riastrad .format_mod_supported = g4x_sprite_format_mod_supported, 2817 1.1 riastrad }; 2818 1.1 riastrad 2819 1.1 riastrad static const struct drm_plane_funcs snb_sprite_funcs = { 2820 1.1 riastrad .update_plane = drm_atomic_helper_update_plane, 2821 1.1 riastrad .disable_plane = drm_atomic_helper_disable_plane, 2822 1.1 riastrad .destroy = intel_plane_destroy, 2823 1.1 riastrad .atomic_duplicate_state = intel_plane_duplicate_state, 2824 1.1 riastrad .atomic_destroy_state = intel_plane_destroy_state, 2825 1.1 riastrad .format_mod_supported = snb_sprite_format_mod_supported, 2826 1.1 riastrad }; 2827 1.1 riastrad 2828 1.1 riastrad static const struct drm_plane_funcs vlv_sprite_funcs = { 2829 1.1 riastrad .update_plane = drm_atomic_helper_update_plane, 2830 1.1 riastrad .disable_plane = drm_atomic_helper_disable_plane, 2831 1.1 riastrad .destroy = intel_plane_destroy, 2832 1.1 riastrad .atomic_duplicate_state = intel_plane_duplicate_state, 2833 1.1 riastrad .atomic_destroy_state = intel_plane_destroy_state, 2834 1.1 riastrad .format_mod_supported = vlv_sprite_format_mod_supported, 2835 1.1 riastrad }; 2836 1.1 riastrad 2837 1.1 riastrad static const struct drm_plane_funcs skl_plane_funcs = { 2838 1.1 riastrad .update_plane = drm_atomic_helper_update_plane, 2839 1.1 riastrad .disable_plane = drm_atomic_helper_disable_plane, 2840 1.1 riastrad .destroy = intel_plane_destroy, 2841 1.1 riastrad .atomic_duplicate_state = intel_plane_duplicate_state, 2842 1.1 riastrad .atomic_destroy_state = intel_plane_destroy_state, 2843 1.1 riastrad .format_mod_supported = skl_plane_format_mod_supported, 2844 1.1 riastrad }; 2845 1.1 riastrad 2846 1.1 riastrad static const struct drm_plane_funcs gen12_plane_funcs = { 2847 1.1 riastrad .update_plane = drm_atomic_helper_update_plane, 2848 1.1 riastrad .disable_plane = drm_atomic_helper_disable_plane, 2849 1.1 riastrad .destroy = intel_plane_destroy, 2850 1.1 riastrad .atomic_duplicate_state = intel_plane_duplicate_state, 2851 1.1 riastrad .atomic_destroy_state = intel_plane_destroy_state, 2852 1.1 riastrad .format_mod_supported = gen12_plane_format_mod_supported, 2853 1.1 riastrad }; 2854 1.1 riastrad 2855 1.1 riastrad static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, 2856 1.1 riastrad enum pipe pipe, enum plane_id plane_id) 2857 1.1 riastrad { 2858 1.1 riastrad if (!HAS_FBC(dev_priv)) 2859 1.1 riastrad return false; 2860 1.1 riastrad 2861 1.1 riastrad return pipe == PIPE_A && plane_id == PLANE_PRIMARY; 2862 1.1 riastrad } 2863 1.1 riastrad 2864 1.1 riastrad static bool skl_plane_has_planar(struct drm_i915_private *dev_priv, 2865 1.1 riastrad enum pipe pipe, enum plane_id plane_id) 2866 1.1 riastrad { 2867 1.1 riastrad /* Display WA #0870: skl, bxt */ 2868 1.1 riastrad if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) 2869 1.1 riastrad return false; 2870 1.1 riastrad 2871 1.1 riastrad if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C) 2872 1.1 riastrad return false; 2873 1.1 riastrad 2874 1.1 riastrad if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0) 2875 1.1 riastrad return false; 2876 1.1 riastrad 2877 1.1 riastrad return true; 2878 1.1 riastrad } 2879 1.1 riastrad 2880 1.1 riastrad static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv, 2881 1.1 riastrad enum pipe pipe, enum plane_id plane_id, 2882 1.1 riastrad int *num_formats) 2883 1.1 riastrad { 2884 1.1 riastrad if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2885 1.1 riastrad *num_formats = ARRAY_SIZE(skl_planar_formats); 2886 1.1 riastrad return skl_planar_formats; 2887 1.1 riastrad } else { 2888 1.1 riastrad *num_formats = ARRAY_SIZE(skl_plane_formats); 2889 1.1 riastrad return skl_plane_formats; 2890 1.1 riastrad } 2891 1.1 riastrad } 2892 1.1 riastrad 2893 1.1 riastrad static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv, 2894 1.1 riastrad enum pipe pipe, enum plane_id plane_id, 2895 1.1 riastrad int *num_formats) 2896 1.1 riastrad { 2897 1.1 riastrad if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { 2898 1.1 riastrad *num_formats = ARRAY_SIZE(glk_planar_formats); 2899 1.1 riastrad return glk_planar_formats; 2900 1.1 riastrad } else { 2901 1.1 riastrad *num_formats = ARRAY_SIZE(skl_plane_formats); 2902 1.1 riastrad return skl_plane_formats; 2903 1.1 riastrad } 2904 1.1 riastrad } 2905 1.1 riastrad 2906 1.1 riastrad static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv, 2907 1.1 riastrad enum pipe pipe, enum plane_id plane_id, 2908 1.1 riastrad int *num_formats) 2909 1.1 riastrad { 2910 1.1 riastrad if (icl_is_hdr_plane(dev_priv, plane_id)) { 2911 1.1 riastrad *num_formats = ARRAY_SIZE(icl_hdr_plane_formats); 2912 1.1 riastrad return icl_hdr_plane_formats; 2913 1.1 riastrad } else if (icl_is_nv12_y_plane(plane_id)) { 2914 1.1 riastrad *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats); 2915 1.1 riastrad return icl_sdr_y_plane_formats; 2916 1.1 riastrad } else { 2917 1.1 riastrad *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats); 2918 1.1 riastrad return icl_sdr_uv_plane_formats; 2919 1.1 riastrad } 2920 1.1 riastrad } 2921 1.1 riastrad 2922 1.1 riastrad static const u64 *gen12_get_plane_modifiers(enum plane_id plane_id) 2923 1.1 riastrad { 2924 1.1 riastrad if (gen12_plane_supports_mc_ccs(plane_id)) 2925 1.1 riastrad return gen12_plane_format_modifiers_mc_ccs; 2926 1.1 riastrad else 2927 1.1 riastrad return gen12_plane_format_modifiers_rc_ccs; 2928 1.1 riastrad } 2929 1.1 riastrad 2930 1.1 riastrad static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv, 2931 1.1 riastrad enum pipe pipe, enum plane_id plane_id) 2932 1.1 riastrad { 2933 1.1 riastrad if (plane_id == PLANE_CURSOR) 2934 1.1 riastrad return false; 2935 1.1 riastrad 2936 1.1 riastrad if (INTEL_GEN(dev_priv) >= 10) 2937 1.1 riastrad return true; 2938 1.1 riastrad 2939 1.1 riastrad if (IS_GEMINILAKE(dev_priv)) 2940 1.1 riastrad return pipe != PIPE_C; 2941 1.1 riastrad 2942 1.1 riastrad return pipe != PIPE_C && 2943 1.1 riastrad (plane_id == PLANE_PRIMARY || 2944 1.1 riastrad plane_id == PLANE_SPRITE0); 2945 1.1 riastrad } 2946 1.1 riastrad 2947 1.1 riastrad struct intel_plane * 2948 1.1 riastrad skl_universal_plane_create(struct drm_i915_private *dev_priv, 2949 1.1 riastrad enum pipe pipe, enum plane_id plane_id) 2950 1.1 riastrad { 2951 1.1 riastrad const struct drm_plane_funcs *plane_funcs; 2952 1.1 riastrad struct intel_plane *plane; 2953 1.1 riastrad enum drm_plane_type plane_type; 2954 1.1 riastrad unsigned int supported_rotations; 2955 1.1 riastrad unsigned int possible_crtcs; 2956 1.1 riastrad const u64 *modifiers; 2957 1.1 riastrad const u32 *formats; 2958 1.1 riastrad int num_formats; 2959 1.1 riastrad int ret; 2960 1.1 riastrad 2961 1.1 riastrad plane = intel_plane_alloc(); 2962 1.1 riastrad if (IS_ERR(plane)) 2963 1.1 riastrad return plane; 2964 1.1 riastrad 2965 1.1 riastrad plane->pipe = pipe; 2966 1.1 riastrad plane->id = plane_id; 2967 1.1 riastrad plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id); 2968 1.1 riastrad 2969 1.1 riastrad plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id); 2970 1.1 riastrad if (plane->has_fbc) { 2971 1.1 riastrad struct intel_fbc *fbc = &dev_priv->fbc; 2972 1.1 riastrad 2973 1.1 riastrad fbc->possible_framebuffer_bits |= plane->frontbuffer_bit; 2974 1.1 riastrad } 2975 1.1 riastrad 2976 1.1 riastrad plane->max_stride = skl_plane_max_stride; 2977 1.1 riastrad plane->update_plane = skl_update_plane; 2978 1.1 riastrad plane->disable_plane = skl_disable_plane; 2979 1.1 riastrad plane->get_hw_state = skl_plane_get_hw_state; 2980 1.1 riastrad plane->check_plane = skl_plane_check; 2981 1.1 riastrad plane->min_cdclk = skl_plane_min_cdclk; 2982 1.1 riastrad 2983 1.1 riastrad if (INTEL_GEN(dev_priv) >= 11) 2984 1.1 riastrad formats = icl_get_plane_formats(dev_priv, pipe, 2985 1.1 riastrad plane_id, &num_formats); 2986 1.1 riastrad else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 2987 1.1 riastrad formats = glk_get_plane_formats(dev_priv, pipe, 2988 1.1 riastrad plane_id, &num_formats); 2989 1.1 riastrad else 2990 1.1 riastrad formats = skl_get_plane_formats(dev_priv, pipe, 2991 1.1 riastrad plane_id, &num_formats); 2992 1.1 riastrad 2993 1.1 riastrad plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id); 2994 1.1 riastrad if (INTEL_GEN(dev_priv) >= 12) { 2995 1.1 riastrad modifiers = gen12_get_plane_modifiers(plane_id); 2996 1.1 riastrad plane_funcs = &gen12_plane_funcs; 2997 1.1 riastrad } else { 2998 1.1 riastrad if (plane->has_ccs) 2999 1.1 riastrad modifiers = skl_plane_format_modifiers_ccs; 3000 1.1 riastrad else 3001 1.1 riastrad modifiers = skl_plane_format_modifiers_noccs; 3002 1.1 riastrad plane_funcs = &skl_plane_funcs; 3003 1.1 riastrad } 3004 1.1 riastrad 3005 1.1 riastrad if (plane_id == PLANE_PRIMARY) 3006 1.1 riastrad plane_type = DRM_PLANE_TYPE_PRIMARY; 3007 1.1 riastrad else 3008 1.1 riastrad plane_type = DRM_PLANE_TYPE_OVERLAY; 3009 1.1 riastrad 3010 1.1 riastrad possible_crtcs = BIT(pipe); 3011 1.1 riastrad 3012 1.1 riastrad ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 3013 1.1 riastrad possible_crtcs, plane_funcs, 3014 1.1 riastrad formats, num_formats, modifiers, 3015 1.1 riastrad plane_type, 3016 1.1 riastrad "plane %d%c", plane_id + 1, 3017 1.1 riastrad pipe_name(pipe)); 3018 1.1 riastrad if (ret) 3019 1.1 riastrad goto fail; 3020 1.1 riastrad 3021 1.1 riastrad supported_rotations = 3022 1.1 riastrad DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | 3023 1.1 riastrad DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; 3024 1.1 riastrad 3025 1.1 riastrad if (INTEL_GEN(dev_priv) >= 10) 3026 1.1 riastrad supported_rotations |= DRM_MODE_REFLECT_X; 3027 1.1 riastrad 3028 1.1 riastrad drm_plane_create_rotation_property(&plane->base, 3029 1.1 riastrad DRM_MODE_ROTATE_0, 3030 1.1 riastrad supported_rotations); 3031 1.1 riastrad 3032 1.1 riastrad drm_plane_create_color_properties(&plane->base, 3033 1.1 riastrad BIT(DRM_COLOR_YCBCR_BT601) | 3034 1.1 riastrad BIT(DRM_COLOR_YCBCR_BT709), 3035 1.1 riastrad BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 3036 1.1 riastrad BIT(DRM_COLOR_YCBCR_FULL_RANGE), 3037 1.1 riastrad DRM_COLOR_YCBCR_BT709, 3038 1.1 riastrad DRM_COLOR_YCBCR_LIMITED_RANGE); 3039 1.1 riastrad 3040 1.1 riastrad drm_plane_create_alpha_property(&plane->base); 3041 1.1 riastrad drm_plane_create_blend_mode_property(&plane->base, 3042 1.1 riastrad BIT(DRM_MODE_BLEND_PIXEL_NONE) | 3043 1.1 riastrad BIT(DRM_MODE_BLEND_PREMULTI) | 3044 1.1 riastrad BIT(DRM_MODE_BLEND_COVERAGE)); 3045 1.1 riastrad 3046 1.1 riastrad drm_plane_create_zpos_immutable_property(&plane->base, plane_id); 3047 1.1 riastrad 3048 1.1 riastrad drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 3049 1.1 riastrad 3050 1.1 riastrad return plane; 3051 1.1 riastrad 3052 1.1 riastrad fail: 3053 1.1 riastrad intel_plane_free(plane); 3054 1.1 riastrad 3055 1.1 riastrad return ERR_PTR(ret); 3056 1.1 riastrad } 3057 1.1 riastrad 3058 1.1 riastrad struct intel_plane * 3059 1.1 riastrad intel_sprite_plane_create(struct drm_i915_private *dev_priv, 3060 1.1 riastrad enum pipe pipe, int sprite) 3061 1.1 riastrad { 3062 1.1 riastrad struct intel_plane *plane; 3063 1.1 riastrad const struct drm_plane_funcs *plane_funcs; 3064 1.1 riastrad unsigned long possible_crtcs; 3065 1.1 riastrad unsigned int supported_rotations; 3066 1.1 riastrad const u64 *modifiers; 3067 1.1 riastrad const u32 *formats; 3068 1.1 riastrad int num_formats; 3069 1.1 riastrad int ret, zpos; 3070 1.1 riastrad 3071 1.1 riastrad if (INTEL_GEN(dev_priv) >= 9) 3072 1.1 riastrad return skl_universal_plane_create(dev_priv, pipe, 3073 1.1 riastrad PLANE_SPRITE0 + sprite); 3074 1.1 riastrad 3075 1.1 riastrad plane = intel_plane_alloc(); 3076 1.1 riastrad if (IS_ERR(plane)) 3077 1.1 riastrad return plane; 3078 1.1 riastrad 3079 1.1 riastrad if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 3080 1.1 riastrad plane->max_stride = i9xx_plane_max_stride; 3081 1.1 riastrad plane->update_plane = vlv_update_plane; 3082 1.1 riastrad plane->disable_plane = vlv_disable_plane; 3083 1.1 riastrad plane->get_hw_state = vlv_plane_get_hw_state; 3084 1.1 riastrad plane->check_plane = vlv_sprite_check; 3085 1.1 riastrad plane->min_cdclk = vlv_plane_min_cdclk; 3086 1.1 riastrad 3087 1.1 riastrad if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 3088 1.1 riastrad formats = chv_pipe_b_sprite_formats; 3089 1.1 riastrad num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats); 3090 1.1 riastrad } else { 3091 1.1 riastrad formats = vlv_plane_formats; 3092 1.1 riastrad num_formats = ARRAY_SIZE(vlv_plane_formats); 3093 1.1 riastrad } 3094 1.1 riastrad modifiers = i9xx_plane_format_modifiers; 3095 1.1 riastrad 3096 1.1 riastrad plane_funcs = &vlv_sprite_funcs; 3097 1.1 riastrad } else if (INTEL_GEN(dev_priv) >= 7) { 3098 1.1 riastrad plane->max_stride = g4x_sprite_max_stride; 3099 1.1 riastrad plane->update_plane = ivb_update_plane; 3100 1.1 riastrad plane->disable_plane = ivb_disable_plane; 3101 1.1 riastrad plane->get_hw_state = ivb_plane_get_hw_state; 3102 1.1 riastrad plane->check_plane = g4x_sprite_check; 3103 1.1 riastrad 3104 1.1 riastrad if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) 3105 1.1 riastrad plane->min_cdclk = hsw_plane_min_cdclk; 3106 1.1 riastrad else 3107 1.1 riastrad plane->min_cdclk = ivb_sprite_min_cdclk; 3108 1.1 riastrad 3109 1.1 riastrad formats = snb_plane_formats; 3110 1.1 riastrad num_formats = ARRAY_SIZE(snb_plane_formats); 3111 1.1 riastrad modifiers = i9xx_plane_format_modifiers; 3112 1.1 riastrad 3113 1.1 riastrad plane_funcs = &snb_sprite_funcs; 3114 1.1 riastrad } else { 3115 1.1 riastrad plane->max_stride = g4x_sprite_max_stride; 3116 1.1 riastrad plane->update_plane = g4x_update_plane; 3117 1.1 riastrad plane->disable_plane = g4x_disable_plane; 3118 1.1 riastrad plane->get_hw_state = g4x_plane_get_hw_state; 3119 1.1 riastrad plane->check_plane = g4x_sprite_check; 3120 1.1 riastrad plane->min_cdclk = g4x_sprite_min_cdclk; 3121 1.1 riastrad 3122 1.1 riastrad modifiers = i9xx_plane_format_modifiers; 3123 1.1 riastrad if (IS_GEN(dev_priv, 6)) { 3124 1.1 riastrad formats = snb_plane_formats; 3125 1.1 riastrad num_formats = ARRAY_SIZE(snb_plane_formats); 3126 1.1 riastrad 3127 1.1 riastrad plane_funcs = &snb_sprite_funcs; 3128 1.1 riastrad } else { 3129 1.1 riastrad formats = g4x_plane_formats; 3130 1.1 riastrad num_formats = ARRAY_SIZE(g4x_plane_formats); 3131 1.1 riastrad 3132 1.1 riastrad plane_funcs = &g4x_sprite_funcs; 3133 1.1 riastrad } 3134 1.1 riastrad } 3135 1.1 riastrad 3136 1.1 riastrad if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { 3137 1.1 riastrad supported_rotations = 3138 1.1 riastrad DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | 3139 1.1 riastrad DRM_MODE_REFLECT_X; 3140 1.1 riastrad } else { 3141 1.1 riastrad supported_rotations = 3142 1.1 riastrad DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; 3143 1.1 riastrad } 3144 1.1 riastrad 3145 1.1 riastrad plane->pipe = pipe; 3146 1.1 riastrad plane->id = PLANE_SPRITE0 + sprite; 3147 1.1 riastrad plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id); 3148 1.1 riastrad 3149 1.1 riastrad possible_crtcs = BIT(pipe); 3150 1.1 riastrad 3151 1.1 riastrad ret = drm_universal_plane_init(&dev_priv->drm, &plane->base, 3152 1.1 riastrad possible_crtcs, plane_funcs, 3153 1.1 riastrad formats, num_formats, modifiers, 3154 1.1 riastrad DRM_PLANE_TYPE_OVERLAY, 3155 1.1 riastrad "sprite %c", sprite_name(pipe, sprite)); 3156 1.1 riastrad if (ret) 3157 1.1 riastrad goto fail; 3158 1.1 riastrad 3159 1.1 riastrad drm_plane_create_rotation_property(&plane->base, 3160 1.1 riastrad DRM_MODE_ROTATE_0, 3161 1.1 riastrad supported_rotations); 3162 1.1 riastrad 3163 1.1 riastrad drm_plane_create_color_properties(&plane->base, 3164 1.1 riastrad BIT(DRM_COLOR_YCBCR_BT601) | 3165 1.1 riastrad BIT(DRM_COLOR_YCBCR_BT709), 3166 1.1 riastrad BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 3167 1.1 riastrad BIT(DRM_COLOR_YCBCR_FULL_RANGE), 3168 1.1 riastrad DRM_COLOR_YCBCR_BT709, 3169 1.1 riastrad DRM_COLOR_YCBCR_LIMITED_RANGE); 3170 1.1 riastrad 3171 1.1 riastrad zpos = sprite + 1; 3172 1.1 riastrad drm_plane_create_zpos_immutable_property(&plane->base, zpos); 3173 1.1 riastrad 3174 1.1 riastrad drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 3175 1.1 riastrad 3176 1.1 riastrad return plane; 3177 1.1 riastrad 3178 1.1 riastrad fail: 3179 1.1 riastrad intel_plane_free(plane); 3180 1.1 riastrad 3181 1.1 riastrad return ERR_PTR(ret); 3182 1.1 riastrad } 3183