2 * Copyright © 2011 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Jesse Barnes <jbarnes@virtuousgeek.org>
26 * New plane/sprite handling.
28 * The older chips had a separate interface for programming plane related
29 * registers; newer ones are much simpler and we can use the new DRM plane
33 #include <drm/drm_atomic.h>
34 #include <drm/drm_atomic_helper.h>
35 #include <drm/drm_color_mgmt.h>
36 #include <drm/drm_crtc.h>
37 #include <drm/drm_damage_helper.h>
38 #include <drm/drm_fourcc.h>
39 #include <drm/drm_plane_helper.h>
40 #include <drm/drm_rect.h>
43 #include "i915_trace.h"
44 #include "i915_vgpu.h"
45 #include "intel_atomic_plane.h"
46 #include "intel_display_types.h"
47 #include "intel_frontbuffer.h"
49 #include "intel_psr.h"
50 #include "intel_dsi.h"
51 #include "intel_sprite.h"
53 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
57 if (!adjusted_mode->crtc_htotal)
60 return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
61 1000 * adjusted_mode->crtc_htotal);
64 /* FIXME: We should instead only take spinlocks once for the entire update
65 * instead of once per mmio. */
66 #if IS_ENABLED(CONFIG_PROVE_LOCKING)
67 #define VBLANK_EVASION_TIME_US 250
69 #define VBLANK_EVASION_TIME_US 100
73 * intel_pipe_update_start() - start update of a set of display registers
74 * @new_crtc_state: the new crtc state
76 * Mark the start of an update to pipe registers that should be updated
77 * atomically regarding vblank. If the next vblank will happens within
78 * the next 100 us, this function waits until the vblank passes.
80 * After a successful call to this function, interrupts will be disabled
81 * until a subsequent call to intel_pipe_update_end(). That is done to
82 * avoid random delays.
84 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
86 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
87 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
88 const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode;
89 long timeout = msecs_to_jiffies_timeout(1);
90 int scanline, min, max, vblank_start;
91 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
92 bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
93 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
97 if (new_crtc_state->uapi.async_flip)
100 vblank_start = adjusted_mode->crtc_vblank_start;
101 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
102 vblank_start = DIV_ROUND_UP(vblank_start, 2);
104 /* FIXME needs to be calibrated sensibly */
105 min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
106 VBLANK_EVASION_TIME_US);
107 max = vblank_start - 1;
109 if (min <= 0 || max <= 0)
112 if (drm_WARN_ON(&dev_priv->drm, drm_crtc_vblank_get(&crtc->base)))
116 * Wait for psr to idle out after enabling the VBL interrupts
117 * VBL interrupts will start the PSR exit and prevent a PSR
120 if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
121 drm_err(&dev_priv->drm,
122 "PSR idle timed out 0x%x, atomic update may fail\n",
127 crtc->debug.min_vbl = min;
128 crtc->debug.max_vbl = max;
129 trace_intel_pipe_update_start(crtc);
133 * prepare_to_wait() has a memory barrier, which guarantees
134 * other CPUs can see the task state update by the time we
137 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
139 scanline = intel_get_crtc_scanline(crtc);
140 if (scanline < min || scanline > max)
144 drm_err(&dev_priv->drm,
145 "Potential atomic update failure on pipe %c\n",
146 pipe_name(crtc->pipe));
152 timeout = schedule_timeout(timeout);
157 finish_wait(wq, &wait);
159 drm_crtc_vblank_put(&crtc->base);
162 * On VLV/CHV DSI the scanline counter would appear to
163 * increment approx. 1/3 of a scanline before start of vblank.
164 * The registers still get latched at start of vblank however.
165 * This means we must not write any registers on the first
166 * line of vblank (since not the whole line is actually in
167 * vblank). And unfortunately we can't use the interrupt to
168 * wait here since it will fire too soon. We could use the
169 * frame start interrupt instead since it will fire after the
170 * critical scanline, but that would require more changes
171 * in the interrupt code. So for now we'll just do the nasty
172 * thing and poll for the bad scanline to pass us by.
174 * FIXME figure out if BXT+ DSI suffers from this as well
176 while (need_vlv_dsi_wa && scanline == vblank_start)
177 scanline = intel_get_crtc_scanline(crtc);
179 crtc->debug.scanline_start = scanline;
180 crtc->debug.start_vbl_time = ktime_get();
181 crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
183 trace_intel_pipe_update_vblank_evaded(crtc);
191 * intel_pipe_update_end() - end update of a set of display registers
192 * @new_crtc_state: the new crtc state
194 * Mark the end of an update started with intel_pipe_update_start(). This
195 * re-enables interrupts and verifies the update was actually completed
198 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
200 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
201 enum pipe pipe = crtc->pipe;
202 int scanline_end = intel_get_crtc_scanline(crtc);
203 u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
204 ktime_t end_vbl_time = ktime_get();
205 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
207 if (new_crtc_state->uapi.async_flip)
210 trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end);
213 * Incase of mipi dsi command mode, we need to set frame update
214 * request for every commit.
216 if (INTEL_GEN(dev_priv) >= 11 &&
217 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI))
218 icl_dsi_frame_update(new_crtc_state);
220 /* We're still in the vblank-evade critical section, this can't race.
221 * Would be slightly nice to just grab the vblank count and arm the
222 * event outside of the critical section - the spinlock might spin for a
224 if (new_crtc_state->uapi.event) {
225 drm_WARN_ON(&dev_priv->drm,
226 drm_crtc_vblank_get(&crtc->base) != 0);
228 spin_lock(&crtc->base.dev->event_lock);
229 drm_crtc_arm_vblank_event(&crtc->base,
230 new_crtc_state->uapi.event);
231 spin_unlock(&crtc->base.dev->event_lock);
233 new_crtc_state->uapi.event = NULL;
238 if (intel_vgpu_active(dev_priv))
241 if (crtc->debug.start_vbl_count &&
242 crtc->debug.start_vbl_count != end_vbl_count) {
243 drm_err(&dev_priv->drm,
244 "Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n",
245 pipe_name(pipe), crtc->debug.start_vbl_count,
247 ktime_us_delta(end_vbl_time,
248 crtc->debug.start_vbl_time),
249 crtc->debug.min_vbl, crtc->debug.max_vbl,
250 crtc->debug.scanline_start, scanline_end);
252 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
253 else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
254 VBLANK_EVASION_TIME_US)
255 drm_warn(&dev_priv->drm,
256 "Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
258 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
259 VBLANK_EVASION_TIME_US);
263 int intel_plane_check_stride(const struct intel_plane_state *plane_state)
265 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
266 const struct drm_framebuffer *fb = plane_state->hw.fb;
267 unsigned int rotation = plane_state->hw.rotation;
268 u32 stride, max_stride;
271 * We ignore stride for all invisible planes that
272 * can be remapped. Otherwise we could end up
273 * with a false positive when the remapping didn't
274 * kick in due the plane being invisible.
276 if (intel_plane_can_remap(plane_state) &&
277 !plane_state->uapi.visible)
280 /* FIXME other color planes? */
281 stride = plane_state->color_plane[0].stride;
282 max_stride = plane->max_stride(plane, fb->format->format,
283 fb->modifier, rotation);
285 if (stride > max_stride) {
286 DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
288 plane->base.base.id, plane->base.name, max_stride);
295 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
297 const struct drm_framebuffer *fb = plane_state->hw.fb;
298 struct drm_rect *src = &plane_state->uapi.src;
299 u32 src_x, src_y, src_w, src_h, hsub, vsub;
300 bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation);
303 * FIXME hsub/vsub vs. block size is a mess. Pre-tgl CCS
304 * abuses hsub/vsub so we can't use them here. But as they
305 * are limited to 32bpp RGB formats we don't actually need
308 if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
309 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)
313 * Hardware doesn't handle subpixel coordinates.
314 * Adjust to (macro)pixel boundary, but be careful not to
315 * increase the source viewport size, because that could
316 * push the downscaling factor out of bounds.
318 src_x = src->x1 >> 16;
319 src_w = drm_rect_width(src) >> 16;
320 src_y = src->y1 >> 16;
321 src_h = drm_rect_height(src) >> 16;
323 drm_rect_init(src, src_x << 16, src_y << 16,
324 src_w << 16, src_h << 16);
326 if (fb->format->format == DRM_FORMAT_RGB565 && rotated) {
330 hsub = fb->format->hsub;
331 vsub = fb->format->vsub;
335 hsub = vsub = max(hsub, vsub);
337 if (src_x % hsub || src_w % hsub) {
338 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
339 src_x, src_w, hsub, yesno(rotated));
343 if (src_y % vsub || src_h % vsub) {
344 DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
345 src_y, src_h, vsub, yesno(rotated));
352 static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
354 if (IS_ROCKETLAKE(i915))
355 return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3);
357 return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5);
360 bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
361 enum plane_id plane_id)
363 return INTEL_GEN(dev_priv) >= 11 &&
364 icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id);
367 bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
369 return INTEL_GEN(dev_priv) >= 11 &&
370 icl_hdr_plane_mask() & BIT(plane_id);
374 skl_plane_ratio(const struct intel_crtc_state *crtc_state,
375 const struct intel_plane_state *plane_state,
376 unsigned int *num, unsigned int *den)
378 struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
379 const struct drm_framebuffer *fb = plane_state->hw.fb;
381 if (fb->format->cpp[0] == 8) {
382 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
395 static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
396 const struct intel_plane_state *plane_state)
398 struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
399 unsigned int num, den;
400 unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
402 skl_plane_ratio(crtc_state, plane_state, &num, &den);
404 /* two pixels per clock on glk+ */
405 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
408 return DIV_ROUND_UP(pixel_rate * num, den);
411 static int skl_plane_max_width(const struct drm_framebuffer *fb,
413 unsigned int rotation)
415 int cpp = fb->format->cpp[color_plane];
417 switch (fb->modifier) {
418 case DRM_FORMAT_MOD_LINEAR:
419 case I915_FORMAT_MOD_X_TILED:
421 * Validated limit is 4k, but has 5k should
422 * work apart from the following features:
423 * - Ytile (already limited to 4k)
424 * - FP16 (already limited to 4k)
425 * - render compression (already limited to 4k)
426 * - KVMR sprite and cursor (don't care)
427 * - horizontal panning (TODO verify this)
428 * - pipe and plane scaling (TODO verify this)
434 case I915_FORMAT_MOD_Y_TILED_CCS:
435 case I915_FORMAT_MOD_Yf_TILED_CCS:
436 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
437 /* FIXME AUX plane? */
438 case I915_FORMAT_MOD_Y_TILED:
439 case I915_FORMAT_MOD_Yf_TILED:
445 MISSING_CASE(fb->modifier);
450 static int glk_plane_max_width(const struct drm_framebuffer *fb,
452 unsigned int rotation)
454 int cpp = fb->format->cpp[color_plane];
456 switch (fb->modifier) {
457 case DRM_FORMAT_MOD_LINEAR:
458 case I915_FORMAT_MOD_X_TILED:
463 case I915_FORMAT_MOD_Y_TILED_CCS:
464 case I915_FORMAT_MOD_Yf_TILED_CCS:
465 /* FIXME AUX plane? */
466 case I915_FORMAT_MOD_Y_TILED:
467 case I915_FORMAT_MOD_Yf_TILED:
473 MISSING_CASE(fb->modifier);
478 static int icl_plane_min_width(const struct drm_framebuffer *fb,
480 unsigned int rotation)
482 /* Wa_14011264657, Wa_14011050563: gen11+ */
483 switch (fb->format->format) {
486 case DRM_FORMAT_RGB565:
488 case DRM_FORMAT_XRGB8888:
489 case DRM_FORMAT_XBGR8888:
490 case DRM_FORMAT_ARGB8888:
491 case DRM_FORMAT_ABGR8888:
492 case DRM_FORMAT_XRGB2101010:
493 case DRM_FORMAT_XBGR2101010:
494 case DRM_FORMAT_ARGB2101010:
495 case DRM_FORMAT_ABGR2101010:
496 case DRM_FORMAT_XVYU2101010:
497 case DRM_FORMAT_Y212:
498 case DRM_FORMAT_Y216:
500 case DRM_FORMAT_NV12:
502 case DRM_FORMAT_P010:
503 case DRM_FORMAT_P012:
504 case DRM_FORMAT_P016:
506 case DRM_FORMAT_XRGB16161616F:
507 case DRM_FORMAT_XBGR16161616F:
508 case DRM_FORMAT_ARGB16161616F:
509 case DRM_FORMAT_ABGR16161616F:
510 case DRM_FORMAT_XVYU12_16161616:
511 case DRM_FORMAT_XVYU16161616:
518 static int icl_plane_max_width(const struct drm_framebuffer *fb,
520 unsigned int rotation)
525 static int skl_plane_max_height(const struct drm_framebuffer *fb,
527 unsigned int rotation)
532 static int icl_plane_max_height(const struct drm_framebuffer *fb,
534 unsigned int rotation)
540 skl_plane_max_stride(struct intel_plane *plane,
541 u32 pixel_format, u64 modifier,
542 unsigned int rotation)
544 const struct drm_format_info *info = drm_format_info(pixel_format);
545 int cpp = info->cpp[0];
548 * "The stride in bytes must not exceed the
549 * of the size of 8K pixels and 32K bytes."
551 if (drm_rotation_90_or_270(rotation))
552 return min(8192, 32768 / cpp);
554 return min(8192 * cpp, 32768);
558 skl_program_scaler(struct intel_plane *plane,
559 const struct intel_crtc_state *crtc_state,
560 const struct intel_plane_state *plane_state)
562 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
563 const struct drm_framebuffer *fb = plane_state->hw.fb;
564 enum pipe pipe = plane->pipe;
565 int scaler_id = plane_state->scaler_id;
566 const struct intel_scaler *scaler =
567 &crtc_state->scaler_state.scalers[scaler_id];
568 int crtc_x = plane_state->uapi.dst.x1;
569 int crtc_y = plane_state->uapi.dst.y1;
570 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
571 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
572 u16 y_hphase, uv_rgb_hphase;
573 u16 y_vphase, uv_rgb_vphase;
577 hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
578 &plane_state->uapi.dst,
580 vscale = drm_rect_calc_vscale(&plane_state->uapi.src,
581 &plane_state->uapi.dst,
584 /* TODO: handle sub-pixel coordinates */
585 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
586 !icl_is_hdr_plane(dev_priv, plane->id)) {
587 y_hphase = skl_scaler_calc_phase(1, hscale, false);
588 y_vphase = skl_scaler_calc_phase(1, vscale, false);
590 /* MPEG2 chroma siting convention */
591 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
592 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
598 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
599 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
602 ps_ctrl = skl_scaler_get_filter_select(plane_state->hw.scaling_filter, 0);
603 ps_ctrl |= PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode;
605 skl_scaler_setup_filter(dev_priv, pipe, scaler_id, 0,
606 plane_state->hw.scaling_filter);
608 intel_de_write_fw(dev_priv, SKL_PS_CTRL(pipe, scaler_id), ps_ctrl);
609 intel_de_write_fw(dev_priv, SKL_PS_VPHASE(pipe, scaler_id),
610 PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
611 intel_de_write_fw(dev_priv, SKL_PS_HPHASE(pipe, scaler_id),
612 PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
613 intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(pipe, scaler_id),
614 (crtc_x << 16) | crtc_y);
615 intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(pipe, scaler_id),
616 (crtc_w << 16) | crtc_h);
619 /* Preoffset values for YUV to RGB Conversion */
620 #define PREOFF_YUV_TO_RGB_HI 0x1800
621 #define PREOFF_YUV_TO_RGB_ME 0x1F00
622 #define PREOFF_YUV_TO_RGB_LO 0x1800
624 #define ROFF(x) (((x) & 0xffff) << 16)
625 #define GOFF(x) (((x) & 0xffff) << 0)
626 #define BOFF(x) (((x) & 0xffff) << 16)
629 icl_program_input_csc(struct intel_plane *plane,
630 const struct intel_crtc_state *crtc_state,
631 const struct intel_plane_state *plane_state)
633 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
634 enum pipe pipe = plane->pipe;
635 enum plane_id plane_id = plane->id;
637 static const u16 input_csc_matrix[][9] = {
639 * BT.601 full range YCbCr -> full range RGB
640 * The matrix required is :
641 * [1.000, 0.000, 1.371,
642 * 1.000, -0.336, -0.698,
643 * 1.000, 1.732, 0.0000]
645 [DRM_COLOR_YCBCR_BT601] = {
647 0x8B28, 0x7800, 0x9AC0,
651 * BT.709 full range YCbCr -> full range RGB
652 * The matrix required is :
653 * [1.000, 0.000, 1.574,
654 * 1.000, -0.187, -0.468,
655 * 1.000, 1.855, 0.0000]
657 [DRM_COLOR_YCBCR_BT709] = {
659 0x9EF8, 0x7800, 0xAC00,
663 * BT.2020 full range YCbCr -> full range RGB
664 * The matrix required is :
665 * [1.000, 0.000, 1.474,
666 * 1.000, -0.1645, -0.5713,
667 * 1.000, 1.8814, 0.0000]
669 [DRM_COLOR_YCBCR_BT2020] = {
671 0x8928, 0x7800, 0xAA88,
676 /* Matrix for Limited Range to Full Range Conversion */
677 static const u16 input_csc_matrix_lr[][9] = {
679 * BT.601 Limted range YCbCr -> full range RGB
680 * The matrix required is :
681 * [1.164384, 0.000, 1.596027,
682 * 1.164384, -0.39175, -0.812813,
683 * 1.164384, 2.017232, 0.0000]
685 [DRM_COLOR_YCBCR_BT601] = {
687 0x8D00, 0x7950, 0x9C88,
691 * BT.709 Limited range YCbCr -> full range RGB
692 * The matrix required is :
693 * [1.164384, 0.000, 1.792741,
694 * 1.164384, -0.213249, -0.532909,
695 * 1.164384, 2.112402, 0.0000]
697 [DRM_COLOR_YCBCR_BT709] = {
699 0x8888, 0x7950, 0xADA8,
703 * BT.2020 Limited range YCbCr -> full range RGB
704 * The matrix required is :
705 * [1.164, 0.000, 1.678,
706 * 1.164, -0.1873, -0.6504,
707 * 1.164, 2.1417, 0.0000]
709 [DRM_COLOR_YCBCR_BT2020] = {
711 0x8A68, 0x7950, 0xAC00,
717 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
718 csc = input_csc_matrix[plane_state->hw.color_encoding];
720 csc = input_csc_matrix_lr[plane_state->hw.color_encoding];
722 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
723 ROFF(csc[0]) | GOFF(csc[1]));
724 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
726 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
727 ROFF(csc[3]) | GOFF(csc[4]));
728 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
730 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
731 ROFF(csc[6]) | GOFF(csc[7]));
732 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
735 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
736 PREOFF_YUV_TO_RGB_HI);
737 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
738 intel_de_write_fw(dev_priv,
739 PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
742 intel_de_write_fw(dev_priv,
743 PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
744 PREOFF_YUV_TO_RGB_ME);
745 intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
746 PREOFF_YUV_TO_RGB_LO);
747 intel_de_write_fw(dev_priv,
748 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
749 intel_de_write_fw(dev_priv,
750 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
751 intel_de_write_fw(dev_priv,
752 PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
756 skl_plane_async_flip(struct intel_plane *plane,
757 const struct intel_crtc_state *crtc_state,
758 const struct intel_plane_state *plane_state)
760 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
761 unsigned long irqflags;
762 enum plane_id plane_id = plane->id;
763 enum pipe pipe = plane->pipe;
764 u32 surf_addr = plane_state->color_plane[0].offset;
765 u32 plane_ctl = plane_state->ctl;
767 plane_ctl |= skl_plane_ctl_crtc(crtc_state);
769 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
771 intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
772 intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
773 intel_plane_ggtt_offset(plane_state) + surf_addr);
775 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
779 skl_program_plane(struct intel_plane *plane,
780 const struct intel_crtc_state *crtc_state,
781 const struct intel_plane_state *plane_state,
784 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
785 enum plane_id plane_id = plane->id;
786 enum pipe pipe = plane->pipe;
787 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
788 u32 surf_addr = plane_state->color_plane[color_plane].offset;
789 u32 stride = skl_plane_stride(plane_state, color_plane);
790 const struct drm_framebuffer *fb = plane_state->hw.fb;
791 int aux_plane = intel_main_to_aux_plane(fb, color_plane);
792 int crtc_x = plane_state->uapi.dst.x1;
793 int crtc_y = plane_state->uapi.dst.y1;
794 u32 x = plane_state->color_plane[color_plane].x;
795 u32 y = plane_state->color_plane[color_plane].y;
796 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
797 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
798 u8 alpha = plane_state->hw.alpha >> 8;
799 u32 plane_color_ctl = 0, aux_dist = 0;
800 unsigned long irqflags;
802 u32 plane_ctl = plane_state->ctl;
804 plane_ctl |= skl_plane_ctl_crtc(crtc_state);
806 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
807 plane_color_ctl = plane_state->color_ctl |
808 glk_plane_color_ctl_crtc(crtc_state);
810 /* Sizes are 0 based */
814 keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
816 keymsk = key->channel_mask & 0x7ffffff;
818 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
820 /* The scaler will handle the output position */
821 if (plane_state->scaler_id >= 0) {
827 aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr;
829 if (INTEL_GEN(dev_priv) < 12)
830 aux_dist |= skl_plane_stride(plane_state, aux_plane);
833 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
835 intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride);
836 intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
837 (crtc_y << 16) | crtc_x);
838 intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
839 (src_h << 16) | src_w);
841 intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist);
843 if (icl_is_hdr_plane(dev_priv, plane_id))
844 intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
845 plane_state->cus_ctl);
847 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
848 intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id),
851 if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
852 icl_program_input_csc(plane, crtc_state, plane_state);
854 skl_write_plane_wm(plane, crtc_state);
856 intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id),
858 intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk);
859 intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax);
861 intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
864 if (INTEL_GEN(dev_priv) < 11)
865 intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
866 (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x);
868 if (!drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
869 intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane);
872 * The control register self-arms if the plane was previously
873 * disabled. Try to make the plane enable atomic by writing
874 * the control register just before the surface register.
876 intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
877 intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
878 intel_plane_ggtt_offset(plane_state) + surf_addr);
880 if (plane_state->scaler_id >= 0)
881 skl_program_scaler(plane, crtc_state, plane_state);
883 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
887 skl_update_plane(struct intel_plane *plane,
888 const struct intel_crtc_state *crtc_state,
889 const struct intel_plane_state *plane_state)
893 if (plane_state->planar_linked_plane && !plane_state->planar_slave)
894 /* Program the UV plane on planar master */
897 skl_program_plane(plane, crtc_state, plane_state, color_plane);
900 skl_disable_plane(struct intel_plane *plane,
901 const struct intel_crtc_state *crtc_state)
903 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
904 enum plane_id plane_id = plane->id;
905 enum pipe pipe = plane->pipe;
906 unsigned long irqflags;
908 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
910 if (icl_is_hdr_plane(dev_priv, plane_id))
911 intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
913 skl_write_plane_wm(plane, crtc_state);
915 intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
916 intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
918 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
922 skl_plane_get_hw_state(struct intel_plane *plane,
925 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
926 enum intel_display_power_domain power_domain;
927 enum plane_id plane_id = plane->id;
928 intel_wakeref_t wakeref;
931 power_domain = POWER_DOMAIN_PIPE(plane->pipe);
932 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
936 ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
940 intel_display_power_put(dev_priv, power_domain, wakeref);
945 static void i9xx_plane_linear_gamma(u16 gamma[8])
947 /* The points are not evenly spaced. */
948 static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 };
951 for (i = 0; i < 8; i++)
952 gamma[i] = (in[i] << 8) / 32;
956 chv_update_csc(const struct intel_plane_state *plane_state)
958 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
959 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
960 const struct drm_framebuffer *fb = plane_state->hw.fb;
961 enum plane_id plane_id = plane->id;
963 * |r| | c0 c1 c2 | |cr|
964 * |g| = | c3 c4 c5 | x |y |
965 * |b| | c6 c7 c8 | |cb|
967 * Coefficients are s3.12.
969 * Cb and Cr apparently come in as signed already, and
970 * we always get full range data in on account of CLRC0/1.
972 static const s16 csc_matrix[][9] = {
973 /* BT.601 full range YCbCr -> full range RGB */
974 [DRM_COLOR_YCBCR_BT601] = {
979 /* BT.709 full range YCbCr -> full range RGB */
980 [DRM_COLOR_YCBCR_BT709] = {
986 const s16 *csc = csc_matrix[plane_state->hw.color_encoding];
988 /* Seems RGB data bypasses the CSC always */
989 if (!fb->format->is_yuv)
992 intel_de_write_fw(dev_priv, SPCSCYGOFF(plane_id),
993 SPCSC_OOFF(0) | SPCSC_IOFF(0));
994 intel_de_write_fw(dev_priv, SPCSCCBOFF(plane_id),
995 SPCSC_OOFF(0) | SPCSC_IOFF(0));
996 intel_de_write_fw(dev_priv, SPCSCCROFF(plane_id),
997 SPCSC_OOFF(0) | SPCSC_IOFF(0));
999 intel_de_write_fw(dev_priv, SPCSCC01(plane_id),
1000 SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
1001 intel_de_write_fw(dev_priv, SPCSCC23(plane_id),
1002 SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
1003 intel_de_write_fw(dev_priv, SPCSCC45(plane_id),
1004 SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
1005 intel_de_write_fw(dev_priv, SPCSCC67(plane_id),
1006 SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
1007 intel_de_write_fw(dev_priv, SPCSCC8(plane_id), SPCSC_C0(csc[8]));
1009 intel_de_write_fw(dev_priv, SPCSCYGICLAMP(plane_id),
1010 SPCSC_IMAX(1023) | SPCSC_IMIN(0));
1011 intel_de_write_fw(dev_priv, SPCSCCBICLAMP(plane_id),
1012 SPCSC_IMAX(512) | SPCSC_IMIN(-512));
1013 intel_de_write_fw(dev_priv, SPCSCCRICLAMP(plane_id),
1014 SPCSC_IMAX(512) | SPCSC_IMIN(-512));
1016 intel_de_write_fw(dev_priv, SPCSCYGOCLAMP(plane_id),
1017 SPCSC_OMAX(1023) | SPCSC_OMIN(0));
1018 intel_de_write_fw(dev_priv, SPCSCCBOCLAMP(plane_id),
1019 SPCSC_OMAX(1023) | SPCSC_OMIN(0));
1020 intel_de_write_fw(dev_priv, SPCSCCROCLAMP(plane_id),
1021 SPCSC_OMAX(1023) | SPCSC_OMIN(0));
1028 vlv_update_clrc(const struct intel_plane_state *plane_state)
1030 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1031 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1032 const struct drm_framebuffer *fb = plane_state->hw.fb;
1033 enum pipe pipe = plane->pipe;
1034 enum plane_id plane_id = plane->id;
1035 int contrast, brightness, sh_scale, sh_sin, sh_cos;
1037 if (fb->format->is_yuv &&
1038 plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
1040 * Expand limited range to full range:
1041 * Contrast is applied first and is used to expand Y range.
1042 * Brightness is applied second and is used to remove the
1043 * offset from Y. Saturation/hue is used to expand CbCr range.
1045 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
1046 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
1047 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
1048 sh_sin = SIN_0 * sh_scale;
1049 sh_cos = COS_0 * sh_scale;
1051 /* Pass-through everything. */
1055 sh_sin = SIN_0 * sh_scale;
1056 sh_cos = COS_0 * sh_scale;
1059 /* FIXME these register are single buffered :( */
1060 intel_de_write_fw(dev_priv, SPCLRC0(pipe, plane_id),
1061 SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
1062 intel_de_write_fw(dev_priv, SPCLRC1(pipe, plane_id),
1063 SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
1067 vlv_plane_ratio(const struct intel_crtc_state *crtc_state,
1068 const struct intel_plane_state *plane_state,
1069 unsigned int *num, unsigned int *den)
1071 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1072 const struct drm_framebuffer *fb = plane_state->hw.fb;
1073 unsigned int cpp = fb->format->cpp[0];
1076 * VLV bspec only considers cases where all three planes are
1077 * enabled, and cases where the primary and one sprite is enabled.
1078 * Let's assume the case with just two sprites enabled also
1079 * maps to the latter case.
1081 if (hweight8(active_planes) == 3) {
1096 } else if (hweight8(active_planes) == 2) {
1125 int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
1126 const struct intel_plane_state *plane_state)
1128 unsigned int pixel_rate;
1129 unsigned int num, den;
1132 * Note that crtc_state->pixel_rate accounts for both
1133 * horizontal and vertical panel fitter downscaling factors.
1134 * Pre-HSW bspec tells us to only consider the horizontal
1135 * downscaling factor here. We ignore that and just consider
1136 * both for simplicity.
1138 pixel_rate = crtc_state->pixel_rate;
1140 vlv_plane_ratio(crtc_state, plane_state, &num, &den);
1142 return DIV_ROUND_UP(pixel_rate * num, den);
1145 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1149 if (crtc_state->gamma_enable)
1150 sprctl |= SP_GAMMA_ENABLE;
1155 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
1156 const struct intel_plane_state *plane_state)
1158 const struct drm_framebuffer *fb = plane_state->hw.fb;
1159 unsigned int rotation = plane_state->hw.rotation;
1160 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1165 switch (fb->format->format) {
1166 case DRM_FORMAT_YUYV:
1167 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
1169 case DRM_FORMAT_YVYU:
1170 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
1172 case DRM_FORMAT_UYVY:
1173 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
1175 case DRM_FORMAT_VYUY:
1176 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
1179 sprctl |= SP_FORMAT_8BPP;
1181 case DRM_FORMAT_RGB565:
1182 sprctl |= SP_FORMAT_BGR565;
1184 case DRM_FORMAT_XRGB8888:
1185 sprctl |= SP_FORMAT_BGRX8888;
1187 case DRM_FORMAT_ARGB8888:
1188 sprctl |= SP_FORMAT_BGRA8888;
1190 case DRM_FORMAT_XBGR2101010:
1191 sprctl |= SP_FORMAT_RGBX1010102;
1193 case DRM_FORMAT_ABGR2101010:
1194 sprctl |= SP_FORMAT_RGBA1010102;
1196 case DRM_FORMAT_XRGB2101010:
1197 sprctl |= SP_FORMAT_BGRX1010102;
1199 case DRM_FORMAT_ARGB2101010:
1200 sprctl |= SP_FORMAT_BGRA1010102;
1202 case DRM_FORMAT_XBGR8888:
1203 sprctl |= SP_FORMAT_RGBX8888;
1205 case DRM_FORMAT_ABGR8888:
1206 sprctl |= SP_FORMAT_RGBA8888;
1209 MISSING_CASE(fb->format->format);
1213 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
1214 sprctl |= SP_YUV_FORMAT_BT709;
1216 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1219 if (rotation & DRM_MODE_ROTATE_180)
1220 sprctl |= SP_ROTATE_180;
1222 if (rotation & DRM_MODE_REFLECT_X)
1223 sprctl |= SP_MIRROR;
1225 if (key->flags & I915_SET_COLORKEY_SOURCE)
1226 sprctl |= SP_SOURCE_KEY;
1231 static void vlv_update_gamma(const struct intel_plane_state *plane_state)
1233 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1234 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1235 const struct drm_framebuffer *fb = plane_state->hw.fb;
1236 enum pipe pipe = plane->pipe;
1237 enum plane_id plane_id = plane->id;
1241 /* Seems RGB data bypasses the gamma always */
1242 if (!fb->format->is_yuv)
1245 i9xx_plane_linear_gamma(gamma);
1247 /* FIXME these register are single buffered :( */
1248 /* The two end points are implicit (0.0 and 1.0) */
1249 for (i = 1; i < 8 - 1; i++)
1250 intel_de_write_fw(dev_priv, SPGAMC(pipe, plane_id, i - 1),
1251 gamma[i] << 16 | gamma[i] << 8 | gamma[i]);
1255 vlv_update_plane(struct intel_plane *plane,
1256 const struct intel_crtc_state *crtc_state,
1257 const struct intel_plane_state *plane_state)
1259 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1260 enum pipe pipe = plane->pipe;
1261 enum plane_id plane_id = plane->id;
1262 u32 sprsurf_offset = plane_state->color_plane[0].offset;
1264 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1265 int crtc_x = plane_state->uapi.dst.x1;
1266 int crtc_y = plane_state->uapi.dst.y1;
1267 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
1268 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
1269 u32 x = plane_state->color_plane[0].x;
1270 u32 y = plane_state->color_plane[0].y;
1271 unsigned long irqflags;
1274 sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
1276 /* Sizes are 0 based */
1280 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1282 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1284 intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id),
1285 plane_state->color_plane[0].stride);
1286 intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id),
1287 (crtc_y << 16) | crtc_x);
1288 intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id),
1289 (crtc_h << 16) | crtc_w);
1290 intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0);
1292 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
1293 chv_update_csc(plane_state);
1296 intel_de_write_fw(dev_priv, SPKEYMINVAL(pipe, plane_id),
1298 intel_de_write_fw(dev_priv, SPKEYMSK(pipe, plane_id),
1300 intel_de_write_fw(dev_priv, SPKEYMAXVAL(pipe, plane_id),
1304 intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset);
1305 intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id), (y << 16) | x);
1308 * The control register self-arms if the plane was previously
1309 * disabled. Try to make the plane enable atomic by writing
1310 * the control register just before the surface register.
1312 intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), sprctl);
1313 intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id),
1314 intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1316 vlv_update_clrc(plane_state);
1317 vlv_update_gamma(plane_state);
1319 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1323 vlv_disable_plane(struct intel_plane *plane,
1324 const struct intel_crtc_state *crtc_state)
1326 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1327 enum pipe pipe = plane->pipe;
1328 enum plane_id plane_id = plane->id;
1329 unsigned long irqflags;
1331 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1333 intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), 0);
1334 intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 0);
1336 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1340 vlv_plane_get_hw_state(struct intel_plane *plane,
1343 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1344 enum intel_display_power_domain power_domain;
1345 enum plane_id plane_id = plane->id;
1346 intel_wakeref_t wakeref;
1349 power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1350 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1354 ret = intel_de_read(dev_priv, SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
1356 *pipe = plane->pipe;
1358 intel_display_power_put(dev_priv, power_domain, wakeref);
1363 static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state,
1364 const struct intel_plane_state *plane_state,
1365 unsigned int *num, unsigned int *den)
1367 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1368 const struct drm_framebuffer *fb = plane_state->hw.fb;
1369 unsigned int cpp = fb->format->cpp[0];
1371 if (hweight8(active_planes) == 2) {
1400 static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state,
1401 const struct intel_plane_state *plane_state,
1402 unsigned int *num, unsigned int *den)
1404 const struct drm_framebuffer *fb = plane_state->hw.fb;
1405 unsigned int cpp = fb->format->cpp[0];
1427 int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
1428 const struct intel_plane_state *plane_state)
1430 unsigned int pixel_rate;
1431 unsigned int num, den;
1434 * Note that crtc_state->pixel_rate accounts for both
1435 * horizontal and vertical panel fitter downscaling factors.
1436 * Pre-HSW bspec tells us to only consider the horizontal
1437 * downscaling factor here. We ignore that and just consider
1438 * both for simplicity.
1440 pixel_rate = crtc_state->pixel_rate;
1442 ivb_plane_ratio(crtc_state, plane_state, &num, &den);
1444 return DIV_ROUND_UP(pixel_rate * num, den);
1447 static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
1448 const struct intel_plane_state *plane_state)
1450 unsigned int src_w, dst_w, pixel_rate;
1451 unsigned int num, den;
1454 * Note that crtc_state->pixel_rate accounts for both
1455 * horizontal and vertical panel fitter downscaling factors.
1456 * Pre-HSW bspec tells us to only consider the horizontal
1457 * downscaling factor here. We ignore that and just consider
1458 * both for simplicity.
1460 pixel_rate = crtc_state->pixel_rate;
1462 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1463 dst_w = drm_rect_width(&plane_state->uapi.dst);
1466 ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den);
1468 ivb_plane_ratio(crtc_state, plane_state, &num, &den);
1470 /* Horizontal downscaling limits the maximum pixel rate */
1471 dst_w = min(src_w, dst_w);
1473 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w),
1477 static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state,
1478 const struct intel_plane_state *plane_state,
1479 unsigned int *num, unsigned int *den)
1481 u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1482 const struct drm_framebuffer *fb = plane_state->hw.fb;
1483 unsigned int cpp = fb->format->cpp[0];
1485 if (hweight8(active_planes) == 2) {
1510 int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
1511 const struct intel_plane_state *plane_state)
1513 unsigned int pixel_rate = crtc_state->pixel_rate;
1514 unsigned int num, den;
1516 hsw_plane_ratio(crtc_state, plane_state, &num, &den);
1518 return DIV_ROUND_UP(pixel_rate * num, den);
1521 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1525 if (crtc_state->gamma_enable)
1526 sprctl |= SPRITE_GAMMA_ENABLE;
1528 if (crtc_state->csc_enable)
1529 sprctl |= SPRITE_PIPE_CSC_ENABLE;
1534 static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state)
1536 struct drm_i915_private *dev_priv =
1537 to_i915(plane_state->uapi.plane->dev);
1538 const struct drm_framebuffer *fb = plane_state->hw.fb;
1540 return fb->format->cpp[0] == 8 &&
1541 (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv));
1544 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
1545 const struct intel_plane_state *plane_state)
1547 struct drm_i915_private *dev_priv =
1548 to_i915(plane_state->uapi.plane->dev);
1549 const struct drm_framebuffer *fb = plane_state->hw.fb;
1550 unsigned int rotation = plane_state->hw.rotation;
1551 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1554 sprctl = SPRITE_ENABLE;
1556 if (IS_IVYBRIDGE(dev_priv))
1557 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
1559 switch (fb->format->format) {
1560 case DRM_FORMAT_XBGR8888:
1561 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
1563 case DRM_FORMAT_XRGB8888:
1564 sprctl |= SPRITE_FORMAT_RGBX888;
1566 case DRM_FORMAT_XBGR2101010:
1567 sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX;
1569 case DRM_FORMAT_XRGB2101010:
1570 sprctl |= SPRITE_FORMAT_RGBX101010;
1572 case DRM_FORMAT_XBGR16161616F:
1573 sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX;
1575 case DRM_FORMAT_XRGB16161616F:
1576 sprctl |= SPRITE_FORMAT_RGBX161616;
1578 case DRM_FORMAT_YUYV:
1579 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
1581 case DRM_FORMAT_YVYU:
1582 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
1584 case DRM_FORMAT_UYVY:
1585 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
1587 case DRM_FORMAT_VYUY:
1588 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
1591 MISSING_CASE(fb->format->format);
1595 if (!ivb_need_sprite_gamma(plane_state))
1596 sprctl |= SPRITE_INT_GAMMA_DISABLE;
1598 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
1599 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
1601 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1602 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
1604 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1605 sprctl |= SPRITE_TILED;
1607 if (rotation & DRM_MODE_ROTATE_180)
1608 sprctl |= SPRITE_ROTATE_180;
1610 if (key->flags & I915_SET_COLORKEY_DESTINATION)
1611 sprctl |= SPRITE_DEST_KEY;
1612 else if (key->flags & I915_SET_COLORKEY_SOURCE)
1613 sprctl |= SPRITE_SOURCE_KEY;
1618 static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state,
1624 * WaFP16GammaEnabling:ivb,hsw
1625 * "Workaround : When using the 64-bit format, the sprite output
1626 * on each color channel has one quarter amplitude. It can be
1627 * brought up to full amplitude by using sprite internal gamma
1628 * correction, pipe gamma correction, or pipe color space
1629 * conversion to multiply the sprite output by four."
1633 for (i = 0; i < 16; i++)
1634 gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1);
1636 gamma[i] = min((scale * i << 10) / 16, 1 << 10);
1643 static void ivb_update_gamma(const struct intel_plane_state *plane_state)
1645 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1646 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1647 enum pipe pipe = plane->pipe;
1651 if (!ivb_need_sprite_gamma(plane_state))
1654 ivb_sprite_linear_gamma(plane_state, gamma);
1656 /* FIXME these register are single buffered :( */
1657 for (i = 0; i < 16; i++)
1658 intel_de_write_fw(dev_priv, SPRGAMC(pipe, i),
1659 gamma[i] << 20 | gamma[i] << 10 | gamma[i]);
1661 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 0), gamma[i]);
1662 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 1), gamma[i]);
1663 intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 2), gamma[i]);
1666 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 0), gamma[i]);
1667 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 1), gamma[i]);
1668 intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 2), gamma[i]);
1673 ivb_update_plane(struct intel_plane *plane,
1674 const struct intel_crtc_state *crtc_state,
1675 const struct intel_plane_state *plane_state)
1677 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1678 enum pipe pipe = plane->pipe;
1679 u32 sprsurf_offset = plane_state->color_plane[0].offset;
1681 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1682 int crtc_x = plane_state->uapi.dst.x1;
1683 int crtc_y = plane_state->uapi.dst.y1;
1684 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
1685 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
1686 u32 x = plane_state->color_plane[0].x;
1687 u32 y = plane_state->color_plane[0].y;
1688 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1689 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1690 u32 sprctl, sprscale = 0;
1691 unsigned long irqflags;
1693 sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
1695 /* Sizes are 0 based */
1701 if (crtc_w != src_w || crtc_h != src_h)
1702 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
1704 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1706 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1708 intel_de_write_fw(dev_priv, SPRSTRIDE(pipe),
1709 plane_state->color_plane[0].stride);
1710 intel_de_write_fw(dev_priv, SPRPOS(pipe), (crtc_y << 16) | crtc_x);
1711 intel_de_write_fw(dev_priv, SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
1712 if (IS_IVYBRIDGE(dev_priv))
1713 intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale);
1716 intel_de_write_fw(dev_priv, SPRKEYVAL(pipe), key->min_value);
1717 intel_de_write_fw(dev_priv, SPRKEYMSK(pipe),
1719 intel_de_write_fw(dev_priv, SPRKEYMAX(pipe), key->max_value);
1722 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
1724 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
1725 intel_de_write_fw(dev_priv, SPROFFSET(pipe), (y << 16) | x);
1727 intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset);
1728 intel_de_write_fw(dev_priv, SPRTILEOFF(pipe), (y << 16) | x);
1732 * The control register self-arms if the plane was previously
1733 * disabled. Try to make the plane enable atomic by writing
1734 * the control register just before the surface register.
1736 intel_de_write_fw(dev_priv, SPRCTL(pipe), sprctl);
1737 intel_de_write_fw(dev_priv, SPRSURF(pipe),
1738 intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1740 ivb_update_gamma(plane_state);
1742 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1746 ivb_disable_plane(struct intel_plane *plane,
1747 const struct intel_crtc_state *crtc_state)
1749 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1750 enum pipe pipe = plane->pipe;
1751 unsigned long irqflags;
1753 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1755 intel_de_write_fw(dev_priv, SPRCTL(pipe), 0);
1756 /* Disable the scaler */
1757 if (IS_IVYBRIDGE(dev_priv))
1758 intel_de_write_fw(dev_priv, SPRSCALE(pipe), 0);
1759 intel_de_write_fw(dev_priv, SPRSURF(pipe), 0);
1761 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1765 ivb_plane_get_hw_state(struct intel_plane *plane,
1768 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1769 enum intel_display_power_domain power_domain;
1770 intel_wakeref_t wakeref;
1773 power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1774 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1778 ret = intel_de_read(dev_priv, SPRCTL(plane->pipe)) & SPRITE_ENABLE;
1780 *pipe = plane->pipe;
1782 intel_display_power_put(dev_priv, power_domain, wakeref);
1787 static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
1788 const struct intel_plane_state *plane_state)
1790 const struct drm_framebuffer *fb = plane_state->hw.fb;
1791 unsigned int hscale, pixel_rate;
1792 unsigned int limit, decimate;
1795 * Note that crtc_state->pixel_rate accounts for both
1796 * horizontal and vertical panel fitter downscaling factors.
1797 * Pre-HSW bspec tells us to only consider the horizontal
1798 * downscaling factor here. We ignore that and just consider
1799 * both for simplicity.
1801 pixel_rate = crtc_state->pixel_rate;
1803 /* Horizontal downscaling limits the maximum pixel rate */
1804 hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
1805 &plane_state->uapi.dst,
1807 hscale = max(hscale, 0x10000u);
1809 /* Decimation steps at 2x,4x,8x,16x */
1810 decimate = ilog2(hscale >> 16);
1811 hscale >>= decimate;
1813 /* Starting limit is 90% of cdclk */
1816 /* -10% per decimation step */
1820 if (!fb->format->is_yuv)
1824 * We should also do -10% if sprite scaling is enabled
1825 * on the other pipe, but we can't really check for that,
1829 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale),
1834 g4x_sprite_max_stride(struct intel_plane *plane,
1835 u32 pixel_format, u64 modifier,
1836 unsigned int rotation)
1841 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1845 if (crtc_state->gamma_enable)
1846 dvscntr |= DVS_GAMMA_ENABLE;
1848 if (crtc_state->csc_enable)
1849 dvscntr |= DVS_PIPE_CSC_ENABLE;
1854 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
1855 const struct intel_plane_state *plane_state)
1857 struct drm_i915_private *dev_priv =
1858 to_i915(plane_state->uapi.plane->dev);
1859 const struct drm_framebuffer *fb = plane_state->hw.fb;
1860 unsigned int rotation = plane_state->hw.rotation;
1861 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1864 dvscntr = DVS_ENABLE;
1866 if (IS_GEN(dev_priv, 6))
1867 dvscntr |= DVS_TRICKLE_FEED_DISABLE;
1869 switch (fb->format->format) {
1870 case DRM_FORMAT_XBGR8888:
1871 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
1873 case DRM_FORMAT_XRGB8888:
1874 dvscntr |= DVS_FORMAT_RGBX888;
1876 case DRM_FORMAT_XBGR2101010:
1877 dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR;
1879 case DRM_FORMAT_XRGB2101010:
1880 dvscntr |= DVS_FORMAT_RGBX101010;
1882 case DRM_FORMAT_XBGR16161616F:
1883 dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR;
1885 case DRM_FORMAT_XRGB16161616F:
1886 dvscntr |= DVS_FORMAT_RGBX161616;
1888 case DRM_FORMAT_YUYV:
1889 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
1891 case DRM_FORMAT_YVYU:
1892 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
1894 case DRM_FORMAT_UYVY:
1895 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
1897 case DRM_FORMAT_VYUY:
1898 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
1901 MISSING_CASE(fb->format->format);
1905 if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
1906 dvscntr |= DVS_YUV_FORMAT_BT709;
1908 if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1909 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
1911 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1912 dvscntr |= DVS_TILED;
1914 if (rotation & DRM_MODE_ROTATE_180)
1915 dvscntr |= DVS_ROTATE_180;
1917 if (key->flags & I915_SET_COLORKEY_DESTINATION)
1918 dvscntr |= DVS_DEST_KEY;
1919 else if (key->flags & I915_SET_COLORKEY_SOURCE)
1920 dvscntr |= DVS_SOURCE_KEY;
1925 static void g4x_update_gamma(const struct intel_plane_state *plane_state)
1927 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1928 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1929 const struct drm_framebuffer *fb = plane_state->hw.fb;
1930 enum pipe pipe = plane->pipe;
1934 /* Seems RGB data bypasses the gamma always */
1935 if (!fb->format->is_yuv)
1938 i9xx_plane_linear_gamma(gamma);
1940 /* FIXME these register are single buffered :( */
1941 /* The two end points are implicit (0.0 and 1.0) */
1942 for (i = 1; i < 8 - 1; i++)
1943 intel_de_write_fw(dev_priv, DVSGAMC_G4X(pipe, i - 1),
1944 gamma[i] << 16 | gamma[i] << 8 | gamma[i]);
1947 static void ilk_sprite_linear_gamma(u16 gamma[17])
1951 for (i = 0; i < 17; i++)
1952 gamma[i] = (i << 10) / 16;
1955 static void ilk_update_gamma(const struct intel_plane_state *plane_state)
1957 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1958 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1959 const struct drm_framebuffer *fb = plane_state->hw.fb;
1960 enum pipe pipe = plane->pipe;
1964 /* Seems RGB data bypasses the gamma always */
1965 if (!fb->format->is_yuv)
1968 ilk_sprite_linear_gamma(gamma);
1970 /* FIXME these register are single buffered :( */
1971 for (i = 0; i < 16; i++)
1972 intel_de_write_fw(dev_priv, DVSGAMC_ILK(pipe, i),
1973 gamma[i] << 20 | gamma[i] << 10 | gamma[i]);
1975 intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 0), gamma[i]);
1976 intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 1), gamma[i]);
1977 intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 2), gamma[i]);
1982 g4x_update_plane(struct intel_plane *plane,
1983 const struct intel_crtc_state *crtc_state,
1984 const struct intel_plane_state *plane_state)
1986 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1987 enum pipe pipe = plane->pipe;
1988 u32 dvssurf_offset = plane_state->color_plane[0].offset;
1990 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1991 int crtc_x = plane_state->uapi.dst.x1;
1992 int crtc_y = plane_state->uapi.dst.y1;
1993 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
1994 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
1995 u32 x = plane_state->color_plane[0].x;
1996 u32 y = plane_state->color_plane[0].y;
1997 u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1998 u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1999 u32 dvscntr, dvsscale = 0;
2000 unsigned long irqflags;
2002 dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
2004 /* Sizes are 0 based */
2010 if (crtc_w != src_w || crtc_h != src_h)
2011 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
2013 linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
2015 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
2017 intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
2018 plane_state->color_plane[0].stride);
2019 intel_de_write_fw(dev_priv, DVSPOS(pipe), (crtc_y << 16) | crtc_x);
2020 intel_de_write_fw(dev_priv, DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
2021 intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale);
2024 intel_de_write_fw(dev_priv, DVSKEYVAL(pipe), key->min_value);
2025 intel_de_write_fw(dev_priv, DVSKEYMSK(pipe),
2027 intel_de_write_fw(dev_priv, DVSKEYMAX(pipe), key->max_value);
2030 intel_de_write_fw(dev_priv, DVSLINOFF(pipe), linear_offset);
2031 intel_de_write_fw(dev_priv, DVSTILEOFF(pipe), (y << 16) | x);
2034 * The control register self-arms if the plane was previously
2035 * disabled. Try to make the plane enable atomic by writing
2036 * the control register just before the surface register.
2038 intel_de_write_fw(dev_priv, DVSCNTR(pipe), dvscntr);
2039 intel_de_write_fw(dev_priv, DVSSURF(pipe),
2040 intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
2042 if (IS_G4X(dev_priv))
2043 g4x_update_gamma(plane_state);
2045 ilk_update_gamma(plane_state);
2047 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
2051 g4x_disable_plane(struct intel_plane *plane,
2052 const struct intel_crtc_state *crtc_state)
2054 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2055 enum pipe pipe = plane->pipe;
2056 unsigned long irqflags;
2058 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
2060 intel_de_write_fw(dev_priv, DVSCNTR(pipe), 0);
2061 /* Disable the scaler */
2062 intel_de_write_fw(dev_priv, DVSSCALE(pipe), 0);
2063 intel_de_write_fw(dev_priv, DVSSURF(pipe), 0);
2065 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
2069 g4x_plane_get_hw_state(struct intel_plane *plane,
2072 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2073 enum intel_display_power_domain power_domain;
2074 intel_wakeref_t wakeref;
2077 power_domain = POWER_DOMAIN_PIPE(plane->pipe);
2078 wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
2082 ret = intel_de_read(dev_priv, DVSCNTR(plane->pipe)) & DVS_ENABLE;
2084 *pipe = plane->pipe;
2086 intel_display_power_put(dev_priv, power_domain, wakeref);
2091 static bool intel_fb_scalable(const struct drm_framebuffer *fb)
2096 switch (fb->format->format) {
2099 case DRM_FORMAT_XRGB16161616F:
2100 case DRM_FORMAT_ARGB16161616F:
2101 case DRM_FORMAT_XBGR16161616F:
2102 case DRM_FORMAT_ABGR16161616F:
2103 return INTEL_GEN(to_i915(fb->dev)) >= 11;
2110 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
2111 struct intel_plane_state *plane_state)
2113 const struct drm_framebuffer *fb = plane_state->hw.fb;
2114 const struct drm_rect *src = &plane_state->uapi.src;
2115 const struct drm_rect *dst = &plane_state->uapi.dst;
2116 int src_x, src_w, src_h, crtc_w, crtc_h;
2117 const struct drm_display_mode *adjusted_mode =
2118 &crtc_state->hw.adjusted_mode;
2119 unsigned int stride = plane_state->color_plane[0].stride;
2120 unsigned int cpp = fb->format->cpp[0];
2121 unsigned int width_bytes;
2122 int min_width, min_height;
2124 crtc_w = drm_rect_width(dst);
2125 crtc_h = drm_rect_height(dst);
2127 src_x = src->x1 >> 16;
2128 src_w = drm_rect_width(src) >> 16;
2129 src_h = drm_rect_height(src) >> 16;
2131 if (src_w == crtc_w && src_h == crtc_h)
2136 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
2138 DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
2146 width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
2148 if (src_w < min_width || src_h < min_height ||
2149 src_w > 2048 || src_h > 2048) {
2150 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
2151 src_w, src_h, min_width, min_height, 2048, 2048);
2155 if (width_bytes > 4096) {
2156 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
2161 if (stride > 4096) {
2162 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
2171 g4x_sprite_check(struct intel_crtc_state *crtc_state,
2172 struct intel_plane_state *plane_state)
2174 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2175 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2176 int min_scale = DRM_PLANE_HELPER_NO_SCALING;
2177 int max_scale = DRM_PLANE_HELPER_NO_SCALING;
2180 if (intel_fb_scalable(plane_state->hw.fb)) {
2181 if (INTEL_GEN(dev_priv) < 7) {
2183 max_scale = 16 << 16;
2184 } else if (IS_IVYBRIDGE(dev_priv)) {
2186 max_scale = 2 << 16;
2190 ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
2191 min_scale, max_scale, true);
2195 ret = i9xx_check_plane_surface(plane_state);
2199 if (!plane_state->uapi.visible)
2202 ret = intel_plane_check_src_coordinates(plane_state);
2206 ret = g4x_sprite_check_scaling(crtc_state, plane_state);
2210 if (INTEL_GEN(dev_priv) >= 7)
2211 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
2213 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
2218 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
2220 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2221 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2222 unsigned int rotation = plane_state->hw.rotation;
2224 /* CHV ignores the mirror bit when the rotate bit is set :( */
2225 if (IS_CHERRYVIEW(dev_priv) &&
2226 rotation & DRM_MODE_ROTATE_180 &&
2227 rotation & DRM_MODE_REFLECT_X) {
2228 drm_dbg_kms(&dev_priv->drm,
2229 "Cannot rotate and reflect at the same time\n");
2237 vlv_sprite_check(struct intel_crtc_state *crtc_state,
2238 struct intel_plane_state *plane_state)
2242 ret = chv_plane_check_rotation(plane_state);
2246 ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
2247 DRM_PLANE_HELPER_NO_SCALING,
2248 DRM_PLANE_HELPER_NO_SCALING,
2253 ret = i9xx_check_plane_surface(plane_state);
2257 if (!plane_state->uapi.visible)
2260 ret = intel_plane_check_src_coordinates(plane_state);
2264 plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
2269 static bool intel_format_is_p01x(u32 format)
2272 case DRM_FORMAT_P010:
2273 case DRM_FORMAT_P012:
2274 case DRM_FORMAT_P016:
2281 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
2282 const struct intel_plane_state *plane_state)
2284 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2285 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2286 const struct drm_framebuffer *fb = plane_state->hw.fb;
2287 unsigned int rotation = plane_state->hw.rotation;
2288 struct drm_format_name_buf format_name;
2293 if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
2294 is_ccs_modifier(fb->modifier)) {
2295 drm_dbg_kms(&dev_priv->drm,
2296 "RC support only with 0/180 degree rotation (%x)\n",
2301 if (rotation & DRM_MODE_REFLECT_X &&
2302 fb->modifier == DRM_FORMAT_MOD_LINEAR) {
2303 drm_dbg_kms(&dev_priv->drm,
2304 "horizontal flip is not supported with linear surface formats\n");
2308 if (drm_rotation_90_or_270(rotation)) {
2309 if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
2310 fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
2311 drm_dbg_kms(&dev_priv->drm,
2312 "Y/Yf tiling required for 90/270!\n");
2317 * 90/270 is not allowed with RGB64 16:16:16:16 and
2318 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
2320 switch (fb->format->format) {
2321 case DRM_FORMAT_RGB565:
2322 if (INTEL_GEN(dev_priv) >= 11)
2326 case DRM_FORMAT_XRGB16161616F:
2327 case DRM_FORMAT_XBGR16161616F:
2328 case DRM_FORMAT_ARGB16161616F:
2329 case DRM_FORMAT_ABGR16161616F:
2330 case DRM_FORMAT_Y210:
2331 case DRM_FORMAT_Y212:
2332 case DRM_FORMAT_Y216:
2333 case DRM_FORMAT_XVYU12_16161616:
2334 case DRM_FORMAT_XVYU16161616:
2335 drm_dbg_kms(&dev_priv->drm,
2336 "Unsupported pixel format %s for 90/270!\n",
2337 drm_get_format_name(fb->format->format,
2345 /* Y-tiling is not supported in IF-ID Interlace mode */
2346 if (crtc_state->hw.enable &&
2347 crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
2348 (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
2349 fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
2350 fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
2351 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
2352 fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
2353 fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)) {
2354 drm_dbg_kms(&dev_priv->drm,
2355 "Y/Yf tiling not supported in IF-ID mode\n");
2359 /* Wa_1606054188:tgl */
2360 if (IS_TIGERLAKE(dev_priv) &&
2361 plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE &&
2362 intel_format_is_p01x(fb->format->format)) {
2363 drm_dbg_kms(&dev_priv->drm,
2364 "Source color keying not supported with P01x formats\n");
2371 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
2372 const struct intel_plane_state *plane_state)
2374 struct drm_i915_private *dev_priv =
2375 to_i915(plane_state->uapi.plane->dev);
2376 int crtc_x = plane_state->uapi.dst.x1;
2377 int crtc_w = drm_rect_width(&plane_state->uapi.dst);
2378 int pipe_src_w = crtc_state->pipe_src_w;
2381 * Display WA #1175: cnl,glk
2382 * Planes other than the cursor may cause FIFO underflow and display
2383 * corruption if starting less than 4 pixels from the right edge of
2385 * Besides the above WA fix the similar problem, where planes other
2386 * than the cursor ending less than 4 pixels from the left edge of the
2387 * screen may cause FIFO underflow and display corruption.
2389 if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
2390 (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
2391 drm_dbg_kms(&dev_priv->drm,
2392 "requested plane X %s position %d invalid (valid range %d-%d)\n",
2393 crtc_x + crtc_w < 4 ? "end" : "start",
2394 crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
2402 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
2404 const struct drm_framebuffer *fb = plane_state->hw.fb;
2405 unsigned int rotation = plane_state->hw.rotation;
2406 int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
2408 /* Display WA #1106 */
2409 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
2411 (rotation == DRM_MODE_ROTATE_270 ||
2412 rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
2413 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
2420 static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
2421 const struct drm_framebuffer *fb)
2424 * We don't yet know the final source width nor
2425 * whether we can use the HQ scaler mode. Assume
2427 * FIXME need to properly check this later.
2429 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) ||
2430 !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
2436 static int skl_plane_check(struct intel_crtc_state *crtc_state,
2437 struct intel_plane_state *plane_state)
2439 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2440 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2441 const struct drm_framebuffer *fb = plane_state->hw.fb;
2442 int min_scale = DRM_PLANE_HELPER_NO_SCALING;
2443 int max_scale = DRM_PLANE_HELPER_NO_SCALING;
2446 ret = skl_plane_check_fb(crtc_state, plane_state);
2450 /* use scaler when colorkey is not required */
2451 if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
2453 max_scale = skl_plane_max_scale(dev_priv, fb);
2456 ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
2457 min_scale, max_scale, true);
2461 ret = skl_check_plane_surface(plane_state);
2465 if (!plane_state->uapi.visible)
2468 ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
2472 ret = intel_plane_check_src_coordinates(plane_state);
2476 ret = skl_plane_check_nv12_rotation(plane_state);
2480 /* HW only has 8 bits pixel precision, disable plane if invisible */
2481 if (!(plane_state->hw.alpha >> 8))
2482 plane_state->uapi.visible = false;
2484 plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
2486 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
2487 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
2490 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
2491 icl_is_hdr_plane(dev_priv, plane->id))
2492 /* Enable and use MPEG-2 chroma siting */
2493 plane_state->cus_ctl = PLANE_CUS_ENABLE |
2494 PLANE_CUS_HPHASE_0 |
2495 PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
2497 plane_state->cus_ctl = 0;
2502 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
2504 return INTEL_GEN(dev_priv) >= 9;
2507 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
2508 const struct drm_intel_sprite_colorkey *set)
2510 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2511 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2512 struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
2517 * We want src key enabled on the
2518 * sprite and not on the primary.
2520 if (plane->id == PLANE_PRIMARY &&
2521 set->flags & I915_SET_COLORKEY_SOURCE)
2525 * On SKL+ we want dst key enabled on
2526 * the primary and not on the sprite.
2528 if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
2529 set->flags & I915_SET_COLORKEY_DESTINATION)
2533 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
2534 struct drm_file *file_priv)
2536 struct drm_i915_private *dev_priv = to_i915(dev);
2537 struct drm_intel_sprite_colorkey *set = data;
2538 struct drm_plane *plane;
2539 struct drm_plane_state *plane_state;
2540 struct drm_atomic_state *state;
2541 struct drm_modeset_acquire_ctx ctx;
2544 /* ignore the pointless "none" flag */
2545 set->flags &= ~I915_SET_COLORKEY_NONE;
2547 if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
2550 /* Make sure we don't try to enable both src & dest simultaneously */
2551 if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
2554 if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
2555 set->flags & I915_SET_COLORKEY_DESTINATION)
2558 plane = drm_plane_find(dev, file_priv, set->plane_id);
2559 if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
2563 * SKL+ only plane 2 can do destination keying against plane 1.
2564 * Also multiple planes can't do destination keying on the same
2565 * pipe simultaneously.
2567 if (INTEL_GEN(dev_priv) >= 9 &&
2568 to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
2569 set->flags & I915_SET_COLORKEY_DESTINATION)
2572 drm_modeset_acquire_init(&ctx, 0);
2574 state = drm_atomic_state_alloc(plane->dev);
2579 state->acquire_ctx = &ctx;
2582 plane_state = drm_atomic_get_plane_state(state, plane);
2583 ret = PTR_ERR_OR_ZERO(plane_state);
2585 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
2588 * On some platforms we have to configure
2589 * the dst colorkey on the primary plane.
2591 if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
2592 struct intel_crtc *crtc =
2593 intel_get_crtc_for_pipe(dev_priv,
2594 to_intel_plane(plane)->pipe);
2596 plane_state = drm_atomic_get_plane_state(state,
2597 crtc->base.primary);
2598 ret = PTR_ERR_OR_ZERO(plane_state);
2600 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
2604 ret = drm_atomic_commit(state);
2606 if (ret != -EDEADLK)
2609 drm_atomic_state_clear(state);
2610 drm_modeset_backoff(&ctx);
2613 drm_atomic_state_put(state);
2615 drm_modeset_drop_locks(&ctx);
2616 drm_modeset_acquire_fini(&ctx);
2620 static const u32 g4x_plane_formats[] = {
2621 DRM_FORMAT_XRGB8888,
2628 static const u64 i9xx_plane_format_modifiers[] = {
2629 I915_FORMAT_MOD_X_TILED,
2630 DRM_FORMAT_MOD_LINEAR,
2631 DRM_FORMAT_MOD_INVALID
2634 static const u32 snb_plane_formats[] = {
2635 DRM_FORMAT_XRGB8888,
2636 DRM_FORMAT_XBGR8888,
2637 DRM_FORMAT_XRGB2101010,
2638 DRM_FORMAT_XBGR2101010,
2639 DRM_FORMAT_XRGB16161616F,
2640 DRM_FORMAT_XBGR16161616F,
2647 static const u32 vlv_plane_formats[] = {
2650 DRM_FORMAT_XRGB8888,
2651 DRM_FORMAT_XBGR8888,
2652 DRM_FORMAT_ARGB8888,
2653 DRM_FORMAT_ABGR8888,
2654 DRM_FORMAT_XBGR2101010,
2655 DRM_FORMAT_ABGR2101010,
2662 static const u32 chv_pipe_b_sprite_formats[] = {
2665 DRM_FORMAT_XRGB8888,
2666 DRM_FORMAT_XBGR8888,
2667 DRM_FORMAT_ARGB8888,
2668 DRM_FORMAT_ABGR8888,
2669 DRM_FORMAT_XRGB2101010,
2670 DRM_FORMAT_XBGR2101010,
2671 DRM_FORMAT_ARGB2101010,
2672 DRM_FORMAT_ABGR2101010,
2679 static const u32 skl_plane_formats[] = {
2682 DRM_FORMAT_XRGB8888,
2683 DRM_FORMAT_XBGR8888,
2684 DRM_FORMAT_ARGB8888,
2685 DRM_FORMAT_ABGR8888,
2686 DRM_FORMAT_XRGB2101010,
2687 DRM_FORMAT_XBGR2101010,
2688 DRM_FORMAT_XRGB16161616F,
2689 DRM_FORMAT_XBGR16161616F,
2694 DRM_FORMAT_XYUV8888,
2697 static const u32 skl_planar_formats[] = {
2700 DRM_FORMAT_XRGB8888,
2701 DRM_FORMAT_XBGR8888,
2702 DRM_FORMAT_ARGB8888,
2703 DRM_FORMAT_ABGR8888,
2704 DRM_FORMAT_XRGB2101010,
2705 DRM_FORMAT_XBGR2101010,
2706 DRM_FORMAT_XRGB16161616F,
2707 DRM_FORMAT_XBGR16161616F,
2713 DRM_FORMAT_XYUV8888,
2716 static const u32 glk_planar_formats[] = {
2719 DRM_FORMAT_XRGB8888,
2720 DRM_FORMAT_XBGR8888,
2721 DRM_FORMAT_ARGB8888,
2722 DRM_FORMAT_ABGR8888,
2723 DRM_FORMAT_XRGB2101010,
2724 DRM_FORMAT_XBGR2101010,
2725 DRM_FORMAT_XRGB16161616F,
2726 DRM_FORMAT_XBGR16161616F,
2732 DRM_FORMAT_XYUV8888,
2738 static const u32 icl_sdr_y_plane_formats[] = {
2741 DRM_FORMAT_XRGB8888,
2742 DRM_FORMAT_XBGR8888,
2743 DRM_FORMAT_ARGB8888,
2744 DRM_FORMAT_ABGR8888,
2745 DRM_FORMAT_XRGB2101010,
2746 DRM_FORMAT_XBGR2101010,
2747 DRM_FORMAT_ARGB2101010,
2748 DRM_FORMAT_ABGR2101010,
2756 DRM_FORMAT_XYUV8888,
2757 DRM_FORMAT_XVYU2101010,
2758 DRM_FORMAT_XVYU12_16161616,
2759 DRM_FORMAT_XVYU16161616,
2762 static const u32 icl_sdr_uv_plane_formats[] = {
2765 DRM_FORMAT_XRGB8888,
2766 DRM_FORMAT_XBGR8888,
2767 DRM_FORMAT_ARGB8888,
2768 DRM_FORMAT_ABGR8888,
2769 DRM_FORMAT_XRGB2101010,
2770 DRM_FORMAT_XBGR2101010,
2771 DRM_FORMAT_ARGB2101010,
2772 DRM_FORMAT_ABGR2101010,
2784 DRM_FORMAT_XYUV8888,
2785 DRM_FORMAT_XVYU2101010,
2786 DRM_FORMAT_XVYU12_16161616,
2787 DRM_FORMAT_XVYU16161616,
2790 static const u32 icl_hdr_plane_formats[] = {
2793 DRM_FORMAT_XRGB8888,
2794 DRM_FORMAT_XBGR8888,
2795 DRM_FORMAT_ARGB8888,
2796 DRM_FORMAT_ABGR8888,
2797 DRM_FORMAT_XRGB2101010,
2798 DRM_FORMAT_XBGR2101010,
2799 DRM_FORMAT_ARGB2101010,
2800 DRM_FORMAT_ABGR2101010,
2801 DRM_FORMAT_XRGB16161616F,
2802 DRM_FORMAT_XBGR16161616F,
2803 DRM_FORMAT_ARGB16161616F,
2804 DRM_FORMAT_ABGR16161616F,
2816 DRM_FORMAT_XYUV8888,
2817 DRM_FORMAT_XVYU2101010,
2818 DRM_FORMAT_XVYU12_16161616,
2819 DRM_FORMAT_XVYU16161616,
2822 static const u64 skl_plane_format_modifiers_noccs[] = {
2823 I915_FORMAT_MOD_Yf_TILED,
2824 I915_FORMAT_MOD_Y_TILED,
2825 I915_FORMAT_MOD_X_TILED,
2826 DRM_FORMAT_MOD_LINEAR,
2827 DRM_FORMAT_MOD_INVALID
2830 static const u64 skl_plane_format_modifiers_ccs[] = {
2831 I915_FORMAT_MOD_Yf_TILED_CCS,
2832 I915_FORMAT_MOD_Y_TILED_CCS,
2833 I915_FORMAT_MOD_Yf_TILED,
2834 I915_FORMAT_MOD_Y_TILED,
2835 I915_FORMAT_MOD_X_TILED,
2836 DRM_FORMAT_MOD_LINEAR,
2837 DRM_FORMAT_MOD_INVALID
2840 static const u64 gen12_plane_format_modifiers_mc_ccs[] = {
2841 I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
2842 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
2843 I915_FORMAT_MOD_Y_TILED,
2844 I915_FORMAT_MOD_X_TILED,
2845 DRM_FORMAT_MOD_LINEAR,
2846 DRM_FORMAT_MOD_INVALID
2849 static const u64 gen12_plane_format_modifiers_rc_ccs[] = {
2850 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
2851 I915_FORMAT_MOD_Y_TILED,
2852 I915_FORMAT_MOD_X_TILED,
2853 DRM_FORMAT_MOD_LINEAR,
2854 DRM_FORMAT_MOD_INVALID
2857 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
2858 u32 format, u64 modifier)
2861 case DRM_FORMAT_MOD_LINEAR:
2862 case I915_FORMAT_MOD_X_TILED:
2869 case DRM_FORMAT_XRGB8888:
2870 case DRM_FORMAT_YUYV:
2871 case DRM_FORMAT_YVYU:
2872 case DRM_FORMAT_UYVY:
2873 case DRM_FORMAT_VYUY:
2874 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2875 modifier == I915_FORMAT_MOD_X_TILED)
2883 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
2884 u32 format, u64 modifier)
2887 case DRM_FORMAT_MOD_LINEAR:
2888 case I915_FORMAT_MOD_X_TILED:
2895 case DRM_FORMAT_XRGB8888:
2896 case DRM_FORMAT_XBGR8888:
2897 case DRM_FORMAT_XRGB2101010:
2898 case DRM_FORMAT_XBGR2101010:
2899 case DRM_FORMAT_XRGB16161616F:
2900 case DRM_FORMAT_XBGR16161616F:
2901 case DRM_FORMAT_YUYV:
2902 case DRM_FORMAT_YVYU:
2903 case DRM_FORMAT_UYVY:
2904 case DRM_FORMAT_VYUY:
2905 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2906 modifier == I915_FORMAT_MOD_X_TILED)
2914 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
2915 u32 format, u64 modifier)
2918 case DRM_FORMAT_MOD_LINEAR:
2919 case I915_FORMAT_MOD_X_TILED:
2927 case DRM_FORMAT_RGB565:
2928 case DRM_FORMAT_ABGR8888:
2929 case DRM_FORMAT_ARGB8888:
2930 case DRM_FORMAT_XBGR8888:
2931 case DRM_FORMAT_XRGB8888:
2932 case DRM_FORMAT_XBGR2101010:
2933 case DRM_FORMAT_ABGR2101010:
2934 case DRM_FORMAT_XRGB2101010:
2935 case DRM_FORMAT_ARGB2101010:
2936 case DRM_FORMAT_YUYV:
2937 case DRM_FORMAT_YVYU:
2938 case DRM_FORMAT_UYVY:
2939 case DRM_FORMAT_VYUY:
2940 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2941 modifier == I915_FORMAT_MOD_X_TILED)
2949 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
2950 u32 format, u64 modifier)
2952 struct intel_plane *plane = to_intel_plane(_plane);
2955 case DRM_FORMAT_MOD_LINEAR:
2956 case I915_FORMAT_MOD_X_TILED:
2957 case I915_FORMAT_MOD_Y_TILED:
2958 case I915_FORMAT_MOD_Yf_TILED:
2960 case I915_FORMAT_MOD_Y_TILED_CCS:
2961 case I915_FORMAT_MOD_Yf_TILED_CCS:
2962 if (!plane->has_ccs)
2970 case DRM_FORMAT_XRGB8888:
2971 case DRM_FORMAT_XBGR8888:
2972 case DRM_FORMAT_ARGB8888:
2973 case DRM_FORMAT_ABGR8888:
2974 if (is_ccs_modifier(modifier))
2977 case DRM_FORMAT_RGB565:
2978 case DRM_FORMAT_XRGB2101010:
2979 case DRM_FORMAT_XBGR2101010:
2980 case DRM_FORMAT_ARGB2101010:
2981 case DRM_FORMAT_ABGR2101010:
2982 case DRM_FORMAT_YUYV:
2983 case DRM_FORMAT_YVYU:
2984 case DRM_FORMAT_UYVY:
2985 case DRM_FORMAT_VYUY:
2986 case DRM_FORMAT_NV12:
2987 case DRM_FORMAT_XYUV8888:
2988 case DRM_FORMAT_P010:
2989 case DRM_FORMAT_P012:
2990 case DRM_FORMAT_P016:
2991 case DRM_FORMAT_XVYU2101010:
2992 if (modifier == I915_FORMAT_MOD_Yf_TILED)
2996 case DRM_FORMAT_XBGR16161616F:
2997 case DRM_FORMAT_ABGR16161616F:
2998 case DRM_FORMAT_XRGB16161616F:
2999 case DRM_FORMAT_ARGB16161616F:
3000 case DRM_FORMAT_Y210:
3001 case DRM_FORMAT_Y212:
3002 case DRM_FORMAT_Y216:
3003 case DRM_FORMAT_XVYU12_16161616:
3004 case DRM_FORMAT_XVYU16161616:
3005 if (modifier == DRM_FORMAT_MOD_LINEAR ||
3006 modifier == I915_FORMAT_MOD_X_TILED ||
3007 modifier == I915_FORMAT_MOD_Y_TILED)
3015 static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
3016 enum plane_id plane_id)
3018 /* Wa_14010477008:tgl[a0..c0],rkl[all],dg1[all] */
3019 if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv) ||
3020 IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0))
3023 return plane_id < PLANE_SPRITE4;
3026 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
3027 u32 format, u64 modifier)
3029 struct drm_i915_private *dev_priv = to_i915(_plane->dev);
3030 struct intel_plane *plane = to_intel_plane(_plane);
3033 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
3034 if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))
3037 case DRM_FORMAT_MOD_LINEAR:
3038 case I915_FORMAT_MOD_X_TILED:
3039 case I915_FORMAT_MOD_Y_TILED:
3040 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
3047 case DRM_FORMAT_XRGB8888:
3048 case DRM_FORMAT_XBGR8888:
3049 case DRM_FORMAT_ARGB8888:
3050 case DRM_FORMAT_ABGR8888:
3051 if (is_ccs_modifier(modifier))
3054 case DRM_FORMAT_YUYV:
3055 case DRM_FORMAT_YVYU:
3056 case DRM_FORMAT_UYVY:
3057 case DRM_FORMAT_VYUY:
3058 case DRM_FORMAT_NV12:
3059 case DRM_FORMAT_XYUV8888:
3060 case DRM_FORMAT_P010:
3061 case DRM_FORMAT_P012:
3062 case DRM_FORMAT_P016:
3063 if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
3066 case DRM_FORMAT_RGB565:
3067 case DRM_FORMAT_XRGB2101010:
3068 case DRM_FORMAT_XBGR2101010:
3069 case DRM_FORMAT_ARGB2101010:
3070 case DRM_FORMAT_ABGR2101010:
3071 case DRM_FORMAT_XVYU2101010:
3073 case DRM_FORMAT_XBGR16161616F:
3074 case DRM_FORMAT_ABGR16161616F:
3075 case DRM_FORMAT_XRGB16161616F:
3076 case DRM_FORMAT_ARGB16161616F:
3077 case DRM_FORMAT_Y210:
3078 case DRM_FORMAT_Y212:
3079 case DRM_FORMAT_Y216:
3080 case DRM_FORMAT_XVYU12_16161616:
3081 case DRM_FORMAT_XVYU16161616:
3082 if (modifier == DRM_FORMAT_MOD_LINEAR ||
3083 modifier == I915_FORMAT_MOD_X_TILED ||
3084 modifier == I915_FORMAT_MOD_Y_TILED)
3092 static const struct drm_plane_funcs g4x_sprite_funcs = {
3093 .update_plane = drm_atomic_helper_update_plane,
3094 .disable_plane = drm_atomic_helper_disable_plane,
3095 .destroy = intel_plane_destroy,
3096 .atomic_duplicate_state = intel_plane_duplicate_state,
3097 .atomic_destroy_state = intel_plane_destroy_state,
3098 .format_mod_supported = g4x_sprite_format_mod_supported,
3101 static const struct drm_plane_funcs snb_sprite_funcs = {
3102 .update_plane = drm_atomic_helper_update_plane,
3103 .disable_plane = drm_atomic_helper_disable_plane,
3104 .destroy = intel_plane_destroy,
3105 .atomic_duplicate_state = intel_plane_duplicate_state,
3106 .atomic_destroy_state = intel_plane_destroy_state,
3107 .format_mod_supported = snb_sprite_format_mod_supported,
3110 static const struct drm_plane_funcs vlv_sprite_funcs = {
3111 .update_plane = drm_atomic_helper_update_plane,
3112 .disable_plane = drm_atomic_helper_disable_plane,
3113 .destroy = intel_plane_destroy,
3114 .atomic_duplicate_state = intel_plane_duplicate_state,
3115 .atomic_destroy_state = intel_plane_destroy_state,
3116 .format_mod_supported = vlv_sprite_format_mod_supported,
3119 static const struct drm_plane_funcs skl_plane_funcs = {
3120 .update_plane = drm_atomic_helper_update_plane,
3121 .disable_plane = drm_atomic_helper_disable_plane,
3122 .destroy = intel_plane_destroy,
3123 .atomic_duplicate_state = intel_plane_duplicate_state,
3124 .atomic_destroy_state = intel_plane_destroy_state,
3125 .format_mod_supported = skl_plane_format_mod_supported,
3128 static const struct drm_plane_funcs gen12_plane_funcs = {
3129 .update_plane = drm_atomic_helper_update_plane,
3130 .disable_plane = drm_atomic_helper_disable_plane,
3131 .destroy = intel_plane_destroy,
3132 .atomic_duplicate_state = intel_plane_duplicate_state,
3133 .atomic_destroy_state = intel_plane_destroy_state,
3134 .format_mod_supported = gen12_plane_format_mod_supported,
3137 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
3138 enum pipe pipe, enum plane_id plane_id)
3140 if (!HAS_FBC(dev_priv))
3143 return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
3146 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
3147 enum pipe pipe, enum plane_id plane_id)
3149 /* Display WA #0870: skl, bxt */
3150 if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
3153 if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
3156 if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
3162 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
3163 enum pipe pipe, enum plane_id plane_id,
3166 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
3167 *num_formats = ARRAY_SIZE(skl_planar_formats);
3168 return skl_planar_formats;
3170 *num_formats = ARRAY_SIZE(skl_plane_formats);
3171 return skl_plane_formats;
3175 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
3176 enum pipe pipe, enum plane_id plane_id,
3179 if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
3180 *num_formats = ARRAY_SIZE(glk_planar_formats);
3181 return glk_planar_formats;
3183 *num_formats = ARRAY_SIZE(skl_plane_formats);
3184 return skl_plane_formats;
3188 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
3189 enum pipe pipe, enum plane_id plane_id,
3192 if (icl_is_hdr_plane(dev_priv, plane_id)) {
3193 *num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
3194 return icl_hdr_plane_formats;
3195 } else if (icl_is_nv12_y_plane(dev_priv, plane_id)) {
3196 *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
3197 return icl_sdr_y_plane_formats;
3199 *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
3200 return icl_sdr_uv_plane_formats;
3204 static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
3205 enum plane_id plane_id)
3207 if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
3208 return gen12_plane_format_modifiers_mc_ccs;
3210 return gen12_plane_format_modifiers_rc_ccs;
3213 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
3214 enum pipe pipe, enum plane_id plane_id)
3216 if (plane_id == PLANE_CURSOR)
3219 if (INTEL_GEN(dev_priv) >= 10)
3222 if (IS_GEMINILAKE(dev_priv))
3223 return pipe != PIPE_C;
3225 return pipe != PIPE_C &&
3226 (plane_id == PLANE_PRIMARY ||
3227 plane_id == PLANE_SPRITE0);
3230 struct intel_plane *
3231 skl_universal_plane_create(struct drm_i915_private *dev_priv,
3232 enum pipe pipe, enum plane_id plane_id)
3234 const struct drm_plane_funcs *plane_funcs;
3235 struct intel_plane *plane;
3236 enum drm_plane_type plane_type;
3237 unsigned int supported_rotations;
3238 unsigned int supported_csc;
3239 const u64 *modifiers;
3244 plane = intel_plane_alloc();
3249 plane->id = plane_id;
3250 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
3252 plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
3253 if (plane->has_fbc) {
3254 struct intel_fbc *fbc = &dev_priv->fbc;
3256 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
3259 if (INTEL_GEN(dev_priv) >= 11) {
3260 plane->min_width = icl_plane_min_width;
3261 plane->max_width = icl_plane_max_width;
3262 plane->max_height = icl_plane_max_height;
3263 } else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
3264 plane->max_width = glk_plane_max_width;
3265 plane->max_height = skl_plane_max_height;
3267 plane->max_width = skl_plane_max_width;
3268 plane->max_height = skl_plane_max_height;
3271 plane->max_stride = skl_plane_max_stride;
3272 plane->update_plane = skl_update_plane;
3273 plane->disable_plane = skl_disable_plane;
3274 plane->get_hw_state = skl_plane_get_hw_state;
3275 plane->check_plane = skl_plane_check;
3276 plane->min_cdclk = skl_plane_min_cdclk;
3277 plane->async_flip = skl_plane_async_flip;
3279 if (INTEL_GEN(dev_priv) >= 11)
3280 formats = icl_get_plane_formats(dev_priv, pipe,
3281 plane_id, &num_formats);
3282 else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
3283 formats = glk_get_plane_formats(dev_priv, pipe,
3284 plane_id, &num_formats);
3286 formats = skl_get_plane_formats(dev_priv, pipe,
3287 plane_id, &num_formats);
3289 plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
3290 if (INTEL_GEN(dev_priv) >= 12) {
3291 modifiers = gen12_get_plane_modifiers(dev_priv, plane_id);
3292 plane_funcs = &gen12_plane_funcs;
3295 modifiers = skl_plane_format_modifiers_ccs;
3297 modifiers = skl_plane_format_modifiers_noccs;
3298 plane_funcs = &skl_plane_funcs;
3301 if (plane_id == PLANE_PRIMARY)
3302 plane_type = DRM_PLANE_TYPE_PRIMARY;
3304 plane_type = DRM_PLANE_TYPE_OVERLAY;
3306 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
3308 formats, num_formats, modifiers,
3310 "plane %d%c", plane_id + 1,
3315 supported_rotations =
3316 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
3317 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
3319 if (INTEL_GEN(dev_priv) >= 10)
3320 supported_rotations |= DRM_MODE_REFLECT_X;
3322 drm_plane_create_rotation_property(&plane->base,
3324 supported_rotations);
3326 supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709);
3328 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
3329 supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020);
3331 drm_plane_create_color_properties(&plane->base,
3333 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
3334 BIT(DRM_COLOR_YCBCR_FULL_RANGE),
3335 DRM_COLOR_YCBCR_BT709,
3336 DRM_COLOR_YCBCR_LIMITED_RANGE);
3338 drm_plane_create_alpha_property(&plane->base);
3339 drm_plane_create_blend_mode_property(&plane->base,
3340 BIT(DRM_MODE_BLEND_PIXEL_NONE) |
3341 BIT(DRM_MODE_BLEND_PREMULTI) |
3342 BIT(DRM_MODE_BLEND_COVERAGE));
3344 drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
3346 if (INTEL_GEN(dev_priv) >= 12)
3347 drm_plane_enable_fb_damage_clips(&plane->base);
3349 if (INTEL_GEN(dev_priv) >= 10)
3350 drm_plane_create_scaling_filter_property(&plane->base,
3351 BIT(DRM_SCALING_FILTER_DEFAULT) |
3352 BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
3354 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
3359 intel_plane_free(plane);
3361 return ERR_PTR(ret);
3364 struct intel_plane *
3365 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
3366 enum pipe pipe, int sprite)
3368 struct intel_plane *plane;
3369 const struct drm_plane_funcs *plane_funcs;
3370 unsigned int supported_rotations;
3371 const u64 *modifiers;
3376 if (INTEL_GEN(dev_priv) >= 9)
3377 return skl_universal_plane_create(dev_priv, pipe,
3378 PLANE_SPRITE0 + sprite);
3380 plane = intel_plane_alloc();
3384 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
3385 plane->max_stride = i9xx_plane_max_stride;
3386 plane->update_plane = vlv_update_plane;
3387 plane->disable_plane = vlv_disable_plane;
3388 plane->get_hw_state = vlv_plane_get_hw_state;
3389 plane->check_plane = vlv_sprite_check;
3390 plane->min_cdclk = vlv_plane_min_cdclk;
3392 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
3393 formats = chv_pipe_b_sprite_formats;
3394 num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats);
3396 formats = vlv_plane_formats;
3397 num_formats = ARRAY_SIZE(vlv_plane_formats);
3399 modifiers = i9xx_plane_format_modifiers;
3401 plane_funcs = &vlv_sprite_funcs;
3402 } else if (INTEL_GEN(dev_priv) >= 7) {
3403 plane->max_stride = g4x_sprite_max_stride;
3404 plane->update_plane = ivb_update_plane;
3405 plane->disable_plane = ivb_disable_plane;
3406 plane->get_hw_state = ivb_plane_get_hw_state;
3407 plane->check_plane = g4x_sprite_check;
3409 if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
3410 plane->min_cdclk = hsw_plane_min_cdclk;
3412 plane->min_cdclk = ivb_sprite_min_cdclk;
3414 formats = snb_plane_formats;
3415 num_formats = ARRAY_SIZE(snb_plane_formats);
3416 modifiers = i9xx_plane_format_modifiers;
3418 plane_funcs = &snb_sprite_funcs;
3420 plane->max_stride = g4x_sprite_max_stride;
3421 plane->update_plane = g4x_update_plane;
3422 plane->disable_plane = g4x_disable_plane;
3423 plane->get_hw_state = g4x_plane_get_hw_state;
3424 plane->check_plane = g4x_sprite_check;
3425 plane->min_cdclk = g4x_sprite_min_cdclk;
3427 modifiers = i9xx_plane_format_modifiers;
3428 if (IS_GEN(dev_priv, 6)) {
3429 formats = snb_plane_formats;
3430 num_formats = ARRAY_SIZE(snb_plane_formats);
3432 plane_funcs = &snb_sprite_funcs;
3434 formats = g4x_plane_formats;
3435 num_formats = ARRAY_SIZE(g4x_plane_formats);
3437 plane_funcs = &g4x_sprite_funcs;
3441 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
3442 supported_rotations =
3443 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
3446 supported_rotations =
3447 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
3451 plane->id = PLANE_SPRITE0 + sprite;
3452 plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
3454 ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
3456 formats, num_formats, modifiers,
3457 DRM_PLANE_TYPE_OVERLAY,
3458 "sprite %c", sprite_name(pipe, sprite));
3462 drm_plane_create_rotation_property(&plane->base,
3464 supported_rotations);
3466 drm_plane_create_color_properties(&plane->base,
3467 BIT(DRM_COLOR_YCBCR_BT601) |
3468 BIT(DRM_COLOR_YCBCR_BT709),
3469 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
3470 BIT(DRM_COLOR_YCBCR_FULL_RANGE),
3471 DRM_COLOR_YCBCR_BT709,
3472 DRM_COLOR_YCBCR_LIMITED_RANGE);
3475 drm_plane_create_zpos_immutable_property(&plane->base, zpos);
3477 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
3482 intel_plane_free(plane);
3484 return ERR_PTR(ret);