146d12f91SDave Airlie // SPDX-License-Identifier: MIT
246d12f91SDave Airlie /*
346d12f91SDave Airlie * Copyright © 2020 Intel Corporation
446d12f91SDave Airlie */
546d12f91SDave Airlie
646d12f91SDave Airlie #include <drm/drm_atomic_helper.h>
790bb087fSVille Syrjälä #include <drm/drm_blend.h>
846d12f91SDave Airlie #include <drm/drm_damage_helper.h>
946d12f91SDave Airlie #include <drm/drm_fourcc.h>
1046d12f91SDave Airlie
1146d12f91SDave Airlie #include "i915_drv.h"
12801543b2SJani Nikula #include "i915_reg.h"
1346d12f91SDave Airlie #include "intel_atomic_plane.h"
147785ae0bSVille Syrjälä #include "intel_de.h"
152b874a02SJani Nikula #include "intel_display_irq.h"
1646d12f91SDave Airlie #include "intel_display_types.h"
17f837a61fSImre Deak #include "intel_fb.h"
18825bd833SVille Syrjälä #include "intel_fbc.h"
1946d12f91SDave Airlie #include "intel_psr.h"
20714b1cdbSDave Airlie #include "skl_scaler.h"
2146d12f91SDave Airlie #include "skl_universal_plane.h"
2242a0d256SVille Syrjälä #include "skl_watermark.h"
23*b3749611SMatt Roper #include "gt/intel_gt.h"
24ef6ba31dSAnshuman Gupta #include "pxp/intel_pxp.h"
2546d12f91SDave Airlie
2646d12f91SDave Airlie static const u32 skl_plane_formats[] = {
2746d12f91SDave Airlie DRM_FORMAT_C8,
2846d12f91SDave Airlie DRM_FORMAT_RGB565,
2946d12f91SDave Airlie DRM_FORMAT_XRGB8888,
3046d12f91SDave Airlie DRM_FORMAT_XBGR8888,
3146d12f91SDave Airlie DRM_FORMAT_ARGB8888,
3246d12f91SDave Airlie DRM_FORMAT_ABGR8888,
3346d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
3446d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
3546d12f91SDave Airlie DRM_FORMAT_XRGB16161616F,
3646d12f91SDave Airlie DRM_FORMAT_XBGR16161616F,
3746d12f91SDave Airlie DRM_FORMAT_YUYV,
3846d12f91SDave Airlie DRM_FORMAT_YVYU,
3946d12f91SDave Airlie DRM_FORMAT_UYVY,
4046d12f91SDave Airlie DRM_FORMAT_VYUY,
4146d12f91SDave Airlie DRM_FORMAT_XYUV8888,
4246d12f91SDave Airlie };
4346d12f91SDave Airlie
4446d12f91SDave Airlie static const u32 skl_planar_formats[] = {
4546d12f91SDave Airlie DRM_FORMAT_C8,
4646d12f91SDave Airlie DRM_FORMAT_RGB565,
4746d12f91SDave Airlie DRM_FORMAT_XRGB8888,
4846d12f91SDave Airlie DRM_FORMAT_XBGR8888,
4946d12f91SDave Airlie DRM_FORMAT_ARGB8888,
5046d12f91SDave Airlie DRM_FORMAT_ABGR8888,
5146d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
5246d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
5346d12f91SDave Airlie DRM_FORMAT_XRGB16161616F,
5446d12f91SDave Airlie DRM_FORMAT_XBGR16161616F,
5546d12f91SDave Airlie DRM_FORMAT_YUYV,
5646d12f91SDave Airlie DRM_FORMAT_YVYU,
5746d12f91SDave Airlie DRM_FORMAT_UYVY,
5846d12f91SDave Airlie DRM_FORMAT_VYUY,
5946d12f91SDave Airlie DRM_FORMAT_NV12,
6046d12f91SDave Airlie DRM_FORMAT_XYUV8888,
6146d12f91SDave Airlie };
6246d12f91SDave Airlie
6346d12f91SDave Airlie static const u32 glk_planar_formats[] = {
6446d12f91SDave Airlie DRM_FORMAT_C8,
6546d12f91SDave Airlie DRM_FORMAT_RGB565,
6646d12f91SDave Airlie DRM_FORMAT_XRGB8888,
6746d12f91SDave Airlie DRM_FORMAT_XBGR8888,
6846d12f91SDave Airlie DRM_FORMAT_ARGB8888,
6946d12f91SDave Airlie DRM_FORMAT_ABGR8888,
7046d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
7146d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
7246d12f91SDave Airlie DRM_FORMAT_XRGB16161616F,
7346d12f91SDave Airlie DRM_FORMAT_XBGR16161616F,
7446d12f91SDave Airlie DRM_FORMAT_YUYV,
7546d12f91SDave Airlie DRM_FORMAT_YVYU,
7646d12f91SDave Airlie DRM_FORMAT_UYVY,
7746d12f91SDave Airlie DRM_FORMAT_VYUY,
7846d12f91SDave Airlie DRM_FORMAT_NV12,
7946d12f91SDave Airlie DRM_FORMAT_XYUV8888,
8046d12f91SDave Airlie DRM_FORMAT_P010,
8146d12f91SDave Airlie DRM_FORMAT_P012,
8246d12f91SDave Airlie DRM_FORMAT_P016,
8346d12f91SDave Airlie };
8446d12f91SDave Airlie
8546d12f91SDave Airlie static const u32 icl_sdr_y_plane_formats[] = {
8646d12f91SDave Airlie DRM_FORMAT_C8,
8746d12f91SDave Airlie DRM_FORMAT_RGB565,
8846d12f91SDave Airlie DRM_FORMAT_XRGB8888,
8946d12f91SDave Airlie DRM_FORMAT_XBGR8888,
9046d12f91SDave Airlie DRM_FORMAT_ARGB8888,
9146d12f91SDave Airlie DRM_FORMAT_ABGR8888,
9246d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
9346d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
9446d12f91SDave Airlie DRM_FORMAT_ARGB2101010,
9546d12f91SDave Airlie DRM_FORMAT_ABGR2101010,
9646d12f91SDave Airlie DRM_FORMAT_YUYV,
9746d12f91SDave Airlie DRM_FORMAT_YVYU,
9846d12f91SDave Airlie DRM_FORMAT_UYVY,
9946d12f91SDave Airlie DRM_FORMAT_VYUY,
10046d12f91SDave Airlie DRM_FORMAT_Y210,
10146d12f91SDave Airlie DRM_FORMAT_Y212,
10246d12f91SDave Airlie DRM_FORMAT_Y216,
10346d12f91SDave Airlie DRM_FORMAT_XYUV8888,
10446d12f91SDave Airlie DRM_FORMAT_XVYU2101010,
10546d12f91SDave Airlie };
10646d12f91SDave Airlie
10746d12f91SDave Airlie static const u32 icl_sdr_uv_plane_formats[] = {
10846d12f91SDave Airlie DRM_FORMAT_C8,
10946d12f91SDave Airlie DRM_FORMAT_RGB565,
11046d12f91SDave Airlie DRM_FORMAT_XRGB8888,
11146d12f91SDave Airlie DRM_FORMAT_XBGR8888,
11246d12f91SDave Airlie DRM_FORMAT_ARGB8888,
11346d12f91SDave Airlie DRM_FORMAT_ABGR8888,
11446d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
11546d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
11646d12f91SDave Airlie DRM_FORMAT_ARGB2101010,
11746d12f91SDave Airlie DRM_FORMAT_ABGR2101010,
11846d12f91SDave Airlie DRM_FORMAT_YUYV,
11946d12f91SDave Airlie DRM_FORMAT_YVYU,
12046d12f91SDave Airlie DRM_FORMAT_UYVY,
12146d12f91SDave Airlie DRM_FORMAT_VYUY,
12246d12f91SDave Airlie DRM_FORMAT_NV12,
12346d12f91SDave Airlie DRM_FORMAT_P010,
12446d12f91SDave Airlie DRM_FORMAT_P012,
12546d12f91SDave Airlie DRM_FORMAT_P016,
12646d12f91SDave Airlie DRM_FORMAT_Y210,
12746d12f91SDave Airlie DRM_FORMAT_Y212,
12846d12f91SDave Airlie DRM_FORMAT_Y216,
12946d12f91SDave Airlie DRM_FORMAT_XYUV8888,
13046d12f91SDave Airlie DRM_FORMAT_XVYU2101010,
13146d12f91SDave Airlie };
13246d12f91SDave Airlie
13346d12f91SDave Airlie static const u32 icl_hdr_plane_formats[] = {
13446d12f91SDave Airlie DRM_FORMAT_C8,
13546d12f91SDave Airlie DRM_FORMAT_RGB565,
13646d12f91SDave Airlie DRM_FORMAT_XRGB8888,
13746d12f91SDave Airlie DRM_FORMAT_XBGR8888,
13846d12f91SDave Airlie DRM_FORMAT_ARGB8888,
13946d12f91SDave Airlie DRM_FORMAT_ABGR8888,
14046d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
14146d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
14246d12f91SDave Airlie DRM_FORMAT_ARGB2101010,
14346d12f91SDave Airlie DRM_FORMAT_ABGR2101010,
14446d12f91SDave Airlie DRM_FORMAT_XRGB16161616F,
14546d12f91SDave Airlie DRM_FORMAT_XBGR16161616F,
14646d12f91SDave Airlie DRM_FORMAT_ARGB16161616F,
14746d12f91SDave Airlie DRM_FORMAT_ABGR16161616F,
14846d12f91SDave Airlie DRM_FORMAT_YUYV,
14946d12f91SDave Airlie DRM_FORMAT_YVYU,
15046d12f91SDave Airlie DRM_FORMAT_UYVY,
15146d12f91SDave Airlie DRM_FORMAT_VYUY,
15246d12f91SDave Airlie DRM_FORMAT_NV12,
15346d12f91SDave Airlie DRM_FORMAT_P010,
15446d12f91SDave Airlie DRM_FORMAT_P012,
15546d12f91SDave Airlie DRM_FORMAT_P016,
15646d12f91SDave Airlie DRM_FORMAT_Y210,
15746d12f91SDave Airlie DRM_FORMAT_Y212,
15846d12f91SDave Airlie DRM_FORMAT_Y216,
15946d12f91SDave Airlie DRM_FORMAT_XYUV8888,
16046d12f91SDave Airlie DRM_FORMAT_XVYU2101010,
16146d12f91SDave Airlie DRM_FORMAT_XVYU12_16161616,
16246d12f91SDave Airlie DRM_FORMAT_XVYU16161616,
16346d12f91SDave Airlie };
16446d12f91SDave Airlie
skl_format_to_fourcc(int format,bool rgb_order,bool alpha)16546d12f91SDave Airlie int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
16646d12f91SDave Airlie {
16746d12f91SDave Airlie switch (format) {
16846d12f91SDave Airlie case PLANE_CTL_FORMAT_RGB_565:
16946d12f91SDave Airlie return DRM_FORMAT_RGB565;
17046d12f91SDave Airlie case PLANE_CTL_FORMAT_NV12:
17146d12f91SDave Airlie return DRM_FORMAT_NV12;
17246d12f91SDave Airlie case PLANE_CTL_FORMAT_XYUV:
17346d12f91SDave Airlie return DRM_FORMAT_XYUV8888;
17446d12f91SDave Airlie case PLANE_CTL_FORMAT_P010:
17546d12f91SDave Airlie return DRM_FORMAT_P010;
17646d12f91SDave Airlie case PLANE_CTL_FORMAT_P012:
17746d12f91SDave Airlie return DRM_FORMAT_P012;
17846d12f91SDave Airlie case PLANE_CTL_FORMAT_P016:
17946d12f91SDave Airlie return DRM_FORMAT_P016;
18046d12f91SDave Airlie case PLANE_CTL_FORMAT_Y210:
18146d12f91SDave Airlie return DRM_FORMAT_Y210;
18246d12f91SDave Airlie case PLANE_CTL_FORMAT_Y212:
18346d12f91SDave Airlie return DRM_FORMAT_Y212;
18446d12f91SDave Airlie case PLANE_CTL_FORMAT_Y216:
18546d12f91SDave Airlie return DRM_FORMAT_Y216;
18646d12f91SDave Airlie case PLANE_CTL_FORMAT_Y410:
18746d12f91SDave Airlie return DRM_FORMAT_XVYU2101010;
18846d12f91SDave Airlie case PLANE_CTL_FORMAT_Y412:
18946d12f91SDave Airlie return DRM_FORMAT_XVYU12_16161616;
19046d12f91SDave Airlie case PLANE_CTL_FORMAT_Y416:
19146d12f91SDave Airlie return DRM_FORMAT_XVYU16161616;
19246d12f91SDave Airlie default:
19346d12f91SDave Airlie case PLANE_CTL_FORMAT_XRGB_8888:
19446d12f91SDave Airlie if (rgb_order) {
19546d12f91SDave Airlie if (alpha)
19646d12f91SDave Airlie return DRM_FORMAT_ABGR8888;
19746d12f91SDave Airlie else
19846d12f91SDave Airlie return DRM_FORMAT_XBGR8888;
19946d12f91SDave Airlie } else {
20046d12f91SDave Airlie if (alpha)
20146d12f91SDave Airlie return DRM_FORMAT_ARGB8888;
20246d12f91SDave Airlie else
20346d12f91SDave Airlie return DRM_FORMAT_XRGB8888;
20446d12f91SDave Airlie }
20546d12f91SDave Airlie case PLANE_CTL_FORMAT_XRGB_2101010:
20646d12f91SDave Airlie if (rgb_order) {
20746d12f91SDave Airlie if (alpha)
20846d12f91SDave Airlie return DRM_FORMAT_ABGR2101010;
20946d12f91SDave Airlie else
21046d12f91SDave Airlie return DRM_FORMAT_XBGR2101010;
21146d12f91SDave Airlie } else {
21246d12f91SDave Airlie if (alpha)
21346d12f91SDave Airlie return DRM_FORMAT_ARGB2101010;
21446d12f91SDave Airlie else
21546d12f91SDave Airlie return DRM_FORMAT_XRGB2101010;
21646d12f91SDave Airlie }
21746d12f91SDave Airlie case PLANE_CTL_FORMAT_XRGB_16161616F:
21846d12f91SDave Airlie if (rgb_order) {
21946d12f91SDave Airlie if (alpha)
22046d12f91SDave Airlie return DRM_FORMAT_ABGR16161616F;
22146d12f91SDave Airlie else
22246d12f91SDave Airlie return DRM_FORMAT_XBGR16161616F;
22346d12f91SDave Airlie } else {
22446d12f91SDave Airlie if (alpha)
22546d12f91SDave Airlie return DRM_FORMAT_ARGB16161616F;
22646d12f91SDave Airlie else
22746d12f91SDave Airlie return DRM_FORMAT_XRGB16161616F;
22846d12f91SDave Airlie }
22946d12f91SDave Airlie }
23046d12f91SDave Airlie }
23146d12f91SDave Airlie
icl_nv12_y_plane_mask(struct drm_i915_private * i915)23246d12f91SDave Airlie static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
23346d12f91SDave Airlie {
2341649a4ccSMatt Roper if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
23546d12f91SDave Airlie return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3);
23646d12f91SDave Airlie else
23746d12f91SDave Airlie return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5);
23846d12f91SDave Airlie }
23946d12f91SDave Airlie
icl_is_nv12_y_plane(struct drm_i915_private * dev_priv,enum plane_id plane_id)24046d12f91SDave Airlie bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
24146d12f91SDave Airlie enum plane_id plane_id)
24246d12f91SDave Airlie {
243005e9537SMatt Roper return DISPLAY_VER(dev_priv) >= 11 &&
24446d12f91SDave Airlie icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id);
24546d12f91SDave Airlie }
24646d12f91SDave Airlie
icl_hdr_plane_mask(void)247d29c410fSJani Nikula u8 icl_hdr_plane_mask(void)
248d29c410fSJani Nikula {
249d29c410fSJani Nikula return BIT(PLANE_PRIMARY) | BIT(PLANE_SPRITE0) | BIT(PLANE_SPRITE1);
250d29c410fSJani Nikula }
251d29c410fSJani Nikula
icl_is_hdr_plane(struct drm_i915_private * dev_priv,enum plane_id plane_id)25246d12f91SDave Airlie bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
25346d12f91SDave Airlie {
254005e9537SMatt Roper return DISPLAY_VER(dev_priv) >= 11 &&
25546d12f91SDave Airlie icl_hdr_plane_mask() & BIT(plane_id);
25646d12f91SDave Airlie }
25746d12f91SDave Airlie
icl_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)2586195f850SVille Syrjälä static int icl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
2596195f850SVille Syrjälä const struct intel_plane_state *plane_state)
2606195f850SVille Syrjälä {
2616195f850SVille Syrjälä unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
2626195f850SVille Syrjälä
2636195f850SVille Syrjälä /* two pixels per clock */
2646195f850SVille Syrjälä return DIV_ROUND_UP(pixel_rate, 2);
2656195f850SVille Syrjälä }
2666195f850SVille Syrjälä
26746d12f91SDave Airlie static void
glk_plane_ratio(const struct intel_plane_state * plane_state,unsigned int * num,unsigned int * den)268efc52308SVille Syrjälä glk_plane_ratio(const struct intel_plane_state *plane_state,
26946d12f91SDave Airlie unsigned int *num, unsigned int *den)
27046d12f91SDave Airlie {
27146d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
27246d12f91SDave Airlie
27346d12f91SDave Airlie if (fb->format->cpp[0] == 8) {
27446d12f91SDave Airlie *num = 10;
27546d12f91SDave Airlie *den = 8;
27646d12f91SDave Airlie } else {
277efc52308SVille Syrjälä *num = 1;
278efc52308SVille Syrjälä *den = 1;
279efc52308SVille Syrjälä }
280efc52308SVille Syrjälä }
281efc52308SVille Syrjälä
glk_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)282efc52308SVille Syrjälä static int glk_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
283efc52308SVille Syrjälä const struct intel_plane_state *plane_state)
284efc52308SVille Syrjälä {
285efc52308SVille Syrjälä unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
286efc52308SVille Syrjälä unsigned int num, den;
287efc52308SVille Syrjälä
288efc52308SVille Syrjälä glk_plane_ratio(plane_state, &num, &den);
289efc52308SVille Syrjälä
290efc52308SVille Syrjälä /* two pixels per clock */
291efc52308SVille Syrjälä return DIV_ROUND_UP(pixel_rate * num, 2 * den);
292efc52308SVille Syrjälä }
293efc52308SVille Syrjälä
294efc52308SVille Syrjälä static void
skl_plane_ratio(const struct intel_plane_state * plane_state,unsigned int * num,unsigned int * den)295efc52308SVille Syrjälä skl_plane_ratio(const struct intel_plane_state *plane_state,
296efc52308SVille Syrjälä unsigned int *num, unsigned int *den)
297efc52308SVille Syrjälä {
298efc52308SVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
299efc52308SVille Syrjälä
300efc52308SVille Syrjälä if (fb->format->cpp[0] == 8) {
30146d12f91SDave Airlie *num = 9;
30246d12f91SDave Airlie *den = 8;
30346d12f91SDave Airlie } else {
30446d12f91SDave Airlie *num = 1;
30546d12f91SDave Airlie *den = 1;
30646d12f91SDave Airlie }
30746d12f91SDave Airlie }
30846d12f91SDave Airlie
skl_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)30946d12f91SDave Airlie static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
31046d12f91SDave Airlie const struct intel_plane_state *plane_state)
31146d12f91SDave Airlie {
31246d12f91SDave Airlie unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
313efc52308SVille Syrjälä unsigned int num, den;
31446d12f91SDave Airlie
315efc52308SVille Syrjälä skl_plane_ratio(plane_state, &num, &den);
31646d12f91SDave Airlie
31746d12f91SDave Airlie return DIV_ROUND_UP(pixel_rate * num, den);
31846d12f91SDave Airlie }
31946d12f91SDave Airlie
skl_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)32046d12f91SDave Airlie static int skl_plane_max_width(const struct drm_framebuffer *fb,
32146d12f91SDave Airlie int color_plane,
32246d12f91SDave Airlie unsigned int rotation)
32346d12f91SDave Airlie {
32446d12f91SDave Airlie int cpp = fb->format->cpp[color_plane];
32546d12f91SDave Airlie
32646d12f91SDave Airlie switch (fb->modifier) {
32746d12f91SDave Airlie case DRM_FORMAT_MOD_LINEAR:
32846d12f91SDave Airlie case I915_FORMAT_MOD_X_TILED:
32946d12f91SDave Airlie /*
33046d12f91SDave Airlie * Validated limit is 4k, but has 5k should
33146d12f91SDave Airlie * work apart from the following features:
33246d12f91SDave Airlie * - Ytile (already limited to 4k)
33346d12f91SDave Airlie * - FP16 (already limited to 4k)
33446d12f91SDave Airlie * - render compression (already limited to 4k)
33546d12f91SDave Airlie * - KVMR sprite and cursor (don't care)
33646d12f91SDave Airlie * - horizontal panning (TODO verify this)
33746d12f91SDave Airlie * - pipe and plane scaling (TODO verify this)
33846d12f91SDave Airlie */
33946d12f91SDave Airlie if (cpp == 8)
34046d12f91SDave Airlie return 4096;
34146d12f91SDave Airlie else
34246d12f91SDave Airlie return 5120;
34346d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_CCS:
34446d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED_CCS:
34546d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
34646d12f91SDave Airlie /* FIXME AUX plane? */
34746d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED:
34846d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED:
34946d12f91SDave Airlie if (cpp == 8)
35046d12f91SDave Airlie return 2048;
35146d12f91SDave Airlie else
35246d12f91SDave Airlie return 4096;
35346d12f91SDave Airlie default:
35446d12f91SDave Airlie MISSING_CASE(fb->modifier);
35546d12f91SDave Airlie return 2048;
35646d12f91SDave Airlie }
35746d12f91SDave Airlie }
35846d12f91SDave Airlie
glk_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)35946d12f91SDave Airlie static int glk_plane_max_width(const struct drm_framebuffer *fb,
36046d12f91SDave Airlie int color_plane,
36146d12f91SDave Airlie unsigned int rotation)
36246d12f91SDave Airlie {
36346d12f91SDave Airlie int cpp = fb->format->cpp[color_plane];
36446d12f91SDave Airlie
36546d12f91SDave Airlie switch (fb->modifier) {
36646d12f91SDave Airlie case DRM_FORMAT_MOD_LINEAR:
36746d12f91SDave Airlie case I915_FORMAT_MOD_X_TILED:
36846d12f91SDave Airlie if (cpp == 8)
36946d12f91SDave Airlie return 4096;
37046d12f91SDave Airlie else
37146d12f91SDave Airlie return 5120;
37246d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_CCS:
37346d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED_CCS:
37446d12f91SDave Airlie /* FIXME AUX plane? */
37546d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED:
37646d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED:
37746d12f91SDave Airlie if (cpp == 8)
37846d12f91SDave Airlie return 2048;
37946d12f91SDave Airlie else
38046d12f91SDave Airlie return 5120;
38146d12f91SDave Airlie default:
38246d12f91SDave Airlie MISSING_CASE(fb->modifier);
38346d12f91SDave Airlie return 2048;
38446d12f91SDave Airlie }
38546d12f91SDave Airlie }
38646d12f91SDave Airlie
icl_plane_min_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)38746d12f91SDave Airlie static int icl_plane_min_width(const struct drm_framebuffer *fb,
38846d12f91SDave Airlie int color_plane,
38946d12f91SDave Airlie unsigned int rotation)
39046d12f91SDave Airlie {
39146d12f91SDave Airlie /* Wa_14011264657, Wa_14011050563: gen11+ */
39246d12f91SDave Airlie switch (fb->format->format) {
39346d12f91SDave Airlie case DRM_FORMAT_C8:
39446d12f91SDave Airlie return 18;
39546d12f91SDave Airlie case DRM_FORMAT_RGB565:
39646d12f91SDave Airlie return 10;
39746d12f91SDave Airlie case DRM_FORMAT_XRGB8888:
39846d12f91SDave Airlie case DRM_FORMAT_XBGR8888:
39946d12f91SDave Airlie case DRM_FORMAT_ARGB8888:
40046d12f91SDave Airlie case DRM_FORMAT_ABGR8888:
40146d12f91SDave Airlie case DRM_FORMAT_XRGB2101010:
40246d12f91SDave Airlie case DRM_FORMAT_XBGR2101010:
40346d12f91SDave Airlie case DRM_FORMAT_ARGB2101010:
40446d12f91SDave Airlie case DRM_FORMAT_ABGR2101010:
40546d12f91SDave Airlie case DRM_FORMAT_XVYU2101010:
40646d12f91SDave Airlie case DRM_FORMAT_Y212:
40746d12f91SDave Airlie case DRM_FORMAT_Y216:
40846d12f91SDave Airlie return 6;
40946d12f91SDave Airlie case DRM_FORMAT_NV12:
41046d12f91SDave Airlie return 20;
41146d12f91SDave Airlie case DRM_FORMAT_P010:
41246d12f91SDave Airlie case DRM_FORMAT_P012:
41346d12f91SDave Airlie case DRM_FORMAT_P016:
41446d12f91SDave Airlie return 12;
41546d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
41646d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
41746d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
41846d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
41946d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
42046d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
42146d12f91SDave Airlie return 4;
42246d12f91SDave Airlie default:
42346d12f91SDave Airlie return 1;
42446d12f91SDave Airlie }
42546d12f91SDave Airlie }
42646d12f91SDave Airlie
icl_hdr_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)4270e959b4eSVidya Srinivas static int icl_hdr_plane_max_width(const struct drm_framebuffer *fb,
4280e959b4eSVidya Srinivas int color_plane,
4290e959b4eSVidya Srinivas unsigned int rotation)
4300e959b4eSVidya Srinivas {
4310e959b4eSVidya Srinivas if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
4320e959b4eSVidya Srinivas return 4096;
4330e959b4eSVidya Srinivas else
4340e959b4eSVidya Srinivas return 5120;
4350e959b4eSVidya Srinivas }
4360e959b4eSVidya Srinivas
icl_sdr_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)4370e959b4eSVidya Srinivas static int icl_sdr_plane_max_width(const struct drm_framebuffer *fb,
43846d12f91SDave Airlie int color_plane,
43946d12f91SDave Airlie unsigned int rotation)
44046d12f91SDave Airlie {
44146d12f91SDave Airlie return 5120;
44246d12f91SDave Airlie }
44346d12f91SDave Airlie
skl_plane_max_height(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)44446d12f91SDave Airlie static int skl_plane_max_height(const struct drm_framebuffer *fb,
44546d12f91SDave Airlie int color_plane,
44646d12f91SDave Airlie unsigned int rotation)
44746d12f91SDave Airlie {
44846d12f91SDave Airlie return 4096;
44946d12f91SDave Airlie }
45046d12f91SDave Airlie
icl_plane_max_height(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)45146d12f91SDave Airlie static int icl_plane_max_height(const struct drm_framebuffer *fb,
45246d12f91SDave Airlie int color_plane,
45346d12f91SDave Airlie unsigned int rotation)
45446d12f91SDave Airlie {
45546d12f91SDave Airlie return 4320;
45646d12f91SDave Airlie }
45746d12f91SDave Airlie
45846d12f91SDave Airlie static unsigned int
skl_plane_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation)45946d12f91SDave Airlie skl_plane_max_stride(struct intel_plane *plane,
46046d12f91SDave Airlie u32 pixel_format, u64 modifier,
46146d12f91SDave Airlie unsigned int rotation)
46246d12f91SDave Airlie {
463e7367af1SJuha-Pekka Heikkilä struct drm_i915_private *i915 = to_i915(plane->base.dev);
46446d12f91SDave Airlie const struct drm_format_info *info = drm_format_info(pixel_format);
46546d12f91SDave Airlie int cpp = info->cpp[0];
466e7367af1SJuha-Pekka Heikkilä int max_horizontal_pixels = 8192;
467e7367af1SJuha-Pekka Heikkilä int max_stride_bytes;
46846d12f91SDave Airlie
469e7367af1SJuha-Pekka Heikkilä if (DISPLAY_VER(i915) >= 13) {
470e7367af1SJuha-Pekka Heikkilä /*
471e7367af1SJuha-Pekka Heikkilä * The stride in bytes must not exceed of the size
472e7367af1SJuha-Pekka Heikkilä * of 128K bytes. For pixel formats of 64bpp will allow
473e7367af1SJuha-Pekka Heikkilä * for a 16K pixel surface.
474e7367af1SJuha-Pekka Heikkilä */
475e7367af1SJuha-Pekka Heikkilä max_stride_bytes = 131072;
476e7367af1SJuha-Pekka Heikkilä if (cpp == 8)
477e7367af1SJuha-Pekka Heikkilä max_horizontal_pixels = 16384;
478e7367af1SJuha-Pekka Heikkilä else
479e7367af1SJuha-Pekka Heikkilä max_horizontal_pixels = 65536;
480e7367af1SJuha-Pekka Heikkilä } else {
48146d12f91SDave Airlie /*
48246d12f91SDave Airlie * "The stride in bytes must not exceed the
48346d12f91SDave Airlie * of the size of 8K pixels and 32K bytes."
48446d12f91SDave Airlie */
485e7367af1SJuha-Pekka Heikkilä max_stride_bytes = 32768;
486e7367af1SJuha-Pekka Heikkilä }
487e7367af1SJuha-Pekka Heikkilä
48846d12f91SDave Airlie if (drm_rotation_90_or_270(rotation))
489e7367af1SJuha-Pekka Heikkilä return min(max_horizontal_pixels, max_stride_bytes / cpp);
49046d12f91SDave Airlie else
491e7367af1SJuha-Pekka Heikkilä return min(max_horizontal_pixels * cpp, max_stride_bytes);
49246d12f91SDave Airlie }
49346d12f91SDave Airlie
49446d12f91SDave Airlie
49546d12f91SDave Airlie /* Preoffset values for YUV to RGB Conversion */
49646d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_HI 0x1800
49746d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_ME 0x0000
49846d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_LO 0x1800
49946d12f91SDave Airlie
50046d12f91SDave Airlie #define ROFF(x) (((x) & 0xffff) << 16)
50146d12f91SDave Airlie #define GOFF(x) (((x) & 0xffff) << 0)
50246d12f91SDave Airlie #define BOFF(x) (((x) & 0xffff) << 16)
50346d12f91SDave Airlie
50446d12f91SDave Airlie /*
50546d12f91SDave Airlie * Programs the input color space conversion stage for ICL HDR planes.
50646d12f91SDave Airlie * Note that it is assumed that this stage always happens after YUV
50746d12f91SDave Airlie * range correction. Thus, the input to this stage is assumed to be
50846d12f91SDave Airlie * in full-range YCbCr.
50946d12f91SDave Airlie */
51046d12f91SDave Airlie static void
icl_program_input_csc(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)51146d12f91SDave Airlie icl_program_input_csc(struct intel_plane *plane,
51246d12f91SDave Airlie const struct intel_crtc_state *crtc_state,
51346d12f91SDave Airlie const struct intel_plane_state *plane_state)
51446d12f91SDave Airlie {
51546d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
51646d12f91SDave Airlie enum pipe pipe = plane->pipe;
51746d12f91SDave Airlie enum plane_id plane_id = plane->id;
51846d12f91SDave Airlie
51946d12f91SDave Airlie static const u16 input_csc_matrix[][9] = {
52046d12f91SDave Airlie /*
52146d12f91SDave Airlie * BT.601 full range YCbCr -> full range RGB
52246d12f91SDave Airlie * The matrix required is :
52346d12f91SDave Airlie * [1.000, 0.000, 1.371,
52446d12f91SDave Airlie * 1.000, -0.336, -0.698,
52546d12f91SDave Airlie * 1.000, 1.732, 0.0000]
52646d12f91SDave Airlie */
52746d12f91SDave Airlie [DRM_COLOR_YCBCR_BT601] = {
52846d12f91SDave Airlie 0x7AF8, 0x7800, 0x0,
52946d12f91SDave Airlie 0x8B28, 0x7800, 0x9AC0,
53046d12f91SDave Airlie 0x0, 0x7800, 0x7DD8,
53146d12f91SDave Airlie },
53246d12f91SDave Airlie /*
53346d12f91SDave Airlie * BT.709 full range YCbCr -> full range RGB
53446d12f91SDave Airlie * The matrix required is :
53546d12f91SDave Airlie * [1.000, 0.000, 1.574,
53646d12f91SDave Airlie * 1.000, -0.187, -0.468,
53746d12f91SDave Airlie * 1.000, 1.855, 0.0000]
53846d12f91SDave Airlie */
53946d12f91SDave Airlie [DRM_COLOR_YCBCR_BT709] = {
54046d12f91SDave Airlie 0x7C98, 0x7800, 0x0,
54146d12f91SDave Airlie 0x9EF8, 0x7800, 0xAC00,
54246d12f91SDave Airlie 0x0, 0x7800, 0x7ED8,
54346d12f91SDave Airlie },
54446d12f91SDave Airlie /*
54546d12f91SDave Airlie * BT.2020 full range YCbCr -> full range RGB
54646d12f91SDave Airlie * The matrix required is :
54746d12f91SDave Airlie * [1.000, 0.000, 1.474,
54846d12f91SDave Airlie * 1.000, -0.1645, -0.5713,
54946d12f91SDave Airlie * 1.000, 1.8814, 0.0000]
55046d12f91SDave Airlie */
55146d12f91SDave Airlie [DRM_COLOR_YCBCR_BT2020] = {
55246d12f91SDave Airlie 0x7BC8, 0x7800, 0x0,
55346d12f91SDave Airlie 0x8928, 0x7800, 0xAA88,
55446d12f91SDave Airlie 0x0, 0x7800, 0x7F10,
55546d12f91SDave Airlie },
55646d12f91SDave Airlie };
55746d12f91SDave Airlie const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding];
55846d12f91SDave Airlie
55946d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
56046d12f91SDave Airlie ROFF(csc[0]) | GOFF(csc[1]));
56146d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
56246d12f91SDave Airlie BOFF(csc[2]));
56346d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
56446d12f91SDave Airlie ROFF(csc[3]) | GOFF(csc[4]));
56546d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
56646d12f91SDave Airlie BOFF(csc[5]));
56746d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
56846d12f91SDave Airlie ROFF(csc[6]) | GOFF(csc[7]));
56946d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
57046d12f91SDave Airlie BOFF(csc[8]));
57146d12f91SDave Airlie
57246d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
57346d12f91SDave Airlie PREOFF_YUV_TO_RGB_HI);
57446d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
57546d12f91SDave Airlie PREOFF_YUV_TO_RGB_ME);
57646d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
57746d12f91SDave Airlie PREOFF_YUV_TO_RGB_LO);
57846d12f91SDave Airlie intel_de_write_fw(dev_priv,
57946d12f91SDave Airlie PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
58046d12f91SDave Airlie intel_de_write_fw(dev_priv,
58146d12f91SDave Airlie PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
58246d12f91SDave Airlie intel_de_write_fw(dev_priv,
58346d12f91SDave Airlie PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
58446d12f91SDave Airlie }
58546d12f91SDave Airlie
skl_plane_stride_mult(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)58646d12f91SDave Airlie static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
58746d12f91SDave Airlie int color_plane, unsigned int rotation)
58846d12f91SDave Airlie {
58946d12f91SDave Airlie /*
59046d12f91SDave Airlie * The stride is either expressed as a multiple of 64 bytes chunks for
59146d12f91SDave Airlie * linear buffers or in number of tiles for tiled buffers.
59246d12f91SDave Airlie */
59346d12f91SDave Airlie if (is_surface_linear(fb, color_plane))
59446d12f91SDave Airlie return 64;
59546d12f91SDave Airlie else if (drm_rotation_90_or_270(rotation))
59646d12f91SDave Airlie return intel_tile_height(fb, color_plane);
59746d12f91SDave Airlie else
59846d12f91SDave Airlie return intel_tile_width_bytes(fb, color_plane);
59946d12f91SDave Airlie }
60046d12f91SDave Airlie
skl_plane_stride(const struct intel_plane_state * plane_state,int color_plane)60146d12f91SDave Airlie static u32 skl_plane_stride(const struct intel_plane_state *plane_state,
60246d12f91SDave Airlie int color_plane)
60346d12f91SDave Airlie {
60446d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
60546d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
606e6d6f689SImre Deak u32 stride = plane_state->view.color_plane[color_plane].scanout_stride;
60746d12f91SDave Airlie
60846d12f91SDave Airlie if (color_plane >= fb->format->num_planes)
60946d12f91SDave Airlie return 0;
61046d12f91SDave Airlie
61146d12f91SDave Airlie return stride / skl_plane_stride_mult(fb, color_plane, rotation);
61246d12f91SDave Airlie }
61346d12f91SDave Airlie
61446d12f91SDave Airlie static void
skl_plane_disable_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)6158ac80733SVille Syrjälä skl_plane_disable_arm(struct intel_plane *plane,
61646d12f91SDave Airlie const struct intel_crtc_state *crtc_state)
61746d12f91SDave Airlie {
61846d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
61946d12f91SDave Airlie enum plane_id plane_id = plane->id;
62046d12f91SDave Airlie enum pipe pipe = plane->pipe;
62146d12f91SDave Airlie
622f8a005ebSVille Syrjälä skl_write_plane_wm(plane, crtc_state);
623f8a005ebSVille Syrjälä
624f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
625f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
626f8a005ebSVille Syrjälä }
627f8a005ebSVille Syrjälä
628f8a005ebSVille Syrjälä static void
icl_plane_disable_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)629f8a005ebSVille Syrjälä icl_plane_disable_arm(struct intel_plane *plane,
630f8a005ebSVille Syrjälä const struct intel_crtc_state *crtc_state)
631f8a005ebSVille Syrjälä {
632f8a005ebSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
633f8a005ebSVille Syrjälä enum plane_id plane_id = plane->id;
634f8a005ebSVille Syrjälä enum pipe pipe = plane->pipe;
635f8a005ebSVille Syrjälä
63646d12f91SDave Airlie if (icl_is_hdr_plane(dev_priv, plane_id))
63746d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
63846d12f91SDave Airlie
63946d12f91SDave Airlie skl_write_plane_wm(plane, crtc_state);
64046d12f91SDave Airlie
641c22cf04cSJouni Högander intel_psr2_disable_plane_sel_fetch_arm(plane, crtc_state);
64246d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
64346d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
64446d12f91SDave Airlie }
64546d12f91SDave Airlie
64646d12f91SDave Airlie static bool
skl_plane_get_hw_state(struct intel_plane * plane,enum pipe * pipe)64746d12f91SDave Airlie skl_plane_get_hw_state(struct intel_plane *plane,
64846d12f91SDave Airlie enum pipe *pipe)
64946d12f91SDave Airlie {
65046d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
65146d12f91SDave Airlie enum intel_display_power_domain power_domain;
65246d12f91SDave Airlie enum plane_id plane_id = plane->id;
65346d12f91SDave Airlie intel_wakeref_t wakeref;
65446d12f91SDave Airlie bool ret;
65546d12f91SDave Airlie
65646d12f91SDave Airlie power_domain = POWER_DOMAIN_PIPE(plane->pipe);
65746d12f91SDave Airlie wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
65846d12f91SDave Airlie if (!wakeref)
65946d12f91SDave Airlie return false;
66046d12f91SDave Airlie
66146d12f91SDave Airlie ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
66246d12f91SDave Airlie
66346d12f91SDave Airlie *pipe = plane->pipe;
66446d12f91SDave Airlie
66546d12f91SDave Airlie intel_display_power_put(dev_priv, power_domain, wakeref);
66646d12f91SDave Airlie
66746d12f91SDave Airlie return ret;
66846d12f91SDave Airlie }
66946d12f91SDave Airlie
skl_plane_ctl_format(u32 pixel_format)67046d12f91SDave Airlie static u32 skl_plane_ctl_format(u32 pixel_format)
67146d12f91SDave Airlie {
67246d12f91SDave Airlie switch (pixel_format) {
67346d12f91SDave Airlie case DRM_FORMAT_C8:
67446d12f91SDave Airlie return PLANE_CTL_FORMAT_INDEXED;
67546d12f91SDave Airlie case DRM_FORMAT_RGB565:
67646d12f91SDave Airlie return PLANE_CTL_FORMAT_RGB_565;
67746d12f91SDave Airlie case DRM_FORMAT_XBGR8888:
67846d12f91SDave Airlie case DRM_FORMAT_ABGR8888:
67946d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
68046d12f91SDave Airlie case DRM_FORMAT_XRGB8888:
68146d12f91SDave Airlie case DRM_FORMAT_ARGB8888:
68246d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_8888;
68346d12f91SDave Airlie case DRM_FORMAT_XBGR2101010:
68446d12f91SDave Airlie case DRM_FORMAT_ABGR2101010:
68546d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_2101010 | PLANE_CTL_ORDER_RGBX;
68646d12f91SDave Airlie case DRM_FORMAT_XRGB2101010:
68746d12f91SDave Airlie case DRM_FORMAT_ARGB2101010:
68846d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_2101010;
68946d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
69046d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
69146d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
69246d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
69346d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
69446d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_16161616F;
69546d12f91SDave Airlie case DRM_FORMAT_XYUV8888:
69646d12f91SDave Airlie return PLANE_CTL_FORMAT_XYUV;
69746d12f91SDave Airlie case DRM_FORMAT_YUYV:
69862f887aeSVille Syrjälä return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_YUYV;
69946d12f91SDave Airlie case DRM_FORMAT_YVYU:
70062f887aeSVille Syrjälä return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_YVYU;
70146d12f91SDave Airlie case DRM_FORMAT_UYVY:
70262f887aeSVille Syrjälä return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_UYVY;
70346d12f91SDave Airlie case DRM_FORMAT_VYUY:
70462f887aeSVille Syrjälä return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_VYUY;
70546d12f91SDave Airlie case DRM_FORMAT_NV12:
70646d12f91SDave Airlie return PLANE_CTL_FORMAT_NV12;
70746d12f91SDave Airlie case DRM_FORMAT_P010:
70846d12f91SDave Airlie return PLANE_CTL_FORMAT_P010;
70946d12f91SDave Airlie case DRM_FORMAT_P012:
71046d12f91SDave Airlie return PLANE_CTL_FORMAT_P012;
71146d12f91SDave Airlie case DRM_FORMAT_P016:
71246d12f91SDave Airlie return PLANE_CTL_FORMAT_P016;
71346d12f91SDave Airlie case DRM_FORMAT_Y210:
71446d12f91SDave Airlie return PLANE_CTL_FORMAT_Y210;
71546d12f91SDave Airlie case DRM_FORMAT_Y212:
71646d12f91SDave Airlie return PLANE_CTL_FORMAT_Y212;
71746d12f91SDave Airlie case DRM_FORMAT_Y216:
71846d12f91SDave Airlie return PLANE_CTL_FORMAT_Y216;
71946d12f91SDave Airlie case DRM_FORMAT_XVYU2101010:
72046d12f91SDave Airlie return PLANE_CTL_FORMAT_Y410;
72146d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
72246d12f91SDave Airlie return PLANE_CTL_FORMAT_Y412;
72346d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
72446d12f91SDave Airlie return PLANE_CTL_FORMAT_Y416;
72546d12f91SDave Airlie default:
72646d12f91SDave Airlie MISSING_CASE(pixel_format);
72746d12f91SDave Airlie }
72846d12f91SDave Airlie
72946d12f91SDave Airlie return 0;
73046d12f91SDave Airlie }
73146d12f91SDave Airlie
skl_plane_ctl_alpha(const struct intel_plane_state * plane_state)73246d12f91SDave Airlie static u32 skl_plane_ctl_alpha(const struct intel_plane_state *plane_state)
73346d12f91SDave Airlie {
73446d12f91SDave Airlie if (!plane_state->hw.fb->format->has_alpha)
73546d12f91SDave Airlie return PLANE_CTL_ALPHA_DISABLE;
73646d12f91SDave Airlie
73746d12f91SDave Airlie switch (plane_state->hw.pixel_blend_mode) {
73846d12f91SDave Airlie case DRM_MODE_BLEND_PIXEL_NONE:
73946d12f91SDave Airlie return PLANE_CTL_ALPHA_DISABLE;
74046d12f91SDave Airlie case DRM_MODE_BLEND_PREMULTI:
74146d12f91SDave Airlie return PLANE_CTL_ALPHA_SW_PREMULTIPLY;
74246d12f91SDave Airlie case DRM_MODE_BLEND_COVERAGE:
74346d12f91SDave Airlie return PLANE_CTL_ALPHA_HW_PREMULTIPLY;
74446d12f91SDave Airlie default:
74546d12f91SDave Airlie MISSING_CASE(plane_state->hw.pixel_blend_mode);
74646d12f91SDave Airlie return PLANE_CTL_ALPHA_DISABLE;
74746d12f91SDave Airlie }
74846d12f91SDave Airlie }
74946d12f91SDave Airlie
glk_plane_color_ctl_alpha(const struct intel_plane_state * plane_state)75046d12f91SDave Airlie static u32 glk_plane_color_ctl_alpha(const struct intel_plane_state *plane_state)
75146d12f91SDave Airlie {
75246d12f91SDave Airlie if (!plane_state->hw.fb->format->has_alpha)
75346d12f91SDave Airlie return PLANE_COLOR_ALPHA_DISABLE;
75446d12f91SDave Airlie
75546d12f91SDave Airlie switch (plane_state->hw.pixel_blend_mode) {
75646d12f91SDave Airlie case DRM_MODE_BLEND_PIXEL_NONE:
75746d12f91SDave Airlie return PLANE_COLOR_ALPHA_DISABLE;
75846d12f91SDave Airlie case DRM_MODE_BLEND_PREMULTI:
75946d12f91SDave Airlie return PLANE_COLOR_ALPHA_SW_PREMULTIPLY;
76046d12f91SDave Airlie case DRM_MODE_BLEND_COVERAGE:
76146d12f91SDave Airlie return PLANE_COLOR_ALPHA_HW_PREMULTIPLY;
76246d12f91SDave Airlie default:
76346d12f91SDave Airlie MISSING_CASE(plane_state->hw.pixel_blend_mode);
76446d12f91SDave Airlie return PLANE_COLOR_ALPHA_DISABLE;
76546d12f91SDave Airlie }
76646d12f91SDave Airlie }
76746d12f91SDave Airlie
skl_plane_ctl_tiling(u64 fb_modifier)76846d12f91SDave Airlie static u32 skl_plane_ctl_tiling(u64 fb_modifier)
76946d12f91SDave Airlie {
77046d12f91SDave Airlie switch (fb_modifier) {
77146d12f91SDave Airlie case DRM_FORMAT_MOD_LINEAR:
77246d12f91SDave Airlie break;
77346d12f91SDave Airlie case I915_FORMAT_MOD_X_TILED:
77446d12f91SDave Airlie return PLANE_CTL_TILED_X;
77546d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED:
77646d12f91SDave Airlie return PLANE_CTL_TILED_Y;
777072ce416SStanislav Lisovskiy case I915_FORMAT_MOD_4_TILED:
778072ce416SStanislav Lisovskiy return PLANE_CTL_TILED_4;
7794c3afa72SMatt Roper case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
7804c3afa72SMatt Roper return PLANE_CTL_TILED_4 |
7814c3afa72SMatt Roper PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
7824c3afa72SMatt Roper PLANE_CTL_CLEAR_COLOR_DISABLE;
7834c3afa72SMatt Roper case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
7844c3afa72SMatt Roper return PLANE_CTL_TILED_4 |
7854c3afa72SMatt Roper PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE |
7864c3afa72SMatt Roper PLANE_CTL_CLEAR_COLOR_DISABLE;
787680025dcSJuha-Pekka Heikkilä case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
788680025dcSJuha-Pekka Heikkilä return PLANE_CTL_TILED_4 | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
789f2eb43f0SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
790f2eb43f0SJuha-Pekka Heikkila return PLANE_CTL_TILED_4 |
791f2eb43f0SJuha-Pekka Heikkila PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
792f2eb43f0SJuha-Pekka Heikkila PLANE_CTL_CLEAR_COLOR_DISABLE;
793f2eb43f0SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
794f2eb43f0SJuha-Pekka Heikkila return PLANE_CTL_TILED_4 | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
795f2eb43f0SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
796f2eb43f0SJuha-Pekka Heikkila return PLANE_CTL_TILED_4 | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
79746d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_CCS:
79846d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
79946d12f91SDave Airlie return PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
80046d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
80146d12f91SDave Airlie return PLANE_CTL_TILED_Y |
80246d12f91SDave Airlie PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
80346d12f91SDave Airlie PLANE_CTL_CLEAR_COLOR_DISABLE;
80446d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
80546d12f91SDave Airlie return PLANE_CTL_TILED_Y | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
80646d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED:
80746d12f91SDave Airlie return PLANE_CTL_TILED_YF;
80846d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED_CCS:
80946d12f91SDave Airlie return PLANE_CTL_TILED_YF | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
81046d12f91SDave Airlie default:
81146d12f91SDave Airlie MISSING_CASE(fb_modifier);
81246d12f91SDave Airlie }
81346d12f91SDave Airlie
81446d12f91SDave Airlie return 0;
81546d12f91SDave Airlie }
81646d12f91SDave Airlie
skl_plane_ctl_rotate(unsigned int rotate)81746d12f91SDave Airlie static u32 skl_plane_ctl_rotate(unsigned int rotate)
81846d12f91SDave Airlie {
81946d12f91SDave Airlie switch (rotate) {
82046d12f91SDave Airlie case DRM_MODE_ROTATE_0:
82146d12f91SDave Airlie break;
82246d12f91SDave Airlie /*
82346d12f91SDave Airlie * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
82446d12f91SDave Airlie * while i915 HW rotation is clockwise, thats why this swapping.
82546d12f91SDave Airlie */
82646d12f91SDave Airlie case DRM_MODE_ROTATE_90:
82746d12f91SDave Airlie return PLANE_CTL_ROTATE_270;
82846d12f91SDave Airlie case DRM_MODE_ROTATE_180:
82946d12f91SDave Airlie return PLANE_CTL_ROTATE_180;
83046d12f91SDave Airlie case DRM_MODE_ROTATE_270:
83146d12f91SDave Airlie return PLANE_CTL_ROTATE_90;
83246d12f91SDave Airlie default:
83346d12f91SDave Airlie MISSING_CASE(rotate);
83446d12f91SDave Airlie }
83546d12f91SDave Airlie
83646d12f91SDave Airlie return 0;
83746d12f91SDave Airlie }
83846d12f91SDave Airlie
icl_plane_ctl_flip(unsigned int reflect)839c988d2dcSLucas De Marchi static u32 icl_plane_ctl_flip(unsigned int reflect)
84046d12f91SDave Airlie {
84146d12f91SDave Airlie switch (reflect) {
84246d12f91SDave Airlie case 0:
84346d12f91SDave Airlie break;
84446d12f91SDave Airlie case DRM_MODE_REFLECT_X:
84546d12f91SDave Airlie return PLANE_CTL_FLIP_HORIZONTAL;
84646d12f91SDave Airlie case DRM_MODE_REFLECT_Y:
84746d12f91SDave Airlie default:
84846d12f91SDave Airlie MISSING_CASE(reflect);
84946d12f91SDave Airlie }
85046d12f91SDave Airlie
85146d12f91SDave Airlie return 0;
85246d12f91SDave Airlie }
85346d12f91SDave Airlie
adlp_plane_ctl_arb_slots(const struct intel_plane_state * plane_state)8540b86952dSVille Syrjälä static u32 adlp_plane_ctl_arb_slots(const struct intel_plane_state *plane_state)
8550b86952dSVille Syrjälä {
8560b86952dSVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
8570b86952dSVille Syrjälä
8580b86952dSVille Syrjälä if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
8590b86952dSVille Syrjälä switch (fb->format->cpp[0]) {
8600b86952dSVille Syrjälä case 2:
8610b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(1);
8620b86952dSVille Syrjälä default:
8630b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(0);
8640b86952dSVille Syrjälä }
8650b86952dSVille Syrjälä } else {
8660b86952dSVille Syrjälä switch (fb->format->cpp[0]) {
8670b86952dSVille Syrjälä case 8:
8680b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(3);
8690b86952dSVille Syrjälä case 4:
8700b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(1);
8710b86952dSVille Syrjälä default:
8720b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(0);
8730b86952dSVille Syrjälä }
8740b86952dSVille Syrjälä }
8750b86952dSVille Syrjälä }
8760b86952dSVille Syrjälä
skl_plane_ctl_crtc(const struct intel_crtc_state * crtc_state)87746d12f91SDave Airlie static u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
87846d12f91SDave Airlie {
87946d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
88046d12f91SDave Airlie u32 plane_ctl = 0;
88146d12f91SDave Airlie
8822b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10)
88346d12f91SDave Airlie return plane_ctl;
88446d12f91SDave Airlie
88546d12f91SDave Airlie if (crtc_state->gamma_enable)
88646d12f91SDave Airlie plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE;
88746d12f91SDave Airlie
88846d12f91SDave Airlie if (crtc_state->csc_enable)
88946d12f91SDave Airlie plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
89046d12f91SDave Airlie
89146d12f91SDave Airlie return plane_ctl;
89246d12f91SDave Airlie }
89346d12f91SDave Airlie
skl_plane_ctl(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)89446d12f91SDave Airlie static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
89546d12f91SDave Airlie const struct intel_plane_state *plane_state)
89646d12f91SDave Airlie {
89746d12f91SDave Airlie struct drm_i915_private *dev_priv =
89846d12f91SDave Airlie to_i915(plane_state->uapi.plane->dev);
89946d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
90046d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
90146d12f91SDave Airlie const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
90246d12f91SDave Airlie u32 plane_ctl;
90346d12f91SDave Airlie
90446d12f91SDave Airlie plane_ctl = PLANE_CTL_ENABLE;
90546d12f91SDave Airlie
906ad314fecSVille Syrjälä if (DISPLAY_VER(dev_priv) < 10) {
90746d12f91SDave Airlie plane_ctl |= skl_plane_ctl_alpha(plane_state);
90846d12f91SDave Airlie plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
90946d12f91SDave Airlie
91046d12f91SDave Airlie if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
91146d12f91SDave Airlie plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709;
91246d12f91SDave Airlie
91346d12f91SDave Airlie if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
91446d12f91SDave Airlie plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE;
91546d12f91SDave Airlie }
91646d12f91SDave Airlie
91746d12f91SDave Airlie plane_ctl |= skl_plane_ctl_format(fb->format->format);
91846d12f91SDave Airlie plane_ctl |= skl_plane_ctl_tiling(fb->modifier);
91946d12f91SDave Airlie plane_ctl |= skl_plane_ctl_rotate(rotation & DRM_MODE_ROTATE_MASK);
92046d12f91SDave Airlie
921c988d2dcSLucas De Marchi if (DISPLAY_VER(dev_priv) >= 11)
922c988d2dcSLucas De Marchi plane_ctl |= icl_plane_ctl_flip(rotation &
92346d12f91SDave Airlie DRM_MODE_REFLECT_MASK);
92446d12f91SDave Airlie
92546d12f91SDave Airlie if (key->flags & I915_SET_COLORKEY_DESTINATION)
92646d12f91SDave Airlie plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
92746d12f91SDave Airlie else if (key->flags & I915_SET_COLORKEY_SOURCE)
92846d12f91SDave Airlie plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
92946d12f91SDave Airlie
9301d2b8fd9SJosé Roberto de Souza /* Wa_22012358565:adl-p */
9310b86952dSVille Syrjälä if (DISPLAY_VER(dev_priv) == 13)
9320b86952dSVille Syrjälä plane_ctl |= adlp_plane_ctl_arb_slots(plane_state);
9330b86952dSVille Syrjälä
93446d12f91SDave Airlie return plane_ctl;
93546d12f91SDave Airlie }
93646d12f91SDave Airlie
glk_plane_color_ctl_crtc(const struct intel_crtc_state * crtc_state)93746d12f91SDave Airlie static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
93846d12f91SDave Airlie {
93946d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
94046d12f91SDave Airlie u32 plane_color_ctl = 0;
94146d12f91SDave Airlie
942005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11)
94346d12f91SDave Airlie return plane_color_ctl;
94446d12f91SDave Airlie
94546d12f91SDave Airlie if (crtc_state->gamma_enable)
94646d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
94746d12f91SDave Airlie
94846d12f91SDave Airlie if (crtc_state->csc_enable)
94946d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
95046d12f91SDave Airlie
95146d12f91SDave Airlie return plane_color_ctl;
95246d12f91SDave Airlie }
95346d12f91SDave Airlie
glk_plane_color_ctl(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)95446d12f91SDave Airlie static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
95546d12f91SDave Airlie const struct intel_plane_state *plane_state)
95646d12f91SDave Airlie {
95746d12f91SDave Airlie struct drm_i915_private *dev_priv =
95846d12f91SDave Airlie to_i915(plane_state->uapi.plane->dev);
95946d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
96046d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
96146d12f91SDave Airlie u32 plane_color_ctl = 0;
96246d12f91SDave Airlie
96346d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
96446d12f91SDave Airlie plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
96546d12f91SDave Airlie
96646d12f91SDave Airlie if (fb->format->is_yuv && !icl_is_hdr_plane(dev_priv, plane->id)) {
96746d12f91SDave Airlie switch (plane_state->hw.color_encoding) {
96846d12f91SDave Airlie case DRM_COLOR_YCBCR_BT709:
96946d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
97046d12f91SDave Airlie break;
97146d12f91SDave Airlie case DRM_COLOR_YCBCR_BT2020:
97246d12f91SDave Airlie plane_color_ctl |=
97346d12f91SDave Airlie PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
97446d12f91SDave Airlie break;
97546d12f91SDave Airlie default:
97646d12f91SDave Airlie plane_color_ctl |=
97746d12f91SDave Airlie PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
97846d12f91SDave Airlie }
97946d12f91SDave Airlie if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
98046d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
98146d12f91SDave Airlie } else if (fb->format->is_yuv) {
98246d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
98346d12f91SDave Airlie if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
98446d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
98546d12f91SDave Airlie }
98646d12f91SDave Airlie
987841f262eSVille Syrjälä if (plane_state->force_black)
988841f262eSVille Syrjälä plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
989841f262eSVille Syrjälä
99046d12f91SDave Airlie return plane_color_ctl;
99146d12f91SDave Airlie }
99246d12f91SDave Airlie
skl_surf_address(const struct intel_plane_state * plane_state,int color_plane)99333e7a975SVille Syrjälä static u32 skl_surf_address(const struct intel_plane_state *plane_state,
99433e7a975SVille Syrjälä int color_plane)
99533e7a975SVille Syrjälä {
9965acbdcd1SJani Nikula struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
99733e7a975SVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
99833e7a975SVille Syrjälä u32 offset = plane_state->view.color_plane[color_plane].offset;
99933e7a975SVille Syrjälä
100033e7a975SVille Syrjälä if (intel_fb_uses_dpt(fb)) {
100192dff6c7SImre Deak /*
100292dff6c7SImre Deak * The DPT object contains only one vma, so the VMA's offset
100392dff6c7SImre Deak * within the DPT is always 0.
100492dff6c7SImre Deak */
10055acbdcd1SJani Nikula drm_WARN_ON(&i915->drm, plane_state->dpt_vma->node.start);
10065acbdcd1SJani Nikula drm_WARN_ON(&i915->drm, offset & 0x1fffff);
100733e7a975SVille Syrjälä return offset >> 9;
100833e7a975SVille Syrjälä } else {
10095acbdcd1SJani Nikula drm_WARN_ON(&i915->drm, offset & 0xfff);
101033e7a975SVille Syrjälä return offset;
101133e7a975SVille Syrjälä }
101233e7a975SVille Syrjälä }
101333e7a975SVille Syrjälä
skl_plane_surf(const struct intel_plane_state * plane_state,int color_plane)101450faf7a1SVille Syrjälä static u32 skl_plane_surf(const struct intel_plane_state *plane_state,
101550faf7a1SVille Syrjälä int color_plane)
101650faf7a1SVille Syrjälä {
101750faf7a1SVille Syrjälä u32 plane_surf;
101850faf7a1SVille Syrjälä
101950faf7a1SVille Syrjälä plane_surf = intel_plane_ggtt_offset(plane_state) +
102050faf7a1SVille Syrjälä skl_surf_address(plane_state, color_plane);
102150faf7a1SVille Syrjälä
102250faf7a1SVille Syrjälä if (plane_state->decrypt)
102350faf7a1SVille Syrjälä plane_surf |= PLANE_SURF_DECRYPT;
102450faf7a1SVille Syrjälä
102550faf7a1SVille Syrjälä return plane_surf;
102650faf7a1SVille Syrjälä }
102750faf7a1SVille Syrjälä
skl_plane_aux_dist(const struct intel_plane_state * plane_state,int color_plane)1028366714b0SVille Syrjälä static u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state,
1029366714b0SVille Syrjälä int color_plane)
1030366714b0SVille Syrjälä {
1031366714b0SVille Syrjälä struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
1032366714b0SVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
1033366714b0SVille Syrjälä int aux_plane = skl_main_to_aux_plane(fb, color_plane);
1034366714b0SVille Syrjälä u32 aux_dist;
1035366714b0SVille Syrjälä
1036366714b0SVille Syrjälä if (!aux_plane)
1037366714b0SVille Syrjälä return 0;
1038366714b0SVille Syrjälä
1039366714b0SVille Syrjälä aux_dist = skl_surf_address(plane_state, aux_plane) -
1040366714b0SVille Syrjälä skl_surf_address(plane_state, color_plane);
1041366714b0SVille Syrjälä
1042366714b0SVille Syrjälä if (DISPLAY_VER(i915) < 12)
1043366714b0SVille Syrjälä aux_dist |= PLANE_AUX_STRIDE(skl_plane_stride(plane_state, aux_plane));
1044366714b0SVille Syrjälä
1045366714b0SVille Syrjälä return aux_dist;
1046366714b0SVille Syrjälä }
1047366714b0SVille Syrjälä
skl_plane_keyval(const struct intel_plane_state * plane_state)10484682a6d9SVille Syrjälä static u32 skl_plane_keyval(const struct intel_plane_state *plane_state)
10494682a6d9SVille Syrjälä {
10504682a6d9SVille Syrjälä const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
10514682a6d9SVille Syrjälä
10524682a6d9SVille Syrjälä return key->min_value;
10534682a6d9SVille Syrjälä }
10544682a6d9SVille Syrjälä
skl_plane_keymax(const struct intel_plane_state * plane_state)10554682a6d9SVille Syrjälä static u32 skl_plane_keymax(const struct intel_plane_state *plane_state)
10564682a6d9SVille Syrjälä {
10574682a6d9SVille Syrjälä const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
10584682a6d9SVille Syrjälä u8 alpha = plane_state->hw.alpha >> 8;
10594682a6d9SVille Syrjälä
10604682a6d9SVille Syrjälä return (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
10614682a6d9SVille Syrjälä }
10624682a6d9SVille Syrjälä
skl_plane_keymsk(const struct intel_plane_state * plane_state)10634682a6d9SVille Syrjälä static u32 skl_plane_keymsk(const struct intel_plane_state *plane_state)
10644682a6d9SVille Syrjälä {
10654682a6d9SVille Syrjälä const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
10664682a6d9SVille Syrjälä u8 alpha = plane_state->hw.alpha >> 8;
10674682a6d9SVille Syrjälä u32 keymsk;
10684682a6d9SVille Syrjälä
10694682a6d9SVille Syrjälä keymsk = key->channel_mask & 0x7ffffff;
10704682a6d9SVille Syrjälä if (alpha < 0xff)
10714682a6d9SVille Syrjälä keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
10724682a6d9SVille Syrjälä
10734682a6d9SVille Syrjälä return keymsk;
10744682a6d9SVille Syrjälä }
10754682a6d9SVille Syrjälä
icl_plane_csc_load_black(struct intel_plane * plane)107617dbbe7bSVille Syrjälä static void icl_plane_csc_load_black(struct intel_plane *plane)
10776eba56f6SAnshuman Gupta {
107817dbbe7bSVille Syrjälä struct drm_i915_private *i915 = to_i915(plane->base.dev);
107917dbbe7bSVille Syrjälä enum plane_id plane_id = plane->id;
108017dbbe7bSVille Syrjälä enum pipe pipe = plane->pipe;
10816eba56f6SAnshuman Gupta
108217dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 0), 0);
108317dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 1), 0);
10846eba56f6SAnshuman Gupta
108517dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 2), 0);
108617dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 3), 0);
10876eba56f6SAnshuman Gupta
108817dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 4), 0);
108917dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 5), 0);
10906eba56f6SAnshuman Gupta
109117dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 0), 0);
109217dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 1), 0);
109317dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 2), 0);
10946eba56f6SAnshuman Gupta
109517dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 0), 0);
109617dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 1), 0);
109717dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0);
10986eba56f6SAnshuman Gupta }
10996eba56f6SAnshuman Gupta
icl_plane_color_plane(const struct intel_plane_state * plane_state)1100f8a005ebSVille Syrjälä static int icl_plane_color_plane(const struct intel_plane_state *plane_state)
1101fee07601SVille Syrjälä {
1102fee07601SVille Syrjälä /* Program the UV plane on planar master */
1103fee07601SVille Syrjälä if (plane_state->planar_linked_plane && !plane_state->planar_slave)
1104fee07601SVille Syrjälä return 1;
1105fee07601SVille Syrjälä else
1106fee07601SVille Syrjälä return 0;
1107fee07601SVille Syrjälä }
1108fee07601SVille Syrjälä
110946d12f91SDave Airlie static void
skl_plane_update_noarm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1110fee07601SVille Syrjälä skl_plane_update_noarm(struct intel_plane *plane,
111146d12f91SDave Airlie const struct intel_crtc_state *crtc_state,
1112fee07601SVille Syrjälä const struct intel_plane_state *plane_state)
111346d12f91SDave Airlie {
111446d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
111546d12f91SDave Airlie enum plane_id plane_id = plane->id;
111646d12f91SDave Airlie enum pipe pipe = plane->pipe;
1117f8a005ebSVille Syrjälä u32 stride = skl_plane_stride(plane_state, 0);
111846d12f91SDave Airlie int crtc_x = plane_state->uapi.dst.x1;
111946d12f91SDave Airlie int crtc_y = plane_state->uapi.dst.y1;
112046d12f91SDave Airlie u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
112146d12f91SDave Airlie u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
112246d12f91SDave Airlie
112346d12f91SDave Airlie /* The scaler will handle the output position */
112446d12f91SDave Airlie if (plane_state->scaler_id >= 0) {
112546d12f91SDave Airlie crtc_x = 0;
112646d12f91SDave Airlie crtc_y = 0;
112746d12f91SDave Airlie }
112846d12f91SDave Airlie
112912d7d858SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
113012d7d858SVille Syrjälä PLANE_STRIDE_(stride));
113146d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
113212d7d858SVille Syrjälä PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
113346d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
113412d7d858SVille Syrjälä PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
113546d12f91SDave Airlie
113646d12f91SDave Airlie skl_write_plane_wm(plane, crtc_state);
1137890b6ec4SVille Syrjälä }
1138890b6ec4SVille Syrjälä
1139890b6ec4SVille Syrjälä static void
skl_plane_update_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1140fee07601SVille Syrjälä skl_plane_update_arm(struct intel_plane *plane,
1141890b6ec4SVille Syrjälä const struct intel_crtc_state *crtc_state,
1142fee07601SVille Syrjälä const struct intel_plane_state *plane_state)
1143890b6ec4SVille Syrjälä {
1144890b6ec4SVille Syrjälä struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1145890b6ec4SVille Syrjälä enum plane_id plane_id = plane->id;
1146890b6ec4SVille Syrjälä enum pipe pipe = plane->pipe;
1147f8a005ebSVille Syrjälä u32 x = plane_state->view.color_plane[0].x;
1148f8a005ebSVille Syrjälä u32 y = plane_state->view.color_plane[0].y;
1149f8a005ebSVille Syrjälä u32 plane_ctl, plane_color_ctl = 0;
1150890b6ec4SVille Syrjälä
1151f8a005ebSVille Syrjälä plane_ctl = plane_state->ctl |
1152f8a005ebSVille Syrjälä skl_plane_ctl_crtc(crtc_state);
1153890b6ec4SVille Syrjälä
1154890b6ec4SVille Syrjälä if (DISPLAY_VER(dev_priv) >= 10)
1155890b6ec4SVille Syrjälä plane_color_ctl = plane_state->color_ctl |
1156890b6ec4SVille Syrjälä glk_plane_color_ctl_crtc(crtc_state);
1157890b6ec4SVille Syrjälä
11584682a6d9SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
11594682a6d9SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
11604682a6d9SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
116146d12f91SDave Airlie
116246d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
116312d7d858SVille Syrjälä PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
116446d12f91SDave Airlie
1165366714b0SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
1166f8a005ebSVille Syrjälä skl_plane_aux_dist(plane_state, 0));
1167890b6ec4SVille Syrjälä
116846d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
116912d7d858SVille Syrjälä PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
117012d7d858SVille Syrjälä PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
117146d12f91SDave Airlie
1172890b6ec4SVille Syrjälä if (DISPLAY_VER(dev_priv) >= 10)
1173890b6ec4SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
117446d12f91SDave Airlie
117546d12f91SDave Airlie /*
11767c653e15SVille Syrjälä * Enable the scaler before the plane so that we don't
11777c653e15SVille Syrjälä * get a catastrophic underrun even if the two operations
11787c653e15SVille Syrjälä * end up happening in two different frames.
1179890b6ec4SVille Syrjälä *
1180890b6ec4SVille Syrjälä * TODO: split into noarm+arm pair
11817c653e15SVille Syrjälä */
11827c653e15SVille Syrjälä if (plane_state->scaler_id >= 0)
11837c653e15SVille Syrjälä skl_program_plane_scaler(plane, crtc_state, plane_state);
11847c653e15SVille Syrjälä
11857c653e15SVille Syrjälä /*
118646d12f91SDave Airlie * The control register self-arms if the plane was previously
118746d12f91SDave Airlie * disabled. Try to make the plane enable atomic by writing
118846d12f91SDave Airlie * the control register just before the surface register.
118946d12f91SDave Airlie */
119046d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
119150faf7a1SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
1192f8a005ebSVille Syrjälä skl_plane_surf(plane_state, 0));
1193f8a005ebSVille Syrjälä }
1194f8a005ebSVille Syrjälä
1195f8a005ebSVille Syrjälä static void
icl_plane_update_noarm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1196f8a005ebSVille Syrjälä icl_plane_update_noarm(struct intel_plane *plane,
1197f8a005ebSVille Syrjälä const struct intel_crtc_state *crtc_state,
1198f8a005ebSVille Syrjälä const struct intel_plane_state *plane_state)
1199f8a005ebSVille Syrjälä {
1200f8a005ebSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1201f8a005ebSVille Syrjälä enum plane_id plane_id = plane->id;
1202f8a005ebSVille Syrjälä enum pipe pipe = plane->pipe;
1203f8a005ebSVille Syrjälä int color_plane = icl_plane_color_plane(plane_state);
1204f8a005ebSVille Syrjälä u32 stride = skl_plane_stride(plane_state, color_plane);
1205f8a005ebSVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
1206f8a005ebSVille Syrjälä int crtc_x = plane_state->uapi.dst.x1;
1207f8a005ebSVille Syrjälä int crtc_y = plane_state->uapi.dst.y1;
1208f8a005ebSVille Syrjälä int x = plane_state->view.color_plane[color_plane].x;
1209f8a005ebSVille Syrjälä int y = plane_state->view.color_plane[color_plane].y;
1210f8a005ebSVille Syrjälä int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1211f8a005ebSVille Syrjälä int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1212f8a005ebSVille Syrjälä u32 plane_color_ctl;
1213f8a005ebSVille Syrjälä
1214f8a005ebSVille Syrjälä plane_color_ctl = plane_state->color_ctl |
1215f8a005ebSVille Syrjälä glk_plane_color_ctl_crtc(crtc_state);
1216f8a005ebSVille Syrjälä
1217f8a005ebSVille Syrjälä /* The scaler will handle the output position */
1218f8a005ebSVille Syrjälä if (plane_state->scaler_id >= 0) {
1219f8a005ebSVille Syrjälä crtc_x = 0;
1220f8a005ebSVille Syrjälä crtc_y = 0;
1221f8a005ebSVille Syrjälä }
1222f8a005ebSVille Syrjälä
1223f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
1224f8a005ebSVille Syrjälä PLANE_STRIDE_(stride));
1225f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
1226f8a005ebSVille Syrjälä PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
1227f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
1228f8a005ebSVille Syrjälä PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
1229f8a005ebSVille Syrjälä
1230f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
1231f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
1232f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
1233f8a005ebSVille Syrjälä
1234f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
1235f8a005ebSVille Syrjälä PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
1236f8a005ebSVille Syrjälä
1237f8a005ebSVille Syrjälä if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) {
1238f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0),
1239f8a005ebSVille Syrjälä lower_32_bits(plane_state->ccval));
1240f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 1),
1241f8a005ebSVille Syrjälä upper_32_bits(plane_state->ccval));
1242f8a005ebSVille Syrjälä }
1243f8a005ebSVille Syrjälä
1244680025dcSJuha-Pekka Heikkilä /* FLAT CCS doesn't need to program AUX_DIST */
1245680025dcSJuha-Pekka Heikkilä if (!HAS_FLAT_CCS(dev_priv))
1246f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
1247f8a005ebSVille Syrjälä skl_plane_aux_dist(plane_state, color_plane));
1248f8a005ebSVille Syrjälä
1249f8a005ebSVille Syrjälä if (icl_is_hdr_plane(dev_priv, plane_id))
1250f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
1251f8a005ebSVille Syrjälä plane_state->cus_ctl);
1252f8a005ebSVille Syrjälä
1253f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
1254f8a005ebSVille Syrjälä
1255f8a005ebSVille Syrjälä if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
1256f8a005ebSVille Syrjälä icl_program_input_csc(plane, crtc_state, plane_state);
1257f8a005ebSVille Syrjälä
1258f8a005ebSVille Syrjälä skl_write_plane_wm(plane, crtc_state);
1259f8a005ebSVille Syrjälä
1260f8a005ebSVille Syrjälä /*
1261f8a005ebSVille Syrjälä * FIXME: pxp session invalidation can hit any time even at time of commit
1262f8a005ebSVille Syrjälä * or after the commit, display content will be garbage.
1263f8a005ebSVille Syrjälä */
1264f8a005ebSVille Syrjälä if (plane_state->force_black)
1265f8a005ebSVille Syrjälä icl_plane_csc_load_black(plane);
1266f8a005ebSVille Syrjälä
1267c22cf04cSJouni Högander intel_psr2_program_plane_sel_fetch_noarm(plane, crtc_state, plane_state, color_plane);
1268f8a005ebSVille Syrjälä }
1269f8a005ebSVille Syrjälä
1270f8a005ebSVille Syrjälä static void
icl_plane_update_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1271f8a005ebSVille Syrjälä icl_plane_update_arm(struct intel_plane *plane,
1272f8a005ebSVille Syrjälä const struct intel_crtc_state *crtc_state,
1273f8a005ebSVille Syrjälä const struct intel_plane_state *plane_state)
1274f8a005ebSVille Syrjälä {
1275f8a005ebSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1276f8a005ebSVille Syrjälä enum plane_id plane_id = plane->id;
1277f8a005ebSVille Syrjälä enum pipe pipe = plane->pipe;
1278f8a005ebSVille Syrjälä int color_plane = icl_plane_color_plane(plane_state);
1279f8a005ebSVille Syrjälä u32 plane_ctl;
1280f8a005ebSVille Syrjälä
1281f8a005ebSVille Syrjälä plane_ctl = plane_state->ctl |
1282f8a005ebSVille Syrjälä skl_plane_ctl_crtc(crtc_state);
1283f8a005ebSVille Syrjälä
1284f8a005ebSVille Syrjälä /*
1285f8a005ebSVille Syrjälä * Enable the scaler before the plane so that we don't
1286f8a005ebSVille Syrjälä * get a catastrophic underrun even if the two operations
1287f8a005ebSVille Syrjälä * end up happening in two different frames.
1288f8a005ebSVille Syrjälä *
1289f8a005ebSVille Syrjälä * TODO: split into noarm+arm pair
1290f8a005ebSVille Syrjälä */
1291f8a005ebSVille Syrjälä if (plane_state->scaler_id >= 0)
1292f8a005ebSVille Syrjälä skl_program_plane_scaler(plane, crtc_state, plane_state);
1293f8a005ebSVille Syrjälä
1294c22cf04cSJouni Högander intel_psr2_program_plane_sel_fetch_arm(plane, crtc_state, plane_state);
1295c22cf04cSJouni Högander
1296f8a005ebSVille Syrjälä /*
1297f8a005ebSVille Syrjälä * The control register self-arms if the plane was previously
1298f8a005ebSVille Syrjälä * disabled. Try to make the plane enable atomic by writing
1299f8a005ebSVille Syrjälä * the control register just before the surface register.
1300f8a005ebSVille Syrjälä */
1301f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
1302f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
130350faf7a1SVille Syrjälä skl_plane_surf(plane_state, color_plane));
130446d12f91SDave Airlie }
130546d12f91SDave Airlie
130646d12f91SDave Airlie static void
skl_plane_async_flip(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,bool async_flip)130746d12f91SDave Airlie skl_plane_async_flip(struct intel_plane *plane,
130846d12f91SDave Airlie const struct intel_crtc_state *crtc_state,
130946d12f91SDave Airlie const struct intel_plane_state *plane_state,
131046d12f91SDave Airlie bool async_flip)
131146d12f91SDave Airlie {
131246d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
131346d12f91SDave Airlie enum plane_id plane_id = plane->id;
131446d12f91SDave Airlie enum pipe pipe = plane->pipe;
131546d12f91SDave Airlie u32 plane_ctl = plane_state->ctl;
131646d12f91SDave Airlie
131746d12f91SDave Airlie plane_ctl |= skl_plane_ctl_crtc(crtc_state);
131846d12f91SDave Airlie
131946d12f91SDave Airlie if (async_flip)
132046d12f91SDave Airlie plane_ctl |= PLANE_CTL_ASYNC_FLIP;
132146d12f91SDave Airlie
132246d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
132346d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
132450faf7a1SVille Syrjälä skl_plane_surf(plane_state, 0));
132546d12f91SDave Airlie }
132646d12f91SDave Airlie
intel_format_is_p01x(u32 format)132746d12f91SDave Airlie static bool intel_format_is_p01x(u32 format)
132846d12f91SDave Airlie {
132946d12f91SDave Airlie switch (format) {
133046d12f91SDave Airlie case DRM_FORMAT_P010:
133146d12f91SDave Airlie case DRM_FORMAT_P012:
133246d12f91SDave Airlie case DRM_FORMAT_P016:
133346d12f91SDave Airlie return true;
133446d12f91SDave Airlie default:
133546d12f91SDave Airlie return false;
133646d12f91SDave Airlie }
133746d12f91SDave Airlie }
133846d12f91SDave Airlie
skl_plane_check_fb(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)133946d12f91SDave Airlie static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
134046d12f91SDave Airlie const struct intel_plane_state *plane_state)
134146d12f91SDave Airlie {
134246d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
134346d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
134446d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
134546d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
134646d12f91SDave Airlie
134746d12f91SDave Airlie if (!fb)
134846d12f91SDave Airlie return 0;
134946d12f91SDave Airlie
135046d12f91SDave Airlie if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1351e359c47bSImre Deak intel_fb_is_ccs_modifier(fb->modifier)) {
135246d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
135346d12f91SDave Airlie "RC support only with 0/180 degree rotation (%x)\n",
135446d12f91SDave Airlie rotation);
135546d12f91SDave Airlie return -EINVAL;
135646d12f91SDave Airlie }
135746d12f91SDave Airlie
135846d12f91SDave Airlie if (rotation & DRM_MODE_REFLECT_X &&
135946d12f91SDave Airlie fb->modifier == DRM_FORMAT_MOD_LINEAR) {
136046d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
136146d12f91SDave Airlie "horizontal flip is not supported with linear surface formats\n");
136246d12f91SDave Airlie return -EINVAL;
136346d12f91SDave Airlie }
136446d12f91SDave Airlie
136546d12f91SDave Airlie if (drm_rotation_90_or_270(rotation)) {
1366d3b4aa43SImre Deak if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) {
136746d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
136846d12f91SDave Airlie "Y/Yf tiling required for 90/270!\n");
136946d12f91SDave Airlie return -EINVAL;
137046d12f91SDave Airlie }
137146d12f91SDave Airlie
137246d12f91SDave Airlie /*
137346d12f91SDave Airlie * 90/270 is not allowed with RGB64 16:16:16:16 and
137446d12f91SDave Airlie * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
137546d12f91SDave Airlie */
137646d12f91SDave Airlie switch (fb->format->format) {
137746d12f91SDave Airlie case DRM_FORMAT_RGB565:
1378005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11)
137946d12f91SDave Airlie break;
138046d12f91SDave Airlie fallthrough;
138146d12f91SDave Airlie case DRM_FORMAT_C8:
138246d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
138346d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
138446d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
138546d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
138646d12f91SDave Airlie case DRM_FORMAT_Y210:
138746d12f91SDave Airlie case DRM_FORMAT_Y212:
138846d12f91SDave Airlie case DRM_FORMAT_Y216:
138946d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
139046d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
139146d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
1392e3c2f187SStephen Rothwell "Unsupported pixel format %p4cc for 90/270!\n",
1393e3c2f187SStephen Rothwell &fb->format->format);
139446d12f91SDave Airlie return -EINVAL;
139546d12f91SDave Airlie default:
139646d12f91SDave Airlie break;
139746d12f91SDave Airlie }
139846d12f91SDave Airlie }
139946d12f91SDave Airlie
140046d12f91SDave Airlie /* Y-tiling is not supported in IF-ID Interlace mode */
140146d12f91SDave Airlie if (crtc_state->hw.enable &&
140246d12f91SDave Airlie crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1403d89357deSImre Deak fb->modifier != DRM_FORMAT_MOD_LINEAR &&
1404d89357deSImre Deak fb->modifier != I915_FORMAT_MOD_X_TILED) {
140546d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
140646d12f91SDave Airlie "Y/Yf tiling not supported in IF-ID mode\n");
140746d12f91SDave Airlie return -EINVAL;
140846d12f91SDave Airlie }
140946d12f91SDave Airlie
141046d12f91SDave Airlie /* Wa_1606054188:tgl,adl-s */
141146d12f91SDave Airlie if ((IS_ALDERLAKE_S(dev_priv) || IS_TIGERLAKE(dev_priv)) &&
141246d12f91SDave Airlie plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE &&
141346d12f91SDave Airlie intel_format_is_p01x(fb->format->format)) {
141446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
141546d12f91SDave Airlie "Source color keying not supported with P01x formats\n");
141646d12f91SDave Airlie return -EINVAL;
141746d12f91SDave Airlie }
141846d12f91SDave Airlie
141946d12f91SDave Airlie return 0;
142046d12f91SDave Airlie }
142146d12f91SDave Airlie
skl_plane_check_dst_coordinates(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)142246d12f91SDave Airlie static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
142346d12f91SDave Airlie const struct intel_plane_state *plane_state)
142446d12f91SDave Airlie {
142546d12f91SDave Airlie struct drm_i915_private *dev_priv =
142646d12f91SDave Airlie to_i915(plane_state->uapi.plane->dev);
142746d12f91SDave Airlie int crtc_x = plane_state->uapi.dst.x1;
142846d12f91SDave Airlie int crtc_w = drm_rect_width(&plane_state->uapi.dst);
142926111a16SVille Syrjälä int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
143046d12f91SDave Airlie
143146d12f91SDave Airlie /*
1432244dba4cSLucas De Marchi * Display WA #1175: glk
143346d12f91SDave Airlie * Planes other than the cursor may cause FIFO underflow and display
143446d12f91SDave Airlie * corruption if starting less than 4 pixels from the right edge of
143546d12f91SDave Airlie * the screen.
143646d12f91SDave Airlie * Besides the above WA fix the similar problem, where planes other
143746d12f91SDave Airlie * than the cursor ending less than 4 pixels from the left edge of the
143846d12f91SDave Airlie * screen may cause FIFO underflow and display corruption.
143946d12f91SDave Airlie */
144093e7e61eSLucas De Marchi if (DISPLAY_VER(dev_priv) == 10 &&
144146d12f91SDave Airlie (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
144246d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
144346d12f91SDave Airlie "requested plane X %s position %d invalid (valid range %d-%d)\n",
144446d12f91SDave Airlie crtc_x + crtc_w < 4 ? "end" : "start",
144546d12f91SDave Airlie crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
144646d12f91SDave Airlie 4, pipe_src_w - 4);
144746d12f91SDave Airlie return -ERANGE;
144846d12f91SDave Airlie }
144946d12f91SDave Airlie
145046d12f91SDave Airlie return 0;
145146d12f91SDave Airlie }
145246d12f91SDave Airlie
skl_plane_check_nv12_rotation(const struct intel_plane_state * plane_state)145346d12f91SDave Airlie static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
145446d12f91SDave Airlie {
14555acbdcd1SJani Nikula struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
145646d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
145746d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
145846d12f91SDave Airlie int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
145946d12f91SDave Airlie
146046d12f91SDave Airlie /* Display WA #1106 */
146146d12f91SDave Airlie if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
146246d12f91SDave Airlie src_w & 3 &&
146346d12f91SDave Airlie (rotation == DRM_MODE_ROTATE_270 ||
146446d12f91SDave Airlie rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
14655acbdcd1SJani Nikula drm_dbg_kms(&i915->drm, "src width must be multiple of 4 for rotated planar YUV\n");
146646d12f91SDave Airlie return -EINVAL;
146746d12f91SDave Airlie }
146846d12f91SDave Airlie
146946d12f91SDave Airlie return 0;
147046d12f91SDave Airlie }
147146d12f91SDave Airlie
skl_plane_max_scale(struct drm_i915_private * dev_priv,const struct drm_framebuffer * fb)147246d12f91SDave Airlie static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
147346d12f91SDave Airlie const struct drm_framebuffer *fb)
147446d12f91SDave Airlie {
147546d12f91SDave Airlie /*
147646d12f91SDave Airlie * We don't yet know the final source width nor
147746d12f91SDave Airlie * whether we can use the HQ scaler mode. Assume
147846d12f91SDave Airlie * the best case.
147946d12f91SDave Airlie * FIXME need to properly check this later.
148046d12f91SDave Airlie */
14812b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10 ||
148246d12f91SDave Airlie !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
148346d12f91SDave Airlie return 0x30000 - 1;
148446d12f91SDave Airlie else
148546d12f91SDave Airlie return 0x20000 - 1;
148646d12f91SDave Airlie }
148746d12f91SDave Airlie
intel_plane_min_width(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)148846d12f91SDave Airlie static int intel_plane_min_width(struct intel_plane *plane,
148946d12f91SDave Airlie const struct drm_framebuffer *fb,
149046d12f91SDave Airlie int color_plane,
149146d12f91SDave Airlie unsigned int rotation)
149246d12f91SDave Airlie {
149346d12f91SDave Airlie if (plane->min_width)
149446d12f91SDave Airlie return plane->min_width(fb, color_plane, rotation);
149546d12f91SDave Airlie else
149646d12f91SDave Airlie return 1;
149746d12f91SDave Airlie }
149846d12f91SDave Airlie
intel_plane_max_width(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)149946d12f91SDave Airlie static int intel_plane_max_width(struct intel_plane *plane,
150046d12f91SDave Airlie const struct drm_framebuffer *fb,
150146d12f91SDave Airlie int color_plane,
150246d12f91SDave Airlie unsigned int rotation)
150346d12f91SDave Airlie {
150446d12f91SDave Airlie if (plane->max_width)
150546d12f91SDave Airlie return plane->max_width(fb, color_plane, rotation);
150646d12f91SDave Airlie else
150746d12f91SDave Airlie return INT_MAX;
150846d12f91SDave Airlie }
150946d12f91SDave Airlie
intel_plane_max_height(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)151046d12f91SDave Airlie static int intel_plane_max_height(struct intel_plane *plane,
151146d12f91SDave Airlie const struct drm_framebuffer *fb,
151246d12f91SDave Airlie int color_plane,
151346d12f91SDave Airlie unsigned int rotation)
151446d12f91SDave Airlie {
151546d12f91SDave Airlie if (plane->max_height)
151646d12f91SDave Airlie return plane->max_height(fb, color_plane, rotation);
151746d12f91SDave Airlie else
151846d12f91SDave Airlie return INT_MAX;
151946d12f91SDave Airlie }
152046d12f91SDave Airlie
152146d12f91SDave Airlie static bool
skl_check_main_ccs_coordinates(struct intel_plane_state * plane_state,int main_x,int main_y,u32 main_offset,int ccs_plane)152246d12f91SDave Airlie skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
152346d12f91SDave Airlie int main_x, int main_y, u32 main_offset,
152446d12f91SDave Airlie int ccs_plane)
152546d12f91SDave Airlie {
152646d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
152761169987SImre Deak int aux_x = plane_state->view.color_plane[ccs_plane].x;
152861169987SImre Deak int aux_y = plane_state->view.color_plane[ccs_plane].y;
152961169987SImre Deak u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
153046d12f91SDave Airlie u32 alignment = intel_surf_alignment(fb, ccs_plane);
153146d12f91SDave Airlie int hsub;
153246d12f91SDave Airlie int vsub;
153346d12f91SDave Airlie
153446d12f91SDave Airlie intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
153546d12f91SDave Airlie while (aux_offset >= main_offset && aux_y <= main_y) {
153646d12f91SDave Airlie int x, y;
153746d12f91SDave Airlie
153846d12f91SDave Airlie if (aux_x == main_x && aux_y == main_y)
153946d12f91SDave Airlie break;
154046d12f91SDave Airlie
154146d12f91SDave Airlie if (aux_offset == 0)
154246d12f91SDave Airlie break;
154346d12f91SDave Airlie
154446d12f91SDave Airlie x = aux_x / hsub;
154546d12f91SDave Airlie y = aux_y / vsub;
154646d12f91SDave Airlie aux_offset = intel_plane_adjust_aligned_offset(&x, &y,
154746d12f91SDave Airlie plane_state,
154846d12f91SDave Airlie ccs_plane,
154946d12f91SDave Airlie aux_offset,
155046d12f91SDave Airlie aux_offset -
155146d12f91SDave Airlie alignment);
155246d12f91SDave Airlie aux_x = x * hsub + aux_x % hsub;
155346d12f91SDave Airlie aux_y = y * vsub + aux_y % vsub;
155446d12f91SDave Airlie }
155546d12f91SDave Airlie
155646d12f91SDave Airlie if (aux_x != main_x || aux_y != main_y)
155746d12f91SDave Airlie return false;
155846d12f91SDave Airlie
155961169987SImre Deak plane_state->view.color_plane[ccs_plane].offset = aux_offset;
156061169987SImre Deak plane_state->view.color_plane[ccs_plane].x = aux_x;
156161169987SImre Deak plane_state->view.color_plane[ccs_plane].y = aux_y;
156246d12f91SDave Airlie
156346d12f91SDave Airlie return true;
156446d12f91SDave Airlie }
156546d12f91SDave Airlie
156646d12f91SDave Airlie
skl_calc_main_surface_offset(const struct intel_plane_state * plane_state,int * x,int * y,u32 * offset)156746d12f91SDave Airlie int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
156846d12f91SDave Airlie int *x, int *y, u32 *offset)
156946d12f91SDave Airlie {
157046d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
157146d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
157246d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
157346d12f91SDave Airlie const int aux_plane = skl_main_to_aux_plane(fb, 0);
157461169987SImre Deak const u32 aux_offset = plane_state->view.color_plane[aux_plane].offset;
157546d12f91SDave Airlie const u32 alignment = intel_surf_alignment(fb, 0);
157646d12f91SDave Airlie const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
157746d12f91SDave Airlie
157846d12f91SDave Airlie intel_add_fb_offsets(x, y, plane_state, 0);
157946d12f91SDave Airlie *offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0);
158046d12f91SDave Airlie if (drm_WARN_ON(&dev_priv->drm, alignment && !is_power_of_2(alignment)))
158146d12f91SDave Airlie return -EINVAL;
158246d12f91SDave Airlie
158346d12f91SDave Airlie /*
158446d12f91SDave Airlie * AUX surface offset is specified as the distance from the
158546d12f91SDave Airlie * main surface offset, and it must be non-negative. Make
158646d12f91SDave Airlie * sure that is what we will get.
158746d12f91SDave Airlie */
158846d12f91SDave Airlie if (aux_plane && *offset > aux_offset)
158946d12f91SDave Airlie *offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
159046d12f91SDave Airlie *offset,
159146d12f91SDave Airlie aux_offset & ~(alignment - 1));
159246d12f91SDave Airlie
159346d12f91SDave Airlie /*
159446d12f91SDave Airlie * When using an X-tiled surface, the plane blows up
159546d12f91SDave Airlie * if the x offset + width exceed the stride.
159646d12f91SDave Airlie *
159746d12f91SDave Airlie * TODO: linear and Y-tiled seem fine, Yf untested,
159846d12f91SDave Airlie */
159946d12f91SDave Airlie if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
160046d12f91SDave Airlie int cpp = fb->format->cpp[0];
160146d12f91SDave Airlie
1602be6c1dd5SImre Deak while ((*x + w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
160346d12f91SDave Airlie if (*offset == 0) {
160446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
160546d12f91SDave Airlie "Unable to find suitable display surface offset due to X-tiling\n");
160646d12f91SDave Airlie return -EINVAL;
160746d12f91SDave Airlie }
160846d12f91SDave Airlie
160946d12f91SDave Airlie *offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
161046d12f91SDave Airlie *offset,
161146d12f91SDave Airlie *offset - alignment);
161246d12f91SDave Airlie }
161346d12f91SDave Airlie }
161446d12f91SDave Airlie
161546d12f91SDave Airlie return 0;
161646d12f91SDave Airlie }
161746d12f91SDave Airlie
skl_check_main_surface(struct intel_plane_state * plane_state)161846d12f91SDave Airlie static int skl_check_main_surface(struct intel_plane_state *plane_state)
161946d12f91SDave Airlie {
162046d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
162146d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
162246d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
162346d12f91SDave Airlie const unsigned int rotation = plane_state->hw.rotation;
162446d12f91SDave Airlie int x = plane_state->uapi.src.x1 >> 16;
162546d12f91SDave Airlie int y = plane_state->uapi.src.y1 >> 16;
162646d12f91SDave Airlie const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
162746d12f91SDave Airlie const int h = drm_rect_height(&plane_state->uapi.src) >> 16;
162846d12f91SDave Airlie const int min_width = intel_plane_min_width(plane, fb, 0, rotation);
162946d12f91SDave Airlie const int max_width = intel_plane_max_width(plane, fb, 0, rotation);
163046d12f91SDave Airlie const int max_height = intel_plane_max_height(plane, fb, 0, rotation);
163146d12f91SDave Airlie const int aux_plane = skl_main_to_aux_plane(fb, 0);
163246d12f91SDave Airlie const u32 alignment = intel_surf_alignment(fb, 0);
163346d12f91SDave Airlie u32 offset;
163446d12f91SDave Airlie int ret;
163546d12f91SDave Airlie
16360fe76b19SDrew Davenport if (w > max_width || w < min_width || h > max_height || h < 1) {
163746d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
163846d12f91SDave Airlie "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n",
163946d12f91SDave Airlie w, h, min_width, max_width, max_height);
164046d12f91SDave Airlie return -EINVAL;
164146d12f91SDave Airlie }
164246d12f91SDave Airlie
164346d12f91SDave Airlie ret = skl_calc_main_surface_offset(plane_state, &x, &y, &offset);
164446d12f91SDave Airlie if (ret)
164546d12f91SDave Airlie return ret;
164646d12f91SDave Airlie
164746d12f91SDave Airlie /*
164846d12f91SDave Airlie * CCS AUX surface doesn't have its own x/y offsets, we must make sure
1649680025dcSJuha-Pekka Heikkilä * they match with the main surface x/y offsets. On DG2
1650680025dcSJuha-Pekka Heikkilä * there's no aux plane on fb so skip this checking.
165146d12f91SDave Airlie */
1652680025dcSJuha-Pekka Heikkilä if (intel_fb_is_ccs_modifier(fb->modifier) && aux_plane) {
165346d12f91SDave Airlie while (!skl_check_main_ccs_coordinates(plane_state, x, y,
165446d12f91SDave Airlie offset, aux_plane)) {
165546d12f91SDave Airlie if (offset == 0)
165646d12f91SDave Airlie break;
165746d12f91SDave Airlie
165846d12f91SDave Airlie offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
165946d12f91SDave Airlie offset, offset - alignment);
166046d12f91SDave Airlie }
166146d12f91SDave Airlie
166261169987SImre Deak if (x != plane_state->view.color_plane[aux_plane].x ||
166361169987SImre Deak y != plane_state->view.color_plane[aux_plane].y) {
166446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
166546d12f91SDave Airlie "Unable to find suitable display surface offset due to CCS\n");
166646d12f91SDave Airlie return -EINVAL;
166746d12f91SDave Airlie }
166846d12f91SDave Airlie }
166946d12f91SDave Airlie
1670e7367af1SJuha-Pekka Heikkilä if (DISPLAY_VER(dev_priv) >= 13)
1671e7367af1SJuha-Pekka Heikkilä drm_WARN_ON(&dev_priv->drm, x > 65535 || y > 65535);
1672e7367af1SJuha-Pekka Heikkilä else
167346d12f91SDave Airlie drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191);
167446d12f91SDave Airlie
167561169987SImre Deak plane_state->view.color_plane[0].offset = offset;
167661169987SImre Deak plane_state->view.color_plane[0].x = x;
167761169987SImre Deak plane_state->view.color_plane[0].y = y;
167846d12f91SDave Airlie
167946d12f91SDave Airlie /*
168046d12f91SDave Airlie * Put the final coordinates back so that the src
168146d12f91SDave Airlie * coordinate checks will see the right values.
168246d12f91SDave Airlie */
168346d12f91SDave Airlie drm_rect_translate_to(&plane_state->uapi.src,
168446d12f91SDave Airlie x << 16, y << 16);
168546d12f91SDave Airlie
168646d12f91SDave Airlie return 0;
168746d12f91SDave Airlie }
168846d12f91SDave Airlie
skl_check_nv12_aux_surface(struct intel_plane_state * plane_state)168946d12f91SDave Airlie static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
169046d12f91SDave Airlie {
169146d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
169246d12f91SDave Airlie struct drm_i915_private *i915 = to_i915(plane->base.dev);
169346d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
169446d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
169546d12f91SDave Airlie int uv_plane = 1;
1696680025dcSJuha-Pekka Heikkilä int ccs_plane = intel_fb_is_ccs_modifier(fb->modifier) ?
1697680025dcSJuha-Pekka Heikkilä skl_main_to_aux_plane(fb, uv_plane) : 0;
169846d12f91SDave Airlie int max_width = intel_plane_max_width(plane, fb, uv_plane, rotation);
169946d12f91SDave Airlie int max_height = intel_plane_max_height(plane, fb, uv_plane, rotation);
170046d12f91SDave Airlie int x = plane_state->uapi.src.x1 >> 17;
170146d12f91SDave Airlie int y = plane_state->uapi.src.y1 >> 17;
170246d12f91SDave Airlie int w = drm_rect_width(&plane_state->uapi.src) >> 17;
170346d12f91SDave Airlie int h = drm_rect_height(&plane_state->uapi.src) >> 17;
170446d12f91SDave Airlie u32 offset;
170546d12f91SDave Airlie
170646d12f91SDave Airlie /* FIXME not quite sure how/if these apply to the chroma plane */
170746d12f91SDave Airlie if (w > max_width || h > max_height) {
170846d12f91SDave Airlie drm_dbg_kms(&i915->drm,
170946d12f91SDave Airlie "CbCr source size %dx%d too big (limit %dx%d)\n",
171046d12f91SDave Airlie w, h, max_width, max_height);
171146d12f91SDave Airlie return -EINVAL;
171246d12f91SDave Airlie }
171346d12f91SDave Airlie
171446d12f91SDave Airlie intel_add_fb_offsets(&x, &y, plane_state, uv_plane);
171546d12f91SDave Airlie offset = intel_plane_compute_aligned_offset(&x, &y,
171646d12f91SDave Airlie plane_state, uv_plane);
171746d12f91SDave Airlie
1718680025dcSJuha-Pekka Heikkilä if (ccs_plane) {
171961169987SImre Deak u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
172046d12f91SDave Airlie u32 alignment = intel_surf_alignment(fb, uv_plane);
172146d12f91SDave Airlie
172246d12f91SDave Airlie if (offset > aux_offset)
172346d12f91SDave Airlie offset = intel_plane_adjust_aligned_offset(&x, &y,
172446d12f91SDave Airlie plane_state,
172546d12f91SDave Airlie uv_plane,
172646d12f91SDave Airlie offset,
172746d12f91SDave Airlie aux_offset & ~(alignment - 1));
172846d12f91SDave Airlie
172946d12f91SDave Airlie while (!skl_check_main_ccs_coordinates(plane_state, x, y,
173046d12f91SDave Airlie offset, ccs_plane)) {
173146d12f91SDave Airlie if (offset == 0)
173246d12f91SDave Airlie break;
173346d12f91SDave Airlie
173446d12f91SDave Airlie offset = intel_plane_adjust_aligned_offset(&x, &y,
173546d12f91SDave Airlie plane_state,
173646d12f91SDave Airlie uv_plane,
173746d12f91SDave Airlie offset, offset - alignment);
173846d12f91SDave Airlie }
173946d12f91SDave Airlie
174061169987SImre Deak if (x != plane_state->view.color_plane[ccs_plane].x ||
174161169987SImre Deak y != plane_state->view.color_plane[ccs_plane].y) {
174246d12f91SDave Airlie drm_dbg_kms(&i915->drm,
174346d12f91SDave Airlie "Unable to find suitable display surface offset due to CCS\n");
174446d12f91SDave Airlie return -EINVAL;
174546d12f91SDave Airlie }
174646d12f91SDave Airlie }
174746d12f91SDave Airlie
1748e7367af1SJuha-Pekka Heikkilä if (DISPLAY_VER(i915) >= 13)
1749e7367af1SJuha-Pekka Heikkilä drm_WARN_ON(&i915->drm, x > 65535 || y > 65535);
1750e7367af1SJuha-Pekka Heikkilä else
175146d12f91SDave Airlie drm_WARN_ON(&i915->drm, x > 8191 || y > 8191);
175246d12f91SDave Airlie
175361169987SImre Deak plane_state->view.color_plane[uv_plane].offset = offset;
175461169987SImre Deak plane_state->view.color_plane[uv_plane].x = x;
175561169987SImre Deak plane_state->view.color_plane[uv_plane].y = y;
175646d12f91SDave Airlie
175746d12f91SDave Airlie return 0;
175846d12f91SDave Airlie }
175946d12f91SDave Airlie
skl_check_ccs_aux_surface(struct intel_plane_state * plane_state)176046d12f91SDave Airlie static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
176146d12f91SDave Airlie {
176246d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
176346d12f91SDave Airlie int src_x = plane_state->uapi.src.x1 >> 16;
176446d12f91SDave Airlie int src_y = plane_state->uapi.src.y1 >> 16;
176546d12f91SDave Airlie u32 offset;
176646d12f91SDave Airlie int ccs_plane;
176746d12f91SDave Airlie
176846d12f91SDave Airlie for (ccs_plane = 0; ccs_plane < fb->format->num_planes; ccs_plane++) {
176946d12f91SDave Airlie int main_hsub, main_vsub;
177046d12f91SDave Airlie int hsub, vsub;
177146d12f91SDave Airlie int x, y;
177246d12f91SDave Airlie
1773f5042343SImre Deak if (!intel_fb_is_ccs_aux_plane(fb, ccs_plane))
177446d12f91SDave Airlie continue;
177546d12f91SDave Airlie
177646d12f91SDave Airlie intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, fb,
177746d12f91SDave Airlie skl_ccs_to_main_plane(fb, ccs_plane));
177846d12f91SDave Airlie intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
177946d12f91SDave Airlie
178046d12f91SDave Airlie hsub *= main_hsub;
178146d12f91SDave Airlie vsub *= main_vsub;
178246d12f91SDave Airlie x = src_x / hsub;
178346d12f91SDave Airlie y = src_y / vsub;
178446d12f91SDave Airlie
178546d12f91SDave Airlie intel_add_fb_offsets(&x, &y, plane_state, ccs_plane);
178646d12f91SDave Airlie
178746d12f91SDave Airlie offset = intel_plane_compute_aligned_offset(&x, &y,
178846d12f91SDave Airlie plane_state,
178946d12f91SDave Airlie ccs_plane);
179046d12f91SDave Airlie
179161169987SImre Deak plane_state->view.color_plane[ccs_plane].offset = offset;
179261169987SImre Deak plane_state->view.color_plane[ccs_plane].x = (x * hsub + src_x % hsub) / main_hsub;
179361169987SImre Deak plane_state->view.color_plane[ccs_plane].y = (y * vsub + src_y % vsub) / main_vsub;
179446d12f91SDave Airlie }
179546d12f91SDave Airlie
179646d12f91SDave Airlie return 0;
179746d12f91SDave Airlie }
179846d12f91SDave Airlie
skl_check_plane_surface(struct intel_plane_state * plane_state)179946d12f91SDave Airlie static int skl_check_plane_surface(struct intel_plane_state *plane_state)
180046d12f91SDave Airlie {
180146d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
1802ee456a4cSImre Deak int ret;
180346d12f91SDave Airlie
180446d12f91SDave Airlie ret = intel_plane_compute_gtt(plane_state);
180546d12f91SDave Airlie if (ret)
180646d12f91SDave Airlie return ret;
180746d12f91SDave Airlie
180846d12f91SDave Airlie if (!plane_state->uapi.visible)
180946d12f91SDave Airlie return 0;
181046d12f91SDave Airlie
181146d12f91SDave Airlie /*
181246d12f91SDave Airlie * Handle the AUX surface first since the main surface setup depends on
181346d12f91SDave Airlie * it.
181446d12f91SDave Airlie */
1815e359c47bSImre Deak if (intel_fb_is_ccs_modifier(fb->modifier)) {
181646d12f91SDave Airlie ret = skl_check_ccs_aux_surface(plane_state);
181746d12f91SDave Airlie if (ret)
181846d12f91SDave Airlie return ret;
181946d12f91SDave Airlie }
182046d12f91SDave Airlie
182146d12f91SDave Airlie if (intel_format_info_is_yuv_semiplanar(fb->format,
182246d12f91SDave Airlie fb->modifier)) {
182346d12f91SDave Airlie ret = skl_check_nv12_aux_surface(plane_state);
182446d12f91SDave Airlie if (ret)
182546d12f91SDave Airlie return ret;
182646d12f91SDave Airlie }
182746d12f91SDave Airlie
182846d12f91SDave Airlie ret = skl_check_main_surface(plane_state);
182946d12f91SDave Airlie if (ret)
183046d12f91SDave Airlie return ret;
183146d12f91SDave Airlie
183246d12f91SDave Airlie return 0;
183346d12f91SDave Airlie }
183446d12f91SDave Airlie
skl_fb_scalable(const struct drm_framebuffer * fb)183514cebc1fSDave Airlie static bool skl_fb_scalable(const struct drm_framebuffer *fb)
183646d12f91SDave Airlie {
183746d12f91SDave Airlie if (!fb)
183846d12f91SDave Airlie return false;
183946d12f91SDave Airlie
184046d12f91SDave Airlie switch (fb->format->format) {
184146d12f91SDave Airlie case DRM_FORMAT_C8:
184246d12f91SDave Airlie return false;
184346d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
184446d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
184546d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
184646d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
1847005e9537SMatt Roper return DISPLAY_VER(to_i915(fb->dev)) >= 11;
184846d12f91SDave Airlie default:
184946d12f91SDave Airlie return true;
185046d12f91SDave Airlie }
185146d12f91SDave Airlie }
185246d12f91SDave Airlie
bo_has_valid_encryption(struct drm_i915_gem_object * obj)1853f9a7b19cSVille Syrjälä static bool bo_has_valid_encryption(struct drm_i915_gem_object *obj)
1854f9a7b19cSVille Syrjälä {
1855f9a7b19cSVille Syrjälä struct drm_i915_private *i915 = to_i915(obj->base.dev);
1856f9a7b19cSVille Syrjälä
1857f67986b0SAlan Previn return intel_pxp_key_check(i915->pxp, obj, false) == 0;
1858f9a7b19cSVille Syrjälä }
1859f9a7b19cSVille Syrjälä
pxp_is_borked(struct drm_i915_gem_object * obj)1860f9a7b19cSVille Syrjälä static bool pxp_is_borked(struct drm_i915_gem_object *obj)
1861f9a7b19cSVille Syrjälä {
1862f9a7b19cSVille Syrjälä return i915_gem_object_is_protected(obj) && !bo_has_valid_encryption(obj);
1863f9a7b19cSVille Syrjälä }
1864f9a7b19cSVille Syrjälä
skl_plane_check(struct intel_crtc_state * crtc_state,struct intel_plane_state * plane_state)186546d12f91SDave Airlie static int skl_plane_check(struct intel_crtc_state *crtc_state,
186646d12f91SDave Airlie struct intel_plane_state *plane_state)
186746d12f91SDave Airlie {
186846d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
186946d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
187046d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
1871cce32e4eSThomas Zimmermann int min_scale = DRM_PLANE_NO_SCALING;
1872cce32e4eSThomas Zimmermann int max_scale = DRM_PLANE_NO_SCALING;
187346d12f91SDave Airlie int ret;
187446d12f91SDave Airlie
187546d12f91SDave Airlie ret = skl_plane_check_fb(crtc_state, plane_state);
187646d12f91SDave Airlie if (ret)
187746d12f91SDave Airlie return ret;
187846d12f91SDave Airlie
187946d12f91SDave Airlie /* use scaler when colorkey is not required */
188014cebc1fSDave Airlie if (!plane_state->ckey.flags && skl_fb_scalable(fb)) {
188146d12f91SDave Airlie min_scale = 1;
188246d12f91SDave Airlie max_scale = skl_plane_max_scale(dev_priv, fb);
188346d12f91SDave Airlie }
188446d12f91SDave Airlie
188546d12f91SDave Airlie ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
188646d12f91SDave Airlie min_scale, max_scale, true);
188746d12f91SDave Airlie if (ret)
188846d12f91SDave Airlie return ret;
188946d12f91SDave Airlie
189046d12f91SDave Airlie ret = skl_check_plane_surface(plane_state);
189146d12f91SDave Airlie if (ret)
189246d12f91SDave Airlie return ret;
189346d12f91SDave Airlie
189446d12f91SDave Airlie if (!plane_state->uapi.visible)
189546d12f91SDave Airlie return 0;
189646d12f91SDave Airlie
189746d12f91SDave Airlie ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
189846d12f91SDave Airlie if (ret)
189946d12f91SDave Airlie return ret;
190046d12f91SDave Airlie
190146d12f91SDave Airlie ret = intel_plane_check_src_coordinates(plane_state);
190246d12f91SDave Airlie if (ret)
190346d12f91SDave Airlie return ret;
190446d12f91SDave Airlie
190546d12f91SDave Airlie ret = skl_plane_check_nv12_rotation(plane_state);
190646d12f91SDave Airlie if (ret)
190746d12f91SDave Airlie return ret;
190846d12f91SDave Airlie
1909f9a7b19cSVille Syrjälä if (DISPLAY_VER(dev_priv) >= 11) {
1910f9a7b19cSVille Syrjälä plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb));
1911f9a7b19cSVille Syrjälä plane_state->force_black = pxp_is_borked(intel_fb_obj(fb));
1912f9a7b19cSVille Syrjälä }
1913f9a7b19cSVille Syrjälä
191446d12f91SDave Airlie /* HW only has 8 bits pixel precision, disable plane if invisible */
191546d12f91SDave Airlie if (!(plane_state->hw.alpha >> 8))
191646d12f91SDave Airlie plane_state->uapi.visible = false;
191746d12f91SDave Airlie
191846d12f91SDave Airlie plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
191946d12f91SDave Airlie
19202b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10)
192146d12f91SDave Airlie plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
192246d12f91SDave Airlie plane_state);
192346d12f91SDave Airlie
192446d12f91SDave Airlie if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
192546d12f91SDave Airlie icl_is_hdr_plane(dev_priv, plane->id))
192646d12f91SDave Airlie /* Enable and use MPEG-2 chroma siting */
192746d12f91SDave Airlie plane_state->cus_ctl = PLANE_CUS_ENABLE |
192846d12f91SDave Airlie PLANE_CUS_HPHASE_0 |
192946d12f91SDave Airlie PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
193046d12f91SDave Airlie else
193146d12f91SDave Airlie plane_state->cus_ctl = 0;
193246d12f91SDave Airlie
193346d12f91SDave Airlie return 0;
193446d12f91SDave Airlie }
193546d12f91SDave Airlie
skl_fbc_id_for_pipe(enum pipe pipe)1936b8ca477eSVille Syrjälä static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
193746d12f91SDave Airlie {
1938b8ca477eSVille Syrjälä return pipe - PIPE_A + INTEL_FBC_A;
1939b8ca477eSVille Syrjälä }
1940b8ca477eSVille Syrjälä
skl_plane_has_fbc(struct drm_i915_private * dev_priv,enum intel_fbc_id fbc_id,enum plane_id plane_id)1941b8ca477eSVille Syrjälä static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
1942b8ca477eSVille Syrjälä enum intel_fbc_id fbc_id, enum plane_id plane_id)
1943b8ca477eSVille Syrjälä {
194418e0deeeSMatt Roper if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0)
194546d12f91SDave Airlie return false;
194646d12f91SDave Airlie
1947b8ca477eSVille Syrjälä return plane_id == PLANE_PRIMARY;
194846d12f91SDave Airlie }
194946d12f91SDave Airlie
skl_plane_fbc(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)1950825bd833SVille Syrjälä static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
1951825bd833SVille Syrjälä enum pipe pipe, enum plane_id plane_id)
1952825bd833SVille Syrjälä {
1953b8ca477eSVille Syrjälä enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe);
1954b8ca477eSVille Syrjälä
1955b8ca477eSVille Syrjälä if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id))
195680b3842fSJani Nikula return dev_priv->display.fbc[fbc_id];
1957825bd833SVille Syrjälä else
1958825bd833SVille Syrjälä return NULL;
1959825bd833SVille Syrjälä }
1960825bd833SVille Syrjälä
skl_plane_has_planar(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)196146d12f91SDave Airlie static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
196246d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id)
196346d12f91SDave Airlie {
196446d12f91SDave Airlie /* Display WA #0870: skl, bxt */
196546d12f91SDave Airlie if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
196646d12f91SDave Airlie return false;
196746d12f91SDave Airlie
196893e7e61eSLucas De Marchi if (DISPLAY_VER(dev_priv) == 9 && pipe == PIPE_C)
196946d12f91SDave Airlie return false;
197046d12f91SDave Airlie
197146d12f91SDave Airlie if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
197246d12f91SDave Airlie return false;
197346d12f91SDave Airlie
197446d12f91SDave Airlie return true;
197546d12f91SDave Airlie }
197646d12f91SDave Airlie
skl_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)197746d12f91SDave Airlie static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
197846d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id,
197946d12f91SDave Airlie int *num_formats)
198046d12f91SDave Airlie {
198146d12f91SDave Airlie if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
198246d12f91SDave Airlie *num_formats = ARRAY_SIZE(skl_planar_formats);
198346d12f91SDave Airlie return skl_planar_formats;
198446d12f91SDave Airlie } else {
198546d12f91SDave Airlie *num_formats = ARRAY_SIZE(skl_plane_formats);
198646d12f91SDave Airlie return skl_plane_formats;
198746d12f91SDave Airlie }
198846d12f91SDave Airlie }
198946d12f91SDave Airlie
glk_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)199046d12f91SDave Airlie static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
199146d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id,
199246d12f91SDave Airlie int *num_formats)
199346d12f91SDave Airlie {
199446d12f91SDave Airlie if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
199546d12f91SDave Airlie *num_formats = ARRAY_SIZE(glk_planar_formats);
199646d12f91SDave Airlie return glk_planar_formats;
199746d12f91SDave Airlie } else {
199846d12f91SDave Airlie *num_formats = ARRAY_SIZE(skl_plane_formats);
199946d12f91SDave Airlie return skl_plane_formats;
200046d12f91SDave Airlie }
200146d12f91SDave Airlie }
200246d12f91SDave Airlie
icl_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)200346d12f91SDave Airlie static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
200446d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id,
200546d12f91SDave Airlie int *num_formats)
200646d12f91SDave Airlie {
200746d12f91SDave Airlie if (icl_is_hdr_plane(dev_priv, plane_id)) {
200846d12f91SDave Airlie *num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
200946d12f91SDave Airlie return icl_hdr_plane_formats;
201046d12f91SDave Airlie } else if (icl_is_nv12_y_plane(dev_priv, plane_id)) {
201146d12f91SDave Airlie *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
201246d12f91SDave Airlie return icl_sdr_y_plane_formats;
201346d12f91SDave Airlie } else {
201446d12f91SDave Airlie *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
201546d12f91SDave Airlie return icl_sdr_uv_plane_formats;
201646d12f91SDave Airlie }
201746d12f91SDave Airlie }
201846d12f91SDave Airlie
skl_plane_format_mod_supported(struct drm_plane * _plane,u32 format,u64 modifier)201946d12f91SDave Airlie static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
202046d12f91SDave Airlie u32 format, u64 modifier)
202146d12f91SDave Airlie {
202246d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(_plane);
202346d12f91SDave Airlie
2024e2b83294SImre Deak if (!intel_fb_plane_supports_modifier(plane, modifier))
202546d12f91SDave Airlie return false;
202646d12f91SDave Airlie
202746d12f91SDave Airlie switch (format) {
202846d12f91SDave Airlie case DRM_FORMAT_XRGB8888:
202946d12f91SDave Airlie case DRM_FORMAT_XBGR8888:
203046d12f91SDave Airlie case DRM_FORMAT_ARGB8888:
203146d12f91SDave Airlie case DRM_FORMAT_ABGR8888:
2032e359c47bSImre Deak if (intel_fb_is_ccs_modifier(modifier))
203346d12f91SDave Airlie return true;
203446d12f91SDave Airlie fallthrough;
203546d12f91SDave Airlie case DRM_FORMAT_RGB565:
203646d12f91SDave Airlie case DRM_FORMAT_XRGB2101010:
203746d12f91SDave Airlie case DRM_FORMAT_XBGR2101010:
203846d12f91SDave Airlie case DRM_FORMAT_ARGB2101010:
203946d12f91SDave Airlie case DRM_FORMAT_ABGR2101010:
204046d12f91SDave Airlie case DRM_FORMAT_YUYV:
204146d12f91SDave Airlie case DRM_FORMAT_YVYU:
204246d12f91SDave Airlie case DRM_FORMAT_UYVY:
204346d12f91SDave Airlie case DRM_FORMAT_VYUY:
204446d12f91SDave Airlie case DRM_FORMAT_NV12:
204546d12f91SDave Airlie case DRM_FORMAT_XYUV8888:
204646d12f91SDave Airlie case DRM_FORMAT_P010:
204746d12f91SDave Airlie case DRM_FORMAT_P012:
204846d12f91SDave Airlie case DRM_FORMAT_P016:
204946d12f91SDave Airlie case DRM_FORMAT_XVYU2101010:
205046d12f91SDave Airlie if (modifier == I915_FORMAT_MOD_Yf_TILED)
205146d12f91SDave Airlie return true;
205246d12f91SDave Airlie fallthrough;
205346d12f91SDave Airlie case DRM_FORMAT_C8:
205446d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
205546d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
205646d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
205746d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
205846d12f91SDave Airlie case DRM_FORMAT_Y210:
205946d12f91SDave Airlie case DRM_FORMAT_Y212:
206046d12f91SDave Airlie case DRM_FORMAT_Y216:
206146d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
206246d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
206346d12f91SDave Airlie if (modifier == DRM_FORMAT_MOD_LINEAR ||
206446d12f91SDave Airlie modifier == I915_FORMAT_MOD_X_TILED ||
206546d12f91SDave Airlie modifier == I915_FORMAT_MOD_Y_TILED)
206646d12f91SDave Airlie return true;
206746d12f91SDave Airlie fallthrough;
206846d12f91SDave Airlie default:
206946d12f91SDave Airlie return false;
207046d12f91SDave Airlie }
207146d12f91SDave Airlie }
207246d12f91SDave Airlie
gen12_plane_format_mod_supported(struct drm_plane * _plane,u32 format,u64 modifier)207346d12f91SDave Airlie static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
207446d12f91SDave Airlie u32 format, u64 modifier)
207546d12f91SDave Airlie {
207646d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(_plane);
207746d12f91SDave Airlie
2078e2b83294SImre Deak if (!intel_fb_plane_supports_modifier(plane, modifier))
207946d12f91SDave Airlie return false;
208046d12f91SDave Airlie
208146d12f91SDave Airlie switch (format) {
208246d12f91SDave Airlie case DRM_FORMAT_XRGB8888:
208346d12f91SDave Airlie case DRM_FORMAT_XBGR8888:
208446d12f91SDave Airlie case DRM_FORMAT_ARGB8888:
208546d12f91SDave Airlie case DRM_FORMAT_ABGR8888:
2086e359c47bSImre Deak if (intel_fb_is_ccs_modifier(modifier))
208746d12f91SDave Airlie return true;
208846d12f91SDave Airlie fallthrough;
208946d12f91SDave Airlie case DRM_FORMAT_YUYV:
209046d12f91SDave Airlie case DRM_FORMAT_YVYU:
209146d12f91SDave Airlie case DRM_FORMAT_UYVY:
209246d12f91SDave Airlie case DRM_FORMAT_VYUY:
209346d12f91SDave Airlie case DRM_FORMAT_NV12:
209446d12f91SDave Airlie case DRM_FORMAT_XYUV8888:
209546d12f91SDave Airlie case DRM_FORMAT_P010:
209646d12f91SDave Airlie case DRM_FORMAT_P012:
209746d12f91SDave Airlie case DRM_FORMAT_P016:
20980b2c31ddSImre Deak if (intel_fb_is_mc_ccs_modifier(modifier))
209946d12f91SDave Airlie return true;
210046d12f91SDave Airlie fallthrough;
210146d12f91SDave Airlie case DRM_FORMAT_RGB565:
210246d12f91SDave Airlie case DRM_FORMAT_XRGB2101010:
210346d12f91SDave Airlie case DRM_FORMAT_XBGR2101010:
210446d12f91SDave Airlie case DRM_FORMAT_ARGB2101010:
210546d12f91SDave Airlie case DRM_FORMAT_ABGR2101010:
210646d12f91SDave Airlie case DRM_FORMAT_XVYU2101010:
210746d12f91SDave Airlie case DRM_FORMAT_C8:
210846d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
210946d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
211046d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
211146d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
211246d12f91SDave Airlie case DRM_FORMAT_Y210:
211346d12f91SDave Airlie case DRM_FORMAT_Y212:
211446d12f91SDave Airlie case DRM_FORMAT_Y216:
211546d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
211646d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
2117072ce416SStanislav Lisovskiy if (!intel_fb_is_ccs_modifier(modifier))
211846d12f91SDave Airlie return true;
211946d12f91SDave Airlie fallthrough;
212046d12f91SDave Airlie default:
212146d12f91SDave Airlie return false;
212246d12f91SDave Airlie }
212346d12f91SDave Airlie }
212446d12f91SDave Airlie
212546d12f91SDave Airlie static const struct drm_plane_funcs skl_plane_funcs = {
212646d12f91SDave Airlie .update_plane = drm_atomic_helper_update_plane,
212746d12f91SDave Airlie .disable_plane = drm_atomic_helper_disable_plane,
212846d12f91SDave Airlie .destroy = intel_plane_destroy,
212946d12f91SDave Airlie .atomic_duplicate_state = intel_plane_duplicate_state,
213046d12f91SDave Airlie .atomic_destroy_state = intel_plane_destroy_state,
213146d12f91SDave Airlie .format_mod_supported = skl_plane_format_mod_supported,
213246d12f91SDave Airlie };
213346d12f91SDave Airlie
213446d12f91SDave Airlie static const struct drm_plane_funcs gen12_plane_funcs = {
213546d12f91SDave Airlie .update_plane = drm_atomic_helper_update_plane,
213646d12f91SDave Airlie .disable_plane = drm_atomic_helper_disable_plane,
213746d12f91SDave Airlie .destroy = intel_plane_destroy,
213846d12f91SDave Airlie .atomic_duplicate_state = intel_plane_duplicate_state,
213946d12f91SDave Airlie .atomic_destroy_state = intel_plane_destroy_state,
214046d12f91SDave Airlie .format_mod_supported = gen12_plane_format_mod_supported,
214146d12f91SDave Airlie };
214246d12f91SDave Airlie
214346d12f91SDave Airlie static void
skl_plane_enable_flip_done(struct intel_plane * plane)214446d12f91SDave Airlie skl_plane_enable_flip_done(struct intel_plane *plane)
214546d12f91SDave Airlie {
214646d12f91SDave Airlie struct drm_i915_private *i915 = to_i915(plane->base.dev);
214746d12f91SDave Airlie enum pipe pipe = plane->pipe;
214846d12f91SDave Airlie
214946d12f91SDave Airlie spin_lock_irq(&i915->irq_lock);
215046d12f91SDave Airlie bdw_enable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
215146d12f91SDave Airlie spin_unlock_irq(&i915->irq_lock);
215246d12f91SDave Airlie }
215346d12f91SDave Airlie
215446d12f91SDave Airlie static void
skl_plane_disable_flip_done(struct intel_plane * plane)215546d12f91SDave Airlie skl_plane_disable_flip_done(struct intel_plane *plane)
215646d12f91SDave Airlie {
215746d12f91SDave Airlie struct drm_i915_private *i915 = to_i915(plane->base.dev);
215846d12f91SDave Airlie enum pipe pipe = plane->pipe;
215946d12f91SDave Airlie
216046d12f91SDave Airlie spin_lock_irq(&i915->irq_lock);
216146d12f91SDave Airlie bdw_disable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
216246d12f91SDave Airlie spin_unlock_irq(&i915->irq_lock);
216346d12f91SDave Airlie }
216446d12f91SDave Airlie
skl_plane_has_rc_ccs(struct drm_i915_private * i915,enum pipe pipe,enum plane_id plane_id)2165e2b83294SImre Deak static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915,
2166e2b83294SImre Deak enum pipe pipe, enum plane_id plane_id)
2167e2b83294SImre Deak {
2168f2eb43f0SJuha-Pekka Heikkila /* Wa_14017240301 */
2169*b3749611SMatt Roper if (IS_GFX_GT_IP_STEP(to_gt(i915), IP_VER(12, 70), STEP_A0, STEP_B0) ||
2170*b3749611SMatt Roper IS_GFX_GT_IP_STEP(to_gt(i915), IP_VER(12, 71), STEP_A0, STEP_B0))
2171f2eb43f0SJuha-Pekka Heikkila return false;
2172f2eb43f0SJuha-Pekka Heikkila
2173e2b83294SImre Deak /* Wa_22011186057 */
2174cc0c986aSDnyaneshwar Bhadane if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
2175e2b83294SImre Deak return false;
2176e2b83294SImre Deak
2177e2b83294SImre Deak if (DISPLAY_VER(i915) >= 11)
2178e2b83294SImre Deak return true;
2179e2b83294SImre Deak
2180e2b83294SImre Deak if (IS_GEMINILAKE(i915))
2181e2b83294SImre Deak return pipe != PIPE_C;
2182e2b83294SImre Deak
2183e2b83294SImre Deak return pipe != PIPE_C &&
2184e2b83294SImre Deak (plane_id == PLANE_PRIMARY ||
2185e2b83294SImre Deak plane_id == PLANE_SPRITE0);
2186e2b83294SImre Deak }
2187e2b83294SImre Deak
gen12_plane_has_mc_ccs(struct drm_i915_private * i915,enum plane_id plane_id)2188e2b83294SImre Deak static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915,
2189e2b83294SImre Deak enum plane_id plane_id)
2190e2b83294SImre Deak {
2191da0c3e2cSImre Deak if (DISPLAY_VER(i915) < 12)
2192da0c3e2cSImre Deak return false;
2193da0c3e2cSImre Deak
2194d1702963SMatt Roper /* Wa_14010477008 */
2195e2b83294SImre Deak if (IS_DG1(i915) || IS_ROCKETLAKE(i915) ||
219648077b0bSDnyaneshwar Bhadane (IS_TIGERLAKE(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_D0)))
2197e2b83294SImre Deak return false;
2198e2b83294SImre Deak
2199e2b83294SImre Deak /* Wa_22011186057 */
2200cc0c986aSDnyaneshwar Bhadane if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
2201e2b83294SImre Deak return false;
2202e2b83294SImre Deak
22034c3afa72SMatt Roper /* Wa_14013215631 */
22044c3afa72SMatt Roper if (IS_DG2_DISPLAY_STEP(i915, STEP_A0, STEP_C0))
22054c3afa72SMatt Roper return false;
22064c3afa72SMatt Roper
2207e2b83294SImre Deak return plane_id < PLANE_SPRITE4;
2208e2b83294SImre Deak }
2209e2b83294SImre Deak
skl_get_plane_caps(struct drm_i915_private * i915,enum pipe pipe,enum plane_id plane_id)221010a657ddSImre Deak static u8 skl_get_plane_caps(struct drm_i915_private *i915,
221110a657ddSImre Deak enum pipe pipe, enum plane_id plane_id)
221210a657ddSImre Deak {
221310a657ddSImre Deak u8 caps = INTEL_PLANE_CAP_TILING_X;
221410a657ddSImre Deak
221510a657ddSImre Deak if (DISPLAY_VER(i915) < 13 || IS_ALDERLAKE_P(i915))
221610a657ddSImre Deak caps |= INTEL_PLANE_CAP_TILING_Y;
221710a657ddSImre Deak if (DISPLAY_VER(i915) < 12)
221810a657ddSImre Deak caps |= INTEL_PLANE_CAP_TILING_Yf;
2219072ce416SStanislav Lisovskiy if (HAS_4TILE(i915))
2220072ce416SStanislav Lisovskiy caps |= INTEL_PLANE_CAP_TILING_4;
222110a657ddSImre Deak
222210a657ddSImre Deak if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) {
222310a657ddSImre Deak caps |= INTEL_PLANE_CAP_CCS_RC;
222410a657ddSImre Deak if (DISPLAY_VER(i915) >= 12)
222510a657ddSImre Deak caps |= INTEL_PLANE_CAP_CCS_RC_CC;
222610a657ddSImre Deak }
222710a657ddSImre Deak
222810a657ddSImre Deak if (gen12_plane_has_mc_ccs(i915, plane_id))
222910a657ddSImre Deak caps |= INTEL_PLANE_CAP_CCS_MC;
223010a657ddSImre Deak
223110a657ddSImre Deak return caps;
223210a657ddSImre Deak }
223310a657ddSImre Deak
223446d12f91SDave Airlie struct intel_plane *
skl_universal_plane_create(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)223546d12f91SDave Airlie skl_universal_plane_create(struct drm_i915_private *dev_priv,
223646d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id)
223746d12f91SDave Airlie {
223846d12f91SDave Airlie const struct drm_plane_funcs *plane_funcs;
223946d12f91SDave Airlie struct intel_plane *plane;
224046d12f91SDave Airlie enum drm_plane_type plane_type;
224146d12f91SDave Airlie unsigned int supported_rotations;
224246d12f91SDave Airlie unsigned int supported_csc;
224346d12f91SDave Airlie const u64 *modifiers;
224446d12f91SDave Airlie const u32 *formats;
224546d12f91SDave Airlie int num_formats;
224646d12f91SDave Airlie int ret;
224746d12f91SDave Airlie
224846d12f91SDave Airlie plane = intel_plane_alloc();
224946d12f91SDave Airlie if (IS_ERR(plane))
225046d12f91SDave Airlie return plane;
225146d12f91SDave Airlie
225246d12f91SDave Airlie plane->pipe = pipe;
225346d12f91SDave Airlie plane->id = plane_id;
225446d12f91SDave Airlie plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
225546d12f91SDave Airlie
2256825bd833SVille Syrjälä intel_fbc_add_plane(skl_plane_fbc(dev_priv, pipe, plane_id), plane);
225746d12f91SDave Airlie
2258005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) {
225946d12f91SDave Airlie plane->min_width = icl_plane_min_width;
22600e959b4eSVidya Srinivas if (icl_is_hdr_plane(dev_priv, plane_id))
22610e959b4eSVidya Srinivas plane->max_width = icl_hdr_plane_max_width;
22620e959b4eSVidya Srinivas else
22630e959b4eSVidya Srinivas plane->max_width = icl_sdr_plane_max_width;
226446d12f91SDave Airlie plane->max_height = icl_plane_max_height;
22656195f850SVille Syrjälä plane->min_cdclk = icl_plane_min_cdclk;
22662b5a4562SMatt Roper } else if (DISPLAY_VER(dev_priv) >= 10) {
226746d12f91SDave Airlie plane->max_width = glk_plane_max_width;
226846d12f91SDave Airlie plane->max_height = skl_plane_max_height;
2269efc52308SVille Syrjälä plane->min_cdclk = glk_plane_min_cdclk;
227046d12f91SDave Airlie } else {
227146d12f91SDave Airlie plane->max_width = skl_plane_max_width;
227246d12f91SDave Airlie plane->max_height = skl_plane_max_height;
2273efc52308SVille Syrjälä plane->min_cdclk = skl_plane_min_cdclk;
227446d12f91SDave Airlie }
227546d12f91SDave Airlie
227646d12f91SDave Airlie plane->max_stride = skl_plane_max_stride;
2277f8a005ebSVille Syrjälä if (DISPLAY_VER(dev_priv) >= 11) {
2278f8a005ebSVille Syrjälä plane->update_noarm = icl_plane_update_noarm;
2279f8a005ebSVille Syrjälä plane->update_arm = icl_plane_update_arm;
2280f8a005ebSVille Syrjälä plane->disable_arm = icl_plane_disable_arm;
2281f8a005ebSVille Syrjälä } else {
2282890b6ec4SVille Syrjälä plane->update_noarm = skl_plane_update_noarm;
22838ac80733SVille Syrjälä plane->update_arm = skl_plane_update_arm;
22848ac80733SVille Syrjälä plane->disable_arm = skl_plane_disable_arm;
2285f8a005ebSVille Syrjälä }
228646d12f91SDave Airlie plane->get_hw_state = skl_plane_get_hw_state;
228746d12f91SDave Airlie plane->check_plane = skl_plane_check;
228846d12f91SDave Airlie
228946d12f91SDave Airlie if (plane_id == PLANE_PRIMARY) {
229093e7e61eSLucas De Marchi plane->need_async_flip_disable_wa = IS_DISPLAY_VER(dev_priv,
2291005e9537SMatt Roper 9, 10);
229246d12f91SDave Airlie plane->async_flip = skl_plane_async_flip;
229346d12f91SDave Airlie plane->enable_flip_done = skl_plane_enable_flip_done;
229446d12f91SDave Airlie plane->disable_flip_done = skl_plane_disable_flip_done;
229546d12f91SDave Airlie }
229646d12f91SDave Airlie
2297005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11)
229846d12f91SDave Airlie formats = icl_get_plane_formats(dev_priv, pipe,
229946d12f91SDave Airlie plane_id, &num_formats);
23002b5a4562SMatt Roper else if (DISPLAY_VER(dev_priv) >= 10)
230146d12f91SDave Airlie formats = glk_get_plane_formats(dev_priv, pipe,
230246d12f91SDave Airlie plane_id, &num_formats);
230346d12f91SDave Airlie else
230446d12f91SDave Airlie formats = skl_get_plane_formats(dev_priv, pipe,
230546d12f91SDave Airlie plane_id, &num_formats);
230646d12f91SDave Airlie
2307e2b83294SImre Deak if (DISPLAY_VER(dev_priv) >= 12)
230846d12f91SDave Airlie plane_funcs = &gen12_plane_funcs;
230946d12f91SDave Airlie else
231046d12f91SDave Airlie plane_funcs = &skl_plane_funcs;
231146d12f91SDave Airlie
231246d12f91SDave Airlie if (plane_id == PLANE_PRIMARY)
231346d12f91SDave Airlie plane_type = DRM_PLANE_TYPE_PRIMARY;
231446d12f91SDave Airlie else
231546d12f91SDave Airlie plane_type = DRM_PLANE_TYPE_OVERLAY;
231646d12f91SDave Airlie
231710a657ddSImre Deak modifiers = intel_fb_plane_get_modifiers(dev_priv,
231810a657ddSImre Deak skl_get_plane_caps(dev_priv, pipe, plane_id));
2319e2b83294SImre Deak
232046d12f91SDave Airlie ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
232146d12f91SDave Airlie 0, plane_funcs,
232246d12f91SDave Airlie formats, num_formats, modifiers,
232346d12f91SDave Airlie plane_type,
232446d12f91SDave Airlie "plane %d%c", plane_id + 1,
232546d12f91SDave Airlie pipe_name(pipe));
2326e2b83294SImre Deak
2327e2b83294SImre Deak kfree(modifiers);
2328e2b83294SImre Deak
232946d12f91SDave Airlie if (ret)
233046d12f91SDave Airlie goto fail;
233146d12f91SDave Airlie
23321649a4ccSMatt Roper if (DISPLAY_VER(dev_priv) >= 13)
23331649a4ccSMatt Roper supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
23341649a4ccSMatt Roper else
233546d12f91SDave Airlie supported_rotations =
233646d12f91SDave Airlie DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
233746d12f91SDave Airlie DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
233846d12f91SDave Airlie
2339c988d2dcSLucas De Marchi if (DISPLAY_VER(dev_priv) >= 11)
234046d12f91SDave Airlie supported_rotations |= DRM_MODE_REFLECT_X;
234146d12f91SDave Airlie
234246d12f91SDave Airlie drm_plane_create_rotation_property(&plane->base,
234346d12f91SDave Airlie DRM_MODE_ROTATE_0,
234446d12f91SDave Airlie supported_rotations);
234546d12f91SDave Airlie
234646d12f91SDave Airlie supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709);
234746d12f91SDave Airlie
23482b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10)
234946d12f91SDave Airlie supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020);
235046d12f91SDave Airlie
235146d12f91SDave Airlie drm_plane_create_color_properties(&plane->base,
235246d12f91SDave Airlie supported_csc,
235346d12f91SDave Airlie BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
235446d12f91SDave Airlie BIT(DRM_COLOR_YCBCR_FULL_RANGE),
235546d12f91SDave Airlie DRM_COLOR_YCBCR_BT709,
235646d12f91SDave Airlie DRM_COLOR_YCBCR_LIMITED_RANGE);
235746d12f91SDave Airlie
235846d12f91SDave Airlie drm_plane_create_alpha_property(&plane->base);
235946d12f91SDave Airlie drm_plane_create_blend_mode_property(&plane->base,
236046d12f91SDave Airlie BIT(DRM_MODE_BLEND_PIXEL_NONE) |
236146d12f91SDave Airlie BIT(DRM_MODE_BLEND_PREMULTI) |
236246d12f91SDave Airlie BIT(DRM_MODE_BLEND_COVERAGE));
236346d12f91SDave Airlie
236446d12f91SDave Airlie drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
236546d12f91SDave Airlie
2366005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12)
236746d12f91SDave Airlie drm_plane_enable_fb_damage_clips(&plane->base);
236846d12f91SDave Airlie
2369c988d2dcSLucas De Marchi if (DISPLAY_VER(dev_priv) >= 11)
237046d12f91SDave Airlie drm_plane_create_scaling_filter_property(&plane->base,
237146d12f91SDave Airlie BIT(DRM_SCALING_FILTER_DEFAULT) |
237246d12f91SDave Airlie BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
237346d12f91SDave Airlie
2374d372ba42SJani Nikula intel_plane_helper_add(plane);
237546d12f91SDave Airlie
237646d12f91SDave Airlie return plane;
237746d12f91SDave Airlie
237846d12f91SDave Airlie fail:
237946d12f91SDave Airlie intel_plane_free(plane);
238046d12f91SDave Airlie
238146d12f91SDave Airlie return ERR_PTR(ret);
238246d12f91SDave Airlie }
238346d12f91SDave Airlie
238446d12f91SDave Airlie void
skl_get_initial_plane_config(struct intel_crtc * crtc,struct intel_initial_plane_config * plane_config)238546d12f91SDave Airlie skl_get_initial_plane_config(struct intel_crtc *crtc,
238646d12f91SDave Airlie struct intel_initial_plane_config *plane_config)
238746d12f91SDave Airlie {
238846d12f91SDave Airlie struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
238946d12f91SDave Airlie struct drm_device *dev = crtc->base.dev;
239046d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(dev);
239146d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(crtc->base.primary);
239246d12f91SDave Airlie enum plane_id plane_id = plane->id;
239346d12f91SDave Airlie enum pipe pipe;
239446d12f91SDave Airlie u32 val, base, offset, stride_mult, tiling, alpha;
239546d12f91SDave Airlie int fourcc, pixel_format;
239646d12f91SDave Airlie unsigned int aligned_height;
239746d12f91SDave Airlie struct drm_framebuffer *fb;
239846d12f91SDave Airlie struct intel_framebuffer *intel_fb;
2399072ce416SStanislav Lisovskiy static_assert(PLANE_CTL_TILED_YF == PLANE_CTL_TILED_4);
240046d12f91SDave Airlie
240146d12f91SDave Airlie if (!plane->get_hw_state(plane, &pipe))
240246d12f91SDave Airlie return;
240346d12f91SDave Airlie
240446d12f91SDave Airlie drm_WARN_ON(dev, pipe != crtc->pipe);
240546d12f91SDave Airlie
24064d1b53dfSVille Syrjälä if (crtc_state->bigjoiner_pipes) {
240746d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
240846d12f91SDave Airlie "Unsupported bigjoiner configuration for initial FB\n");
240946d12f91SDave Airlie return;
241046d12f91SDave Airlie }
241146d12f91SDave Airlie
241246d12f91SDave Airlie intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
241346d12f91SDave Airlie if (!intel_fb) {
241446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n");
241546d12f91SDave Airlie return;
241646d12f91SDave Airlie }
241746d12f91SDave Airlie
241846d12f91SDave Airlie fb = &intel_fb->base;
241946d12f91SDave Airlie
242046d12f91SDave Airlie fb->dev = dev;
242146d12f91SDave Airlie
242246d12f91SDave Airlie val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id));
242346d12f91SDave Airlie
2424005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11)
242512d7d858SVille Syrjälä pixel_format = val & PLANE_CTL_FORMAT_MASK_ICL;
242646d12f91SDave Airlie else
242712d7d858SVille Syrjälä pixel_format = val & PLANE_CTL_FORMAT_MASK_SKL;
242846d12f91SDave Airlie
24292b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10) {
243012d7d858SVille Syrjälä u32 color_ctl;
243112d7d858SVille Syrjälä
243212d7d858SVille Syrjälä color_ctl = intel_de_read(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
243312d7d858SVille Syrjälä alpha = REG_FIELD_GET(PLANE_COLOR_ALPHA_MASK, color_ctl);
243446d12f91SDave Airlie } else {
243512d7d858SVille Syrjälä alpha = REG_FIELD_GET(PLANE_CTL_ALPHA_MASK, val);
243646d12f91SDave Airlie }
243746d12f91SDave Airlie
243846d12f91SDave Airlie fourcc = skl_format_to_fourcc(pixel_format,
243946d12f91SDave Airlie val & PLANE_CTL_ORDER_RGBX, alpha);
244046d12f91SDave Airlie fb->format = drm_format_info(fourcc);
244146d12f91SDave Airlie
244246d12f91SDave Airlie tiling = val & PLANE_CTL_TILED_MASK;
244346d12f91SDave Airlie switch (tiling) {
244446d12f91SDave Airlie case PLANE_CTL_TILED_LINEAR:
244546d12f91SDave Airlie fb->modifier = DRM_FORMAT_MOD_LINEAR;
244646d12f91SDave Airlie break;
244746d12f91SDave Airlie case PLANE_CTL_TILED_X:
244846d12f91SDave Airlie plane_config->tiling = I915_TILING_X;
244946d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_X_TILED;
245046d12f91SDave Airlie break;
245146d12f91SDave Airlie case PLANE_CTL_TILED_Y:
245246d12f91SDave Airlie plane_config->tiling = I915_TILING_Y;
245346d12f91SDave Airlie if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
2454f2eb43f0SJuha-Pekka Heikkila if (DISPLAY_VER(dev_priv) >= 14)
2455f2eb43f0SJuha-Pekka Heikkila fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_RC_CCS;
2456f2eb43f0SJuha-Pekka Heikkila else if (DISPLAY_VER(dev_priv) >= 12)
24574c3afa72SMatt Roper fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS;
24584c3afa72SMatt Roper else
24594c3afa72SMatt Roper fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
246046d12f91SDave Airlie else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
2461f2eb43f0SJuha-Pekka Heikkila if (DISPLAY_VER(dev_priv) >= 14)
2462f2eb43f0SJuha-Pekka Heikkila fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_MC_CCS;
2463f2eb43f0SJuha-Pekka Heikkila else
246446d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS;
246546d12f91SDave Airlie else
246646d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_Y_TILED;
246746d12f91SDave Airlie break;
2468072ce416SStanislav Lisovskiy case PLANE_CTL_TILED_YF: /* aka PLANE_CTL_TILED_4 on XE_LPD+ */
2469072ce416SStanislav Lisovskiy if (HAS_4TILE(dev_priv)) {
2470680025dcSJuha-Pekka Heikkilä u32 rc_mask = PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
2471680025dcSJuha-Pekka Heikkilä PLANE_CTL_CLEAR_COLOR_DISABLE;
2472680025dcSJuha-Pekka Heikkilä
2473680025dcSJuha-Pekka Heikkilä if ((val & rc_mask) == rc_mask)
24744c3afa72SMatt Roper fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_RC_CCS;
24754c3afa72SMatt Roper else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
24764c3afa72SMatt Roper fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_MC_CCS;
2477680025dcSJuha-Pekka Heikkilä else if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
2478680025dcSJuha-Pekka Heikkilä fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
24794c3afa72SMatt Roper else
2480072ce416SStanislav Lisovskiy fb->modifier = I915_FORMAT_MOD_4_TILED;
2481072ce416SStanislav Lisovskiy } else {
248246d12f91SDave Airlie if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
248346d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
248446d12f91SDave Airlie else
248546d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_Yf_TILED;
2486072ce416SStanislav Lisovskiy }
248746d12f91SDave Airlie break;
248846d12f91SDave Airlie default:
248946d12f91SDave Airlie MISSING_CASE(tiling);
249046d12f91SDave Airlie goto error;
249146d12f91SDave Airlie }
249246d12f91SDave Airlie
2493c5de2484SVille Syrjälä if (!dev_priv->params.enable_dpt &&
2494c5de2484SVille Syrjälä intel_fb_modifier_uses_dpt(dev_priv, fb->modifier)) {
2495c5de2484SVille Syrjälä drm_dbg_kms(&dev_priv->drm, "DPT disabled, skipping initial FB\n");
2496c5de2484SVille Syrjälä goto error;
2497c5de2484SVille Syrjälä }
2498c5de2484SVille Syrjälä
249946d12f91SDave Airlie /*
250046d12f91SDave Airlie * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
250146d12f91SDave Airlie * while i915 HW rotation is clockwise, thats why this swapping.
250246d12f91SDave Airlie */
250346d12f91SDave Airlie switch (val & PLANE_CTL_ROTATE_MASK) {
250446d12f91SDave Airlie case PLANE_CTL_ROTATE_0:
250546d12f91SDave Airlie plane_config->rotation = DRM_MODE_ROTATE_0;
250646d12f91SDave Airlie break;
250746d12f91SDave Airlie case PLANE_CTL_ROTATE_90:
250846d12f91SDave Airlie plane_config->rotation = DRM_MODE_ROTATE_270;
250946d12f91SDave Airlie break;
251046d12f91SDave Airlie case PLANE_CTL_ROTATE_180:
251146d12f91SDave Airlie plane_config->rotation = DRM_MODE_ROTATE_180;
251246d12f91SDave Airlie break;
251346d12f91SDave Airlie case PLANE_CTL_ROTATE_270:
251446d12f91SDave Airlie plane_config->rotation = DRM_MODE_ROTATE_90;
251546d12f91SDave Airlie break;
251646d12f91SDave Airlie }
251746d12f91SDave Airlie
2518c988d2dcSLucas De Marchi if (DISPLAY_VER(dev_priv) >= 11 && val & PLANE_CTL_FLIP_HORIZONTAL)
251946d12f91SDave Airlie plane_config->rotation |= DRM_MODE_REFLECT_X;
252046d12f91SDave Airlie
252146d12f91SDave Airlie /* 90/270 degree rotation would require extra work */
252246d12f91SDave Airlie if (drm_rotation_90_or_270(plane_config->rotation))
252346d12f91SDave Airlie goto error;
252446d12f91SDave Airlie
252512d7d858SVille Syrjälä base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & PLANE_SURF_ADDR_MASK;
252646d12f91SDave Airlie plane_config->base = base;
252746d12f91SDave Airlie
252846d12f91SDave Airlie offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id));
252947e157a5SJani Nikula drm_WARN_ON(&dev_priv->drm, offset != 0);
253046d12f91SDave Airlie
253146d12f91SDave Airlie val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id));
253212d7d858SVille Syrjälä fb->height = REG_FIELD_GET(PLANE_HEIGHT_MASK, val) + 1;
253312d7d858SVille Syrjälä fb->width = REG_FIELD_GET(PLANE_WIDTH_MASK, val) + 1;
253446d12f91SDave Airlie
253546d12f91SDave Airlie val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
253646d12f91SDave Airlie stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
2537e7367af1SJuha-Pekka Heikkilä
253812d7d858SVille Syrjälä fb->pitches[0] = REG_FIELD_GET(PLANE_STRIDE__MASK, val) * stride_mult;
253946d12f91SDave Airlie
254046d12f91SDave Airlie aligned_height = intel_fb_align_height(fb, 0, fb->height);
254146d12f91SDave Airlie
254246d12f91SDave Airlie plane_config->size = fb->pitches[0] * aligned_height;
254346d12f91SDave Airlie
254446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
254546d12f91SDave Airlie "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
254646d12f91SDave Airlie crtc->base.name, plane->base.name, fb->width, fb->height,
254746d12f91SDave Airlie fb->format->cpp[0] * 8, base, fb->pitches[0],
254846d12f91SDave Airlie plane_config->size);
254946d12f91SDave Airlie
255046d12f91SDave Airlie plane_config->fb = intel_fb;
255146d12f91SDave Airlie return;
255246d12f91SDave Airlie
255346d12f91SDave Airlie error:
255446d12f91SDave Airlie kfree(intel_fb);
255546d12f91SDave Airlie }
2556