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"
176dbd43dcSRodrigo Vivi #include "intel_dpt.h"
18f837a61fSImre Deak #include "intel_fb.h"
19825bd833SVille Syrjälä #include "intel_fbc.h"
20c1464a89SJani Nikula #include "intel_frontbuffer.h"
2146d12f91SDave Airlie #include "intel_psr.h"
22b1f5279bSJouni Högander #include "intel_psr_regs.h"
23714b1cdbSDave Airlie #include "skl_scaler.h"
2446d12f91SDave Airlie #include "skl_universal_plane.h"
258c866768SVille Syrjälä #include "skl_universal_plane_regs.h"
2642a0d256SVille Syrjälä #include "skl_watermark.h"
27ef6ba31dSAnshuman Gupta #include "pxp/intel_pxp.h"
2846d12f91SDave Airlie
2946d12f91SDave Airlie static const u32 skl_plane_formats[] = {
3046d12f91SDave Airlie DRM_FORMAT_C8,
3146d12f91SDave Airlie DRM_FORMAT_RGB565,
3246d12f91SDave Airlie DRM_FORMAT_XRGB8888,
3346d12f91SDave Airlie DRM_FORMAT_XBGR8888,
3446d12f91SDave Airlie DRM_FORMAT_ARGB8888,
3546d12f91SDave Airlie DRM_FORMAT_ABGR8888,
3646d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
3746d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
3846d12f91SDave Airlie DRM_FORMAT_XRGB16161616F,
3946d12f91SDave Airlie DRM_FORMAT_XBGR16161616F,
4046d12f91SDave Airlie DRM_FORMAT_YUYV,
4146d12f91SDave Airlie DRM_FORMAT_YVYU,
4246d12f91SDave Airlie DRM_FORMAT_UYVY,
4346d12f91SDave Airlie DRM_FORMAT_VYUY,
4446d12f91SDave Airlie DRM_FORMAT_XYUV8888,
4546d12f91SDave Airlie };
4646d12f91SDave Airlie
4746d12f91SDave Airlie static const u32 skl_planar_formats[] = {
4846d12f91SDave Airlie DRM_FORMAT_C8,
4946d12f91SDave Airlie DRM_FORMAT_RGB565,
5046d12f91SDave Airlie DRM_FORMAT_XRGB8888,
5146d12f91SDave Airlie DRM_FORMAT_XBGR8888,
5246d12f91SDave Airlie DRM_FORMAT_ARGB8888,
5346d12f91SDave Airlie DRM_FORMAT_ABGR8888,
5446d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
5546d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
5646d12f91SDave Airlie DRM_FORMAT_XRGB16161616F,
5746d12f91SDave Airlie DRM_FORMAT_XBGR16161616F,
5846d12f91SDave Airlie DRM_FORMAT_YUYV,
5946d12f91SDave Airlie DRM_FORMAT_YVYU,
6046d12f91SDave Airlie DRM_FORMAT_UYVY,
6146d12f91SDave Airlie DRM_FORMAT_VYUY,
6246d12f91SDave Airlie DRM_FORMAT_NV12,
6346d12f91SDave Airlie DRM_FORMAT_XYUV8888,
6446d12f91SDave Airlie };
6546d12f91SDave Airlie
6646d12f91SDave Airlie static const u32 glk_planar_formats[] = {
6746d12f91SDave Airlie DRM_FORMAT_C8,
6846d12f91SDave Airlie DRM_FORMAT_RGB565,
6946d12f91SDave Airlie DRM_FORMAT_XRGB8888,
7046d12f91SDave Airlie DRM_FORMAT_XBGR8888,
7146d12f91SDave Airlie DRM_FORMAT_ARGB8888,
7246d12f91SDave Airlie DRM_FORMAT_ABGR8888,
7346d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
7446d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
7546d12f91SDave Airlie DRM_FORMAT_XRGB16161616F,
7646d12f91SDave Airlie DRM_FORMAT_XBGR16161616F,
7746d12f91SDave Airlie DRM_FORMAT_YUYV,
7846d12f91SDave Airlie DRM_FORMAT_YVYU,
7946d12f91SDave Airlie DRM_FORMAT_UYVY,
8046d12f91SDave Airlie DRM_FORMAT_VYUY,
8146d12f91SDave Airlie DRM_FORMAT_NV12,
8246d12f91SDave Airlie DRM_FORMAT_XYUV8888,
8346d12f91SDave Airlie DRM_FORMAT_P010,
8446d12f91SDave Airlie DRM_FORMAT_P012,
8546d12f91SDave Airlie DRM_FORMAT_P016,
8646d12f91SDave Airlie };
8746d12f91SDave Airlie
8846d12f91SDave Airlie static const u32 icl_sdr_y_plane_formats[] = {
8946d12f91SDave Airlie DRM_FORMAT_C8,
9046d12f91SDave Airlie DRM_FORMAT_RGB565,
9146d12f91SDave Airlie DRM_FORMAT_XRGB8888,
9246d12f91SDave Airlie DRM_FORMAT_XBGR8888,
9346d12f91SDave Airlie DRM_FORMAT_ARGB8888,
9446d12f91SDave Airlie DRM_FORMAT_ABGR8888,
9546d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
9646d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
9746d12f91SDave Airlie DRM_FORMAT_ARGB2101010,
9846d12f91SDave Airlie DRM_FORMAT_ABGR2101010,
9946d12f91SDave Airlie DRM_FORMAT_YUYV,
10046d12f91SDave Airlie DRM_FORMAT_YVYU,
10146d12f91SDave Airlie DRM_FORMAT_UYVY,
10246d12f91SDave Airlie DRM_FORMAT_VYUY,
10346d12f91SDave Airlie DRM_FORMAT_Y210,
10446d12f91SDave Airlie DRM_FORMAT_Y212,
10546d12f91SDave Airlie DRM_FORMAT_Y216,
10646d12f91SDave Airlie DRM_FORMAT_XYUV8888,
10746d12f91SDave Airlie DRM_FORMAT_XVYU2101010,
10846d12f91SDave Airlie DRM_FORMAT_XVYU12_16161616,
10946d12f91SDave Airlie DRM_FORMAT_XVYU16161616,
11046d12f91SDave Airlie };
11146d12f91SDave Airlie
11246d12f91SDave Airlie static const u32 icl_sdr_uv_plane_formats[] = {
11346d12f91SDave Airlie DRM_FORMAT_C8,
11446d12f91SDave Airlie DRM_FORMAT_RGB565,
11546d12f91SDave Airlie DRM_FORMAT_XRGB8888,
11646d12f91SDave Airlie DRM_FORMAT_XBGR8888,
11746d12f91SDave Airlie DRM_FORMAT_ARGB8888,
11846d12f91SDave Airlie DRM_FORMAT_ABGR8888,
11946d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
12046d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
12146d12f91SDave Airlie DRM_FORMAT_ARGB2101010,
12246d12f91SDave Airlie DRM_FORMAT_ABGR2101010,
12346d12f91SDave Airlie DRM_FORMAT_YUYV,
12446d12f91SDave Airlie DRM_FORMAT_YVYU,
12546d12f91SDave Airlie DRM_FORMAT_UYVY,
12646d12f91SDave Airlie DRM_FORMAT_VYUY,
12746d12f91SDave Airlie DRM_FORMAT_NV12,
12846d12f91SDave Airlie DRM_FORMAT_P010,
12946d12f91SDave Airlie DRM_FORMAT_P012,
13046d12f91SDave Airlie DRM_FORMAT_P016,
13146d12f91SDave Airlie DRM_FORMAT_Y210,
13246d12f91SDave Airlie DRM_FORMAT_Y212,
13346d12f91SDave Airlie DRM_FORMAT_Y216,
13446d12f91SDave Airlie DRM_FORMAT_XYUV8888,
13546d12f91SDave Airlie DRM_FORMAT_XVYU2101010,
13646d12f91SDave Airlie DRM_FORMAT_XVYU12_16161616,
13746d12f91SDave Airlie DRM_FORMAT_XVYU16161616,
13846d12f91SDave Airlie };
13946d12f91SDave Airlie
14046d12f91SDave Airlie static const u32 icl_hdr_plane_formats[] = {
14146d12f91SDave Airlie DRM_FORMAT_C8,
14246d12f91SDave Airlie DRM_FORMAT_RGB565,
14346d12f91SDave Airlie DRM_FORMAT_XRGB8888,
14446d12f91SDave Airlie DRM_FORMAT_XBGR8888,
14546d12f91SDave Airlie DRM_FORMAT_ARGB8888,
14646d12f91SDave Airlie DRM_FORMAT_ABGR8888,
14746d12f91SDave Airlie DRM_FORMAT_XRGB2101010,
14846d12f91SDave Airlie DRM_FORMAT_XBGR2101010,
14946d12f91SDave Airlie DRM_FORMAT_ARGB2101010,
15046d12f91SDave Airlie DRM_FORMAT_ABGR2101010,
15146d12f91SDave Airlie DRM_FORMAT_XRGB16161616F,
15246d12f91SDave Airlie DRM_FORMAT_XBGR16161616F,
15346d12f91SDave Airlie DRM_FORMAT_ARGB16161616F,
15446d12f91SDave Airlie DRM_FORMAT_ABGR16161616F,
15546d12f91SDave Airlie DRM_FORMAT_YUYV,
15646d12f91SDave Airlie DRM_FORMAT_YVYU,
15746d12f91SDave Airlie DRM_FORMAT_UYVY,
15846d12f91SDave Airlie DRM_FORMAT_VYUY,
15946d12f91SDave Airlie DRM_FORMAT_NV12,
16046d12f91SDave Airlie DRM_FORMAT_P010,
16146d12f91SDave Airlie DRM_FORMAT_P012,
16246d12f91SDave Airlie DRM_FORMAT_P016,
16346d12f91SDave Airlie DRM_FORMAT_Y210,
16446d12f91SDave Airlie DRM_FORMAT_Y212,
16546d12f91SDave Airlie DRM_FORMAT_Y216,
16646d12f91SDave Airlie DRM_FORMAT_XYUV8888,
16746d12f91SDave Airlie DRM_FORMAT_XVYU2101010,
16846d12f91SDave Airlie DRM_FORMAT_XVYU12_16161616,
16946d12f91SDave Airlie DRM_FORMAT_XVYU16161616,
17046d12f91SDave Airlie };
17146d12f91SDave Airlie
skl_format_to_fourcc(int format,bool rgb_order,bool alpha)17246d12f91SDave Airlie int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
17346d12f91SDave Airlie {
17446d12f91SDave Airlie switch (format) {
17546d12f91SDave Airlie case PLANE_CTL_FORMAT_RGB_565:
17646d12f91SDave Airlie return DRM_FORMAT_RGB565;
17746d12f91SDave Airlie case PLANE_CTL_FORMAT_NV12:
17846d12f91SDave Airlie return DRM_FORMAT_NV12;
17946d12f91SDave Airlie case PLANE_CTL_FORMAT_XYUV:
18046d12f91SDave Airlie return DRM_FORMAT_XYUV8888;
18146d12f91SDave Airlie case PLANE_CTL_FORMAT_P010:
18246d12f91SDave Airlie return DRM_FORMAT_P010;
18346d12f91SDave Airlie case PLANE_CTL_FORMAT_P012:
18446d12f91SDave Airlie return DRM_FORMAT_P012;
18546d12f91SDave Airlie case PLANE_CTL_FORMAT_P016:
18646d12f91SDave Airlie return DRM_FORMAT_P016;
18746d12f91SDave Airlie case PLANE_CTL_FORMAT_Y210:
18846d12f91SDave Airlie return DRM_FORMAT_Y210;
18946d12f91SDave Airlie case PLANE_CTL_FORMAT_Y212:
19046d12f91SDave Airlie return DRM_FORMAT_Y212;
19146d12f91SDave Airlie case PLANE_CTL_FORMAT_Y216:
19246d12f91SDave Airlie return DRM_FORMAT_Y216;
19346d12f91SDave Airlie case PLANE_CTL_FORMAT_Y410:
19446d12f91SDave Airlie return DRM_FORMAT_XVYU2101010;
19546d12f91SDave Airlie case PLANE_CTL_FORMAT_Y412:
19646d12f91SDave Airlie return DRM_FORMAT_XVYU12_16161616;
19746d12f91SDave Airlie case PLANE_CTL_FORMAT_Y416:
19846d12f91SDave Airlie return DRM_FORMAT_XVYU16161616;
19946d12f91SDave Airlie default:
20046d12f91SDave Airlie case PLANE_CTL_FORMAT_XRGB_8888:
20146d12f91SDave Airlie if (rgb_order) {
20246d12f91SDave Airlie if (alpha)
20346d12f91SDave Airlie return DRM_FORMAT_ABGR8888;
20446d12f91SDave Airlie else
20546d12f91SDave Airlie return DRM_FORMAT_XBGR8888;
20646d12f91SDave Airlie } else {
20746d12f91SDave Airlie if (alpha)
20846d12f91SDave Airlie return DRM_FORMAT_ARGB8888;
20946d12f91SDave Airlie else
21046d12f91SDave Airlie return DRM_FORMAT_XRGB8888;
21146d12f91SDave Airlie }
21246d12f91SDave Airlie case PLANE_CTL_FORMAT_XRGB_2101010:
21346d12f91SDave Airlie if (rgb_order) {
21446d12f91SDave Airlie if (alpha)
21546d12f91SDave Airlie return DRM_FORMAT_ABGR2101010;
21646d12f91SDave Airlie else
21746d12f91SDave Airlie return DRM_FORMAT_XBGR2101010;
21846d12f91SDave Airlie } else {
21946d12f91SDave Airlie if (alpha)
22046d12f91SDave Airlie return DRM_FORMAT_ARGB2101010;
22146d12f91SDave Airlie else
22246d12f91SDave Airlie return DRM_FORMAT_XRGB2101010;
22346d12f91SDave Airlie }
22446d12f91SDave Airlie case PLANE_CTL_FORMAT_XRGB_16161616F:
22546d12f91SDave Airlie if (rgb_order) {
22646d12f91SDave Airlie if (alpha)
22746d12f91SDave Airlie return DRM_FORMAT_ABGR16161616F;
22846d12f91SDave Airlie else
22946d12f91SDave Airlie return DRM_FORMAT_XBGR16161616F;
23046d12f91SDave Airlie } else {
23146d12f91SDave Airlie if (alpha)
23246d12f91SDave Airlie return DRM_FORMAT_ARGB16161616F;
23346d12f91SDave Airlie else
23446d12f91SDave Airlie return DRM_FORMAT_XRGB16161616F;
23546d12f91SDave Airlie }
23646d12f91SDave Airlie }
23746d12f91SDave Airlie }
23846d12f91SDave Airlie
icl_nv12_y_plane_mask(struct drm_i915_private * i915)23946d12f91SDave Airlie static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
24046d12f91SDave Airlie {
2411649a4ccSMatt Roper if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
242df798d43SVille Syrjälä return BIT(PLANE_4) | BIT(PLANE_5);
24346d12f91SDave Airlie else
244df798d43SVille Syrjälä return BIT(PLANE_6) | BIT(PLANE_7);
24546d12f91SDave Airlie }
24646d12f91SDave Airlie
icl_is_nv12_y_plane(struct drm_i915_private * dev_priv,enum plane_id plane_id)24746d12f91SDave Airlie bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
24846d12f91SDave Airlie enum plane_id plane_id)
24946d12f91SDave Airlie {
250005e9537SMatt Roper return DISPLAY_VER(dev_priv) >= 11 &&
25146d12f91SDave Airlie icl_nv12_y_plane_mask(dev_priv) & BIT(plane_id);
25246d12f91SDave Airlie }
25346d12f91SDave Airlie
icl_hdr_plane_mask(void)254d29c410fSJani Nikula u8 icl_hdr_plane_mask(void)
255d29c410fSJani Nikula {
256df798d43SVille Syrjälä return BIT(PLANE_1) | BIT(PLANE_2) | BIT(PLANE_3);
257d29c410fSJani Nikula }
258d29c410fSJani Nikula
icl_is_hdr_plane(struct drm_i915_private * dev_priv,enum plane_id plane_id)25946d12f91SDave Airlie bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
26046d12f91SDave Airlie {
261005e9537SMatt Roper return DISPLAY_VER(dev_priv) >= 11 &&
26246d12f91SDave Airlie icl_hdr_plane_mask() & BIT(plane_id);
26346d12f91SDave Airlie }
26446d12f91SDave Airlie
icl_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)2656195f850SVille Syrjälä static int icl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
2666195f850SVille Syrjälä const struct intel_plane_state *plane_state)
2676195f850SVille Syrjälä {
2686195f850SVille Syrjälä unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
2696195f850SVille Syrjälä
2706195f850SVille Syrjälä /* two pixels per clock */
2716195f850SVille Syrjälä return DIV_ROUND_UP(pixel_rate, 2);
2726195f850SVille Syrjälä }
2736195f850SVille Syrjälä
27446d12f91SDave Airlie static void
glk_plane_ratio(const struct intel_plane_state * plane_state,unsigned int * num,unsigned int * den)275efc52308SVille Syrjälä glk_plane_ratio(const struct intel_plane_state *plane_state,
27646d12f91SDave Airlie unsigned int *num, unsigned int *den)
27746d12f91SDave Airlie {
27846d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
27946d12f91SDave Airlie
28046d12f91SDave Airlie if (fb->format->cpp[0] == 8) {
28146d12f91SDave Airlie *num = 10;
28246d12f91SDave Airlie *den = 8;
28346d12f91SDave Airlie } else {
284efc52308SVille Syrjälä *num = 1;
285efc52308SVille Syrjälä *den = 1;
286efc52308SVille Syrjälä }
287efc52308SVille Syrjälä }
288efc52308SVille Syrjälä
glk_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)289efc52308SVille Syrjälä static int glk_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
290efc52308SVille Syrjälä const struct intel_plane_state *plane_state)
291efc52308SVille Syrjälä {
292efc52308SVille Syrjälä unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
293efc52308SVille Syrjälä unsigned int num, den;
294efc52308SVille Syrjälä
295efc52308SVille Syrjälä glk_plane_ratio(plane_state, &num, &den);
296efc52308SVille Syrjälä
297efc52308SVille Syrjälä /* two pixels per clock */
298efc52308SVille Syrjälä return DIV_ROUND_UP(pixel_rate * num, 2 * den);
299efc52308SVille Syrjälä }
300efc52308SVille Syrjälä
301efc52308SVille Syrjälä static void
skl_plane_ratio(const struct intel_plane_state * plane_state,unsigned int * num,unsigned int * den)302efc52308SVille Syrjälä skl_plane_ratio(const struct intel_plane_state *plane_state,
303efc52308SVille Syrjälä unsigned int *num, unsigned int *den)
304efc52308SVille Syrjälä {
305efc52308SVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
306efc52308SVille Syrjälä
307efc52308SVille Syrjälä if (fb->format->cpp[0] == 8) {
30846d12f91SDave Airlie *num = 9;
30946d12f91SDave Airlie *den = 8;
31046d12f91SDave Airlie } else {
31146d12f91SDave Airlie *num = 1;
31246d12f91SDave Airlie *den = 1;
31346d12f91SDave Airlie }
31446d12f91SDave Airlie }
31546d12f91SDave Airlie
skl_plane_min_cdclk(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)31646d12f91SDave Airlie static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
31746d12f91SDave Airlie const struct intel_plane_state *plane_state)
31846d12f91SDave Airlie {
31946d12f91SDave Airlie unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
320efc52308SVille Syrjälä unsigned int num, den;
32146d12f91SDave Airlie
322efc52308SVille Syrjälä skl_plane_ratio(plane_state, &num, &den);
32346d12f91SDave Airlie
32446d12f91SDave Airlie return DIV_ROUND_UP(pixel_rate * num, den);
32546d12f91SDave Airlie }
32646d12f91SDave Airlie
skl_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)32746d12f91SDave Airlie static int skl_plane_max_width(const struct drm_framebuffer *fb,
32846d12f91SDave Airlie int color_plane,
32946d12f91SDave Airlie unsigned int rotation)
33046d12f91SDave Airlie {
33146d12f91SDave Airlie int cpp = fb->format->cpp[color_plane];
33246d12f91SDave Airlie
33346d12f91SDave Airlie switch (fb->modifier) {
33446d12f91SDave Airlie case DRM_FORMAT_MOD_LINEAR:
33546d12f91SDave Airlie case I915_FORMAT_MOD_X_TILED:
33646d12f91SDave Airlie /*
33746d12f91SDave Airlie * Validated limit is 4k, but has 5k should
33846d12f91SDave Airlie * work apart from the following features:
33946d12f91SDave Airlie * - Ytile (already limited to 4k)
34046d12f91SDave Airlie * - FP16 (already limited to 4k)
34146d12f91SDave Airlie * - render compression (already limited to 4k)
34246d12f91SDave Airlie * - KVMR sprite and cursor (don't care)
34346d12f91SDave Airlie * - horizontal panning (TODO verify this)
34446d12f91SDave Airlie * - pipe and plane scaling (TODO verify this)
34546d12f91SDave Airlie */
34646d12f91SDave Airlie if (cpp == 8)
34746d12f91SDave Airlie return 4096;
34846d12f91SDave Airlie else
34946d12f91SDave Airlie return 5120;
35046d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_CCS:
35146d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED_CCS:
35246d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
35346d12f91SDave Airlie /* FIXME AUX plane? */
35446d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED:
35546d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED:
35646d12f91SDave Airlie if (cpp == 8)
35746d12f91SDave Airlie return 2048;
35846d12f91SDave Airlie else
35946d12f91SDave Airlie return 4096;
36046d12f91SDave Airlie default:
36146d12f91SDave Airlie MISSING_CASE(fb->modifier);
36246d12f91SDave Airlie return 2048;
36346d12f91SDave Airlie }
36446d12f91SDave Airlie }
36546d12f91SDave Airlie
glk_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)36646d12f91SDave Airlie static int glk_plane_max_width(const struct drm_framebuffer *fb,
36746d12f91SDave Airlie int color_plane,
36846d12f91SDave Airlie unsigned int rotation)
36946d12f91SDave Airlie {
37046d12f91SDave Airlie int cpp = fb->format->cpp[color_plane];
37146d12f91SDave Airlie
37246d12f91SDave Airlie switch (fb->modifier) {
37346d12f91SDave Airlie case DRM_FORMAT_MOD_LINEAR:
37446d12f91SDave Airlie case I915_FORMAT_MOD_X_TILED:
37546d12f91SDave Airlie if (cpp == 8)
37646d12f91SDave Airlie return 4096;
37746d12f91SDave Airlie else
37846d12f91SDave Airlie return 5120;
37946d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_CCS:
38046d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED_CCS:
38146d12f91SDave Airlie /* FIXME AUX plane? */
38246d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED:
38346d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED:
38446d12f91SDave Airlie if (cpp == 8)
38546d12f91SDave Airlie return 2048;
38646d12f91SDave Airlie else
38746d12f91SDave Airlie return 5120;
38846d12f91SDave Airlie default:
38946d12f91SDave Airlie MISSING_CASE(fb->modifier);
39046d12f91SDave Airlie return 2048;
39146d12f91SDave Airlie }
39246d12f91SDave Airlie }
39346d12f91SDave Airlie
icl_plane_min_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)39446d12f91SDave Airlie static int icl_plane_min_width(const struct drm_framebuffer *fb,
39546d12f91SDave Airlie int color_plane,
39646d12f91SDave Airlie unsigned int rotation)
39746d12f91SDave Airlie {
39846d12f91SDave Airlie /* Wa_14011264657, Wa_14011050563: gen11+ */
39946d12f91SDave Airlie switch (fb->format->format) {
40046d12f91SDave Airlie case DRM_FORMAT_C8:
40146d12f91SDave Airlie return 18;
40246d12f91SDave Airlie case DRM_FORMAT_RGB565:
40346d12f91SDave Airlie return 10;
40446d12f91SDave Airlie case DRM_FORMAT_XRGB8888:
40546d12f91SDave Airlie case DRM_FORMAT_XBGR8888:
40646d12f91SDave Airlie case DRM_FORMAT_ARGB8888:
40746d12f91SDave Airlie case DRM_FORMAT_ABGR8888:
40846d12f91SDave Airlie case DRM_FORMAT_XRGB2101010:
40946d12f91SDave Airlie case DRM_FORMAT_XBGR2101010:
41046d12f91SDave Airlie case DRM_FORMAT_ARGB2101010:
41146d12f91SDave Airlie case DRM_FORMAT_ABGR2101010:
41246d12f91SDave Airlie case DRM_FORMAT_XVYU2101010:
41346d12f91SDave Airlie case DRM_FORMAT_Y212:
41446d12f91SDave Airlie case DRM_FORMAT_Y216:
41546d12f91SDave Airlie return 6;
41646d12f91SDave Airlie case DRM_FORMAT_NV12:
41746d12f91SDave Airlie return 20;
41846d12f91SDave Airlie case DRM_FORMAT_P010:
41946d12f91SDave Airlie case DRM_FORMAT_P012:
42046d12f91SDave Airlie case DRM_FORMAT_P016:
42146d12f91SDave Airlie return 12;
42246d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
42346d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
42446d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
42546d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
42646d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
42746d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
42846d12f91SDave Airlie return 4;
42946d12f91SDave Airlie default:
43046d12f91SDave Airlie return 1;
43146d12f91SDave Airlie }
43246d12f91SDave Airlie }
43346d12f91SDave Airlie
icl_hdr_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)4340e959b4eSVidya Srinivas static int icl_hdr_plane_max_width(const struct drm_framebuffer *fb,
4350e959b4eSVidya Srinivas int color_plane,
4360e959b4eSVidya Srinivas unsigned int rotation)
4370e959b4eSVidya Srinivas {
4380e959b4eSVidya Srinivas if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
4390e959b4eSVidya Srinivas return 4096;
4400e959b4eSVidya Srinivas else
4410e959b4eSVidya Srinivas return 5120;
4420e959b4eSVidya Srinivas }
4430e959b4eSVidya Srinivas
icl_sdr_plane_max_width(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)4440e959b4eSVidya Srinivas static int icl_sdr_plane_max_width(const struct drm_framebuffer *fb,
44546d12f91SDave Airlie int color_plane,
44646d12f91SDave Airlie unsigned int rotation)
44746d12f91SDave Airlie {
44846d12f91SDave Airlie return 5120;
44946d12f91SDave Airlie }
45046d12f91SDave Airlie
skl_plane_max_height(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)45146d12f91SDave Airlie static int skl_plane_max_height(const struct drm_framebuffer *fb,
45246d12f91SDave Airlie int color_plane,
45346d12f91SDave Airlie unsigned int rotation)
45446d12f91SDave Airlie {
45546d12f91SDave Airlie return 4096;
45646d12f91SDave Airlie }
45746d12f91SDave Airlie
icl_plane_max_height(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)45846d12f91SDave Airlie static int icl_plane_max_height(const struct drm_framebuffer *fb,
45946d12f91SDave Airlie int color_plane,
46046d12f91SDave Airlie unsigned int rotation)
46146d12f91SDave Airlie {
46246d12f91SDave Airlie return 4320;
46346d12f91SDave Airlie }
46446d12f91SDave Airlie
46546d12f91SDave Airlie static unsigned int
plane_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation,unsigned int max_pixels,unsigned int max_bytes)4661301ce34SVille Syrjälä plane_max_stride(struct intel_plane *plane,
4671301ce34SVille Syrjälä u32 pixel_format, u64 modifier,
4681301ce34SVille Syrjälä unsigned int rotation,
4691301ce34SVille Syrjälä unsigned int max_pixels,
4701301ce34SVille Syrjälä unsigned int max_bytes)
4711301ce34SVille Syrjälä {
4721301ce34SVille Syrjälä const struct drm_format_info *info = drm_format_info(pixel_format);
4731301ce34SVille Syrjälä int cpp = info->cpp[0];
4741301ce34SVille Syrjälä
4751301ce34SVille Syrjälä if (drm_rotation_90_or_270(rotation))
4761301ce34SVille Syrjälä return min(max_pixels, max_bytes / cpp);
4771301ce34SVille Syrjälä else
4781301ce34SVille Syrjälä return min(max_pixels * cpp, max_bytes);
4791301ce34SVille Syrjälä }
4801301ce34SVille Syrjälä
4811301ce34SVille Syrjälä static unsigned int
adl_plane_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation)4821301ce34SVille Syrjälä adl_plane_max_stride(struct intel_plane *plane,
4831301ce34SVille Syrjälä u32 pixel_format, u64 modifier,
4841301ce34SVille Syrjälä unsigned int rotation)
4851301ce34SVille Syrjälä {
4861301ce34SVille Syrjälä unsigned int max_pixels = 65536; /* PLANE_OFFSET limit */
4871301ce34SVille Syrjälä unsigned int max_bytes = 128 * 1024;
4881301ce34SVille Syrjälä
4891301ce34SVille Syrjälä return plane_max_stride(plane, pixel_format,
4901301ce34SVille Syrjälä modifier, rotation,
4911301ce34SVille Syrjälä max_pixels, max_bytes);
4921301ce34SVille Syrjälä }
4931301ce34SVille Syrjälä
4941301ce34SVille Syrjälä static unsigned int
skl_plane_max_stride(struct intel_plane * plane,u32 pixel_format,u64 modifier,unsigned int rotation)49546d12f91SDave Airlie skl_plane_max_stride(struct intel_plane *plane,
49646d12f91SDave Airlie u32 pixel_format, u64 modifier,
49746d12f91SDave Airlie unsigned int rotation)
49846d12f91SDave Airlie {
4991301ce34SVille Syrjälä unsigned int max_pixels = 8192; /* PLANE_OFFSET limit */
5001301ce34SVille Syrjälä unsigned int max_bytes = 32 * 1024;
50146d12f91SDave Airlie
5021301ce34SVille Syrjälä return plane_max_stride(plane, pixel_format,
5031301ce34SVille Syrjälä modifier, rotation,
5041301ce34SVille Syrjälä max_pixels, max_bytes);
505e7367af1SJuha-Pekka Heikkilä }
506e7367af1SJuha-Pekka Heikkilä
tgl_plane_min_alignment(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane)5077652126cSVille Syrjälä static u32 tgl_plane_min_alignment(struct intel_plane *plane,
508ee3c3e33SVille Syrjälä const struct drm_framebuffer *fb,
509ee3c3e33SVille Syrjälä int color_plane)
510ee3c3e33SVille Syrjälä {
5117652126cSVille Syrjälä struct drm_i915_private *i915 = to_i915(plane->base.dev);
5127652126cSVille Syrjälä /* PLANE_SURF GGTT -> DPT alignment */
5137652126cSVille Syrjälä int mult = intel_fb_uses_dpt(fb) ? 512 : 1;
514ee3c3e33SVille Syrjälä
515ee3c3e33SVille Syrjälä /* AUX_DIST needs only 4K alignment */
516ee3c3e33SVille Syrjälä if (intel_fb_is_ccs_aux_plane(fb, color_plane))
5177652126cSVille Syrjälä return mult * 4 * 1024;
518ee3c3e33SVille Syrjälä
519ee3c3e33SVille Syrjälä switch (fb->modifier) {
520ee3c3e33SVille Syrjälä case DRM_FORMAT_MOD_LINEAR:
521ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_X_TILED:
5227652126cSVille Syrjälä case I915_FORMAT_MOD_Y_TILED:
5237652126cSVille Syrjälä case I915_FORMAT_MOD_4_TILED:
5247652126cSVille Syrjälä /*
5257652126cSVille Syrjälä * FIXME ADL sees GGTT/DMAR faults with async
5267652126cSVille Syrjälä * flips unless we align to 16k at least.
5277652126cSVille Syrjälä * Figure out what's going on here...
5287652126cSVille Syrjälä */
5297652126cSVille Syrjälä if (IS_ALDERLAKE_P(i915) && HAS_ASYNC_FLIPS(i915))
5307652126cSVille Syrjälä return mult * 16 * 1024;
5317652126cSVille Syrjälä return mult * 4 * 1024;
532ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
533ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
534ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
535ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
536ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
537ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
538ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
539ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
540ee3c3e33SVille Syrjälä case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
541fca0abb2SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_BMG_CCS:
542fca0abb2SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_LNL_CCS:
5437652126cSVille Syrjälä /*
5447652126cSVille Syrjälä * Align to at least 4x1 main surface
5457652126cSVille Syrjälä * tiles (16K) to match 64B of AUX.
5467652126cSVille Syrjälä */
5477652126cSVille Syrjälä return max(mult * 4 * 1024, 16 * 1024);
5487652126cSVille Syrjälä default:
5497652126cSVille Syrjälä MISSING_CASE(fb->modifier);
5507652126cSVille Syrjälä return 0;
5517652126cSVille Syrjälä }
5527652126cSVille Syrjälä }
5537652126cSVille Syrjälä
skl_plane_min_alignment(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane)5547652126cSVille Syrjälä static u32 skl_plane_min_alignment(struct intel_plane *plane,
5557652126cSVille Syrjälä const struct drm_framebuffer *fb,
5567652126cSVille Syrjälä int color_plane)
5577652126cSVille Syrjälä {
5587652126cSVille Syrjälä /*
5597652126cSVille Syrjälä * AUX_DIST needs only 4K alignment,
5607652126cSVille Syrjälä * as does ICL UV PLANE_SURF.
5617652126cSVille Syrjälä */
5627652126cSVille Syrjälä if (color_plane != 0)
5637652126cSVille Syrjälä return 4 * 1024;
5647652126cSVille Syrjälä
5657652126cSVille Syrjälä switch (fb->modifier) {
5667652126cSVille Syrjälä case DRM_FORMAT_MOD_LINEAR:
5677652126cSVille Syrjälä case I915_FORMAT_MOD_X_TILED:
5687652126cSVille Syrjälä return 256 * 1024;
5697652126cSVille Syrjälä case I915_FORMAT_MOD_Y_TILED_CCS:
5707652126cSVille Syrjälä case I915_FORMAT_MOD_Yf_TILED_CCS:
5717652126cSVille Syrjälä case I915_FORMAT_MOD_Y_TILED:
5727652126cSVille Syrjälä case I915_FORMAT_MOD_Yf_TILED:
5737652126cSVille Syrjälä return 1 * 1024 * 1024;
574ee3c3e33SVille Syrjälä default:
575ee3c3e33SVille Syrjälä MISSING_CASE(fb->modifier);
576ee3c3e33SVille Syrjälä return 0;
577ee3c3e33SVille Syrjälä }
578ee3c3e33SVille Syrjälä }
579ee3c3e33SVille Syrjälä
58046d12f91SDave Airlie /* Preoffset values for YUV to RGB Conversion */
58146d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_HI 0x1800
58246d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_ME 0x0000
58346d12f91SDave Airlie #define PREOFF_YUV_TO_RGB_LO 0x1800
58446d12f91SDave Airlie
58546d12f91SDave Airlie #define ROFF(x) (((x) & 0xffff) << 16)
58646d12f91SDave Airlie #define GOFF(x) (((x) & 0xffff) << 0)
58746d12f91SDave Airlie #define BOFF(x) (((x) & 0xffff) << 16)
58846d12f91SDave Airlie
58946d12f91SDave Airlie /*
59046d12f91SDave Airlie * Programs the input color space conversion stage for ICL HDR planes.
59146d12f91SDave Airlie * Note that it is assumed that this stage always happens after YUV
59246d12f91SDave Airlie * range correction. Thus, the input to this stage is assumed to be
59346d12f91SDave Airlie * in full-range YCbCr.
59446d12f91SDave Airlie */
59546d12f91SDave 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)59646d12f91SDave Airlie icl_program_input_csc(struct intel_plane *plane,
59746d12f91SDave Airlie const struct intel_crtc_state *crtc_state,
59846d12f91SDave Airlie const struct intel_plane_state *plane_state)
59946d12f91SDave Airlie {
60046d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
60146d12f91SDave Airlie enum pipe pipe = plane->pipe;
60246d12f91SDave Airlie enum plane_id plane_id = plane->id;
60346d12f91SDave Airlie
60446d12f91SDave Airlie static const u16 input_csc_matrix[][9] = {
60546d12f91SDave Airlie /*
60646d12f91SDave Airlie * BT.601 full range YCbCr -> full range RGB
60746d12f91SDave Airlie * The matrix required is :
60846d12f91SDave Airlie * [1.000, 0.000, 1.371,
60946d12f91SDave Airlie * 1.000, -0.336, -0.698,
61046d12f91SDave Airlie * 1.000, 1.732, 0.0000]
61146d12f91SDave Airlie */
61246d12f91SDave Airlie [DRM_COLOR_YCBCR_BT601] = {
61346d12f91SDave Airlie 0x7AF8, 0x7800, 0x0,
61446d12f91SDave Airlie 0x8B28, 0x7800, 0x9AC0,
61546d12f91SDave Airlie 0x0, 0x7800, 0x7DD8,
61646d12f91SDave Airlie },
61746d12f91SDave Airlie /*
61846d12f91SDave Airlie * BT.709 full range YCbCr -> full range RGB
61946d12f91SDave Airlie * The matrix required is :
62046d12f91SDave Airlie * [1.000, 0.000, 1.574,
62146d12f91SDave Airlie * 1.000, -0.187, -0.468,
62246d12f91SDave Airlie * 1.000, 1.855, 0.0000]
62346d12f91SDave Airlie */
62446d12f91SDave Airlie [DRM_COLOR_YCBCR_BT709] = {
62546d12f91SDave Airlie 0x7C98, 0x7800, 0x0,
62646d12f91SDave Airlie 0x9EF8, 0x7800, 0xAC00,
62746d12f91SDave Airlie 0x0, 0x7800, 0x7ED8,
62846d12f91SDave Airlie },
62946d12f91SDave Airlie /*
63046d12f91SDave Airlie * BT.2020 full range YCbCr -> full range RGB
63146d12f91SDave Airlie * The matrix required is :
63246d12f91SDave Airlie * [1.000, 0.000, 1.474,
63346d12f91SDave Airlie * 1.000, -0.1645, -0.5713,
63446d12f91SDave Airlie * 1.000, 1.8814, 0.0000]
63546d12f91SDave Airlie */
63646d12f91SDave Airlie [DRM_COLOR_YCBCR_BT2020] = {
63746d12f91SDave Airlie 0x7BC8, 0x7800, 0x0,
63846d12f91SDave Airlie 0x8928, 0x7800, 0xAA88,
63946d12f91SDave Airlie 0x0, 0x7800, 0x7F10,
64046d12f91SDave Airlie },
64146d12f91SDave Airlie };
64246d12f91SDave Airlie const u16 *csc = input_csc_matrix[plane_state->hw.color_encoding];
64346d12f91SDave Airlie
64446d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
64546d12f91SDave Airlie ROFF(csc[0]) | GOFF(csc[1]));
64646d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
64746d12f91SDave Airlie BOFF(csc[2]));
64846d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
64946d12f91SDave Airlie ROFF(csc[3]) | GOFF(csc[4]));
65046d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
65146d12f91SDave Airlie BOFF(csc[5]));
65246d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
65346d12f91SDave Airlie ROFF(csc[6]) | GOFF(csc[7]));
65446d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
65546d12f91SDave Airlie BOFF(csc[8]));
65646d12f91SDave Airlie
65746d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
65846d12f91SDave Airlie PREOFF_YUV_TO_RGB_HI);
65946d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
66046d12f91SDave Airlie PREOFF_YUV_TO_RGB_ME);
66146d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
66246d12f91SDave Airlie PREOFF_YUV_TO_RGB_LO);
66346d12f91SDave Airlie intel_de_write_fw(dev_priv,
66446d12f91SDave Airlie PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
66546d12f91SDave Airlie intel_de_write_fw(dev_priv,
66646d12f91SDave Airlie PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
66746d12f91SDave Airlie intel_de_write_fw(dev_priv,
66846d12f91SDave Airlie PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
66946d12f91SDave Airlie }
67046d12f91SDave Airlie
skl_plane_stride_mult(const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)67146d12f91SDave Airlie static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
67246d12f91SDave Airlie int color_plane, unsigned int rotation)
67346d12f91SDave Airlie {
67446d12f91SDave Airlie /*
67546d12f91SDave Airlie * The stride is either expressed as a multiple of 64 bytes chunks for
67646d12f91SDave Airlie * linear buffers or in number of tiles for tiled buffers.
67746d12f91SDave Airlie */
67846d12f91SDave Airlie if (is_surface_linear(fb, color_plane))
67946d12f91SDave Airlie return 64;
68046d12f91SDave Airlie else if (drm_rotation_90_or_270(rotation))
68146d12f91SDave Airlie return intel_tile_height(fb, color_plane);
68246d12f91SDave Airlie else
68346d12f91SDave Airlie return intel_tile_width_bytes(fb, color_plane);
68446d12f91SDave Airlie }
68546d12f91SDave Airlie
skl_plane_stride(const struct intel_plane_state * plane_state,int color_plane)68646d12f91SDave Airlie static u32 skl_plane_stride(const struct intel_plane_state *plane_state,
68746d12f91SDave Airlie int color_plane)
68846d12f91SDave Airlie {
68946d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
69046d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
691e6d6f689SImre Deak u32 stride = plane_state->view.color_plane[color_plane].scanout_stride;
69246d12f91SDave Airlie
69346d12f91SDave Airlie if (color_plane >= fb->format->num_planes)
69446d12f91SDave Airlie return 0;
69546d12f91SDave Airlie
69646d12f91SDave Airlie return stride / skl_plane_stride_mult(fb, color_plane, rotation);
69746d12f91SDave Airlie }
69846d12f91SDave Airlie
skl_plane_ddb_reg_val(const struct skl_ddb_entry * entry)69998719270SVille Syrjälä static u32 skl_plane_ddb_reg_val(const struct skl_ddb_entry *entry)
70019be15dcSVille Syrjälä {
70119be15dcSVille Syrjälä if (!entry->end)
70219be15dcSVille Syrjälä return 0;
70319be15dcSVille Syrjälä
70419be15dcSVille Syrjälä return PLANE_BUF_END(entry->end - 1) |
70519be15dcSVille Syrjälä PLANE_BUF_START(entry->start);
70619be15dcSVille Syrjälä }
70719be15dcSVille Syrjälä
skl_plane_wm_reg_val(const struct skl_wm_level * level)70898719270SVille Syrjälä static u32 skl_plane_wm_reg_val(const struct skl_wm_level *level)
70919be15dcSVille Syrjälä {
71019be15dcSVille Syrjälä u32 val = 0;
71119be15dcSVille Syrjälä
71219be15dcSVille Syrjälä if (level->enable)
71319be15dcSVille Syrjälä val |= PLANE_WM_EN;
71419be15dcSVille Syrjälä if (level->ignore_lines)
71519be15dcSVille Syrjälä val |= PLANE_WM_IGNORE_LINES;
71619be15dcSVille Syrjälä val |= REG_FIELD_PREP(PLANE_WM_BLOCKS_MASK, level->blocks);
71719be15dcSVille Syrjälä val |= REG_FIELD_PREP(PLANE_WM_LINES_MASK, level->lines);
71819be15dcSVille Syrjälä
71919be15dcSVille Syrjälä return val;
72019be15dcSVille Syrjälä }
72119be15dcSVille Syrjälä
skl_write_plane_wm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)72219be15dcSVille Syrjälä static void skl_write_plane_wm(struct intel_plane *plane,
72319be15dcSVille Syrjälä const struct intel_crtc_state *crtc_state)
72419be15dcSVille Syrjälä {
72519be15dcSVille Syrjälä struct drm_i915_private *i915 = to_i915(plane->base.dev);
72619be15dcSVille Syrjälä enum plane_id plane_id = plane->id;
72719be15dcSVille Syrjälä enum pipe pipe = plane->pipe;
72819be15dcSVille Syrjälä const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
72919be15dcSVille Syrjälä const struct skl_ddb_entry *ddb =
73019be15dcSVille Syrjälä &crtc_state->wm.skl.plane_ddb[plane_id];
73119be15dcSVille Syrjälä const struct skl_ddb_entry *ddb_y =
73219be15dcSVille Syrjälä &crtc_state->wm.skl.plane_ddb_y[plane_id];
73319be15dcSVille Syrjälä int level;
73419be15dcSVille Syrjälä
73519be15dcSVille Syrjälä for (level = 0; level < i915->display.wm.num_levels; level++)
73619be15dcSVille Syrjälä intel_de_write_fw(i915, PLANE_WM(pipe, plane_id, level),
73719be15dcSVille Syrjälä skl_plane_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
73819be15dcSVille Syrjälä
73919be15dcSVille Syrjälä intel_de_write_fw(i915, PLANE_WM_TRANS(pipe, plane_id),
74019be15dcSVille Syrjälä skl_plane_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
74119be15dcSVille Syrjälä
74219be15dcSVille Syrjälä if (HAS_HW_SAGV_WM(i915)) {
74319be15dcSVille Syrjälä const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
74419be15dcSVille Syrjälä
74519be15dcSVille Syrjälä intel_de_write_fw(i915, PLANE_WM_SAGV(pipe, plane_id),
74619be15dcSVille Syrjälä skl_plane_wm_reg_val(&wm->sagv.wm0));
74719be15dcSVille Syrjälä intel_de_write_fw(i915, PLANE_WM_SAGV_TRANS(pipe, plane_id),
74819be15dcSVille Syrjälä skl_plane_wm_reg_val(&wm->sagv.trans_wm));
74919be15dcSVille Syrjälä }
75019be15dcSVille Syrjälä
75119be15dcSVille Syrjälä intel_de_write_fw(i915, PLANE_BUF_CFG(pipe, plane_id),
75219be15dcSVille Syrjälä skl_plane_ddb_reg_val(ddb));
75319be15dcSVille Syrjälä
75419be15dcSVille Syrjälä if (DISPLAY_VER(i915) < 11)
75519be15dcSVille Syrjälä intel_de_write_fw(i915, PLANE_NV12_BUF_CFG(pipe, plane_id),
75619be15dcSVille Syrjälä skl_plane_ddb_reg_val(ddb_y));
75719be15dcSVille Syrjälä }
75819be15dcSVille Syrjälä
75946d12f91SDave Airlie static void
skl_plane_disable_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)7608ac80733SVille Syrjälä skl_plane_disable_arm(struct intel_plane *plane,
76146d12f91SDave Airlie const struct intel_crtc_state *crtc_state)
76246d12f91SDave Airlie {
76346d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
76446d12f91SDave Airlie enum plane_id plane_id = plane->id;
76546d12f91SDave Airlie enum pipe pipe = plane->pipe;
76646d12f91SDave Airlie
767f8a005ebSVille Syrjälä skl_write_plane_wm(plane, crtc_state);
768f8a005ebSVille Syrjälä
769f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
770f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
771f8a005ebSVille Syrjälä }
772f8a005ebSVille Syrjälä
icl_plane_disable_sel_fetch_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)773b1f5279bSJouni Högander static void icl_plane_disable_sel_fetch_arm(struct intel_plane *plane,
774b1f5279bSJouni Högander const struct intel_crtc_state *crtc_state)
775b1f5279bSJouni Högander {
776b1f5279bSJouni Högander struct drm_i915_private *i915 = to_i915(plane->base.dev);
777b1f5279bSJouni Högander enum pipe pipe = plane->pipe;
778b1f5279bSJouni Högander
779b1f5279bSJouni Högander if (!crtc_state->enable_psr2_sel_fetch)
780b1f5279bSJouni Högander return;
781b1f5279bSJouni Högander
7820ff7639bSVille Syrjälä intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
783b1f5279bSJouni Högander }
784b1f5279bSJouni Högander
785f8a005ebSVille Syrjälä static void
icl_plane_disable_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state)786f8a005ebSVille Syrjälä icl_plane_disable_arm(struct intel_plane *plane,
787f8a005ebSVille Syrjälä const struct intel_crtc_state *crtc_state)
788f8a005ebSVille Syrjälä {
789f8a005ebSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
790f8a005ebSVille Syrjälä enum plane_id plane_id = plane->id;
791f8a005ebSVille Syrjälä enum pipe pipe = plane->pipe;
792f8a005ebSVille Syrjälä
79346d12f91SDave Airlie if (icl_is_hdr_plane(dev_priv, plane_id))
79446d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
79546d12f91SDave Airlie
79646d12f91SDave Airlie skl_write_plane_wm(plane, crtc_state);
79746d12f91SDave Airlie
798b1f5279bSJouni Högander icl_plane_disable_sel_fetch_arm(plane, crtc_state);
79946d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
80046d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
80146d12f91SDave Airlie }
80246d12f91SDave Airlie
80346d12f91SDave Airlie static bool
skl_plane_get_hw_state(struct intel_plane * plane,enum pipe * pipe)80446d12f91SDave Airlie skl_plane_get_hw_state(struct intel_plane *plane,
80546d12f91SDave Airlie enum pipe *pipe)
80646d12f91SDave Airlie {
80746d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
80846d12f91SDave Airlie enum intel_display_power_domain power_domain;
80946d12f91SDave Airlie enum plane_id plane_id = plane->id;
81046d12f91SDave Airlie intel_wakeref_t wakeref;
81146d12f91SDave Airlie bool ret;
81246d12f91SDave Airlie
81346d12f91SDave Airlie power_domain = POWER_DOMAIN_PIPE(plane->pipe);
81446d12f91SDave Airlie wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
81546d12f91SDave Airlie if (!wakeref)
81646d12f91SDave Airlie return false;
81746d12f91SDave Airlie
81846d12f91SDave Airlie ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
81946d12f91SDave Airlie
82046d12f91SDave Airlie *pipe = plane->pipe;
82146d12f91SDave Airlie
82246d12f91SDave Airlie intel_display_power_put(dev_priv, power_domain, wakeref);
82346d12f91SDave Airlie
82446d12f91SDave Airlie return ret;
82546d12f91SDave Airlie }
82646d12f91SDave Airlie
skl_plane_ctl_format(u32 pixel_format)82746d12f91SDave Airlie static u32 skl_plane_ctl_format(u32 pixel_format)
82846d12f91SDave Airlie {
82946d12f91SDave Airlie switch (pixel_format) {
83046d12f91SDave Airlie case DRM_FORMAT_C8:
83146d12f91SDave Airlie return PLANE_CTL_FORMAT_INDEXED;
83246d12f91SDave Airlie case DRM_FORMAT_RGB565:
83346d12f91SDave Airlie return PLANE_CTL_FORMAT_RGB_565;
83446d12f91SDave Airlie case DRM_FORMAT_XBGR8888:
83546d12f91SDave Airlie case DRM_FORMAT_ABGR8888:
83646d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
83746d12f91SDave Airlie case DRM_FORMAT_XRGB8888:
83846d12f91SDave Airlie case DRM_FORMAT_ARGB8888:
83946d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_8888;
84046d12f91SDave Airlie case DRM_FORMAT_XBGR2101010:
84146d12f91SDave Airlie case DRM_FORMAT_ABGR2101010:
84246d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_2101010 | PLANE_CTL_ORDER_RGBX;
84346d12f91SDave Airlie case DRM_FORMAT_XRGB2101010:
84446d12f91SDave Airlie case DRM_FORMAT_ARGB2101010:
84546d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_2101010;
84646d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
84746d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
84846d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_16161616F | PLANE_CTL_ORDER_RGBX;
84946d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
85046d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
85146d12f91SDave Airlie return PLANE_CTL_FORMAT_XRGB_16161616F;
85246d12f91SDave Airlie case DRM_FORMAT_XYUV8888:
85346d12f91SDave Airlie return PLANE_CTL_FORMAT_XYUV;
85446d12f91SDave Airlie case DRM_FORMAT_YUYV:
85562f887aeSVille Syrjälä return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_YUYV;
85646d12f91SDave Airlie case DRM_FORMAT_YVYU:
85762f887aeSVille Syrjälä return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_YVYU;
85846d12f91SDave Airlie case DRM_FORMAT_UYVY:
85962f887aeSVille Syrjälä return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_UYVY;
86046d12f91SDave Airlie case DRM_FORMAT_VYUY:
86162f887aeSVille Syrjälä return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_ORDER_VYUY;
86246d12f91SDave Airlie case DRM_FORMAT_NV12:
86346d12f91SDave Airlie return PLANE_CTL_FORMAT_NV12;
86446d12f91SDave Airlie case DRM_FORMAT_P010:
86546d12f91SDave Airlie return PLANE_CTL_FORMAT_P010;
86646d12f91SDave Airlie case DRM_FORMAT_P012:
86746d12f91SDave Airlie return PLANE_CTL_FORMAT_P012;
86846d12f91SDave Airlie case DRM_FORMAT_P016:
86946d12f91SDave Airlie return PLANE_CTL_FORMAT_P016;
87046d12f91SDave Airlie case DRM_FORMAT_Y210:
87146d12f91SDave Airlie return PLANE_CTL_FORMAT_Y210;
87246d12f91SDave Airlie case DRM_FORMAT_Y212:
87346d12f91SDave Airlie return PLANE_CTL_FORMAT_Y212;
87446d12f91SDave Airlie case DRM_FORMAT_Y216:
87546d12f91SDave Airlie return PLANE_CTL_FORMAT_Y216;
87646d12f91SDave Airlie case DRM_FORMAT_XVYU2101010:
87746d12f91SDave Airlie return PLANE_CTL_FORMAT_Y410;
87846d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
87946d12f91SDave Airlie return PLANE_CTL_FORMAT_Y412;
88046d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
88146d12f91SDave Airlie return PLANE_CTL_FORMAT_Y416;
88246d12f91SDave Airlie default:
88346d12f91SDave Airlie MISSING_CASE(pixel_format);
88446d12f91SDave Airlie }
88546d12f91SDave Airlie
88646d12f91SDave Airlie return 0;
88746d12f91SDave Airlie }
88846d12f91SDave Airlie
skl_plane_ctl_alpha(const struct intel_plane_state * plane_state)88946d12f91SDave Airlie static u32 skl_plane_ctl_alpha(const struct intel_plane_state *plane_state)
89046d12f91SDave Airlie {
89146d12f91SDave Airlie if (!plane_state->hw.fb->format->has_alpha)
89246d12f91SDave Airlie return PLANE_CTL_ALPHA_DISABLE;
89346d12f91SDave Airlie
89446d12f91SDave Airlie switch (plane_state->hw.pixel_blend_mode) {
89546d12f91SDave Airlie case DRM_MODE_BLEND_PIXEL_NONE:
89646d12f91SDave Airlie return PLANE_CTL_ALPHA_DISABLE;
89746d12f91SDave Airlie case DRM_MODE_BLEND_PREMULTI:
89846d12f91SDave Airlie return PLANE_CTL_ALPHA_SW_PREMULTIPLY;
89946d12f91SDave Airlie case DRM_MODE_BLEND_COVERAGE:
90046d12f91SDave Airlie return PLANE_CTL_ALPHA_HW_PREMULTIPLY;
90146d12f91SDave Airlie default:
90246d12f91SDave Airlie MISSING_CASE(plane_state->hw.pixel_blend_mode);
90346d12f91SDave Airlie return PLANE_CTL_ALPHA_DISABLE;
90446d12f91SDave Airlie }
90546d12f91SDave Airlie }
90646d12f91SDave Airlie
glk_plane_color_ctl_alpha(const struct intel_plane_state * plane_state)90746d12f91SDave Airlie static u32 glk_plane_color_ctl_alpha(const struct intel_plane_state *plane_state)
90846d12f91SDave Airlie {
90946d12f91SDave Airlie if (!plane_state->hw.fb->format->has_alpha)
91046d12f91SDave Airlie return PLANE_COLOR_ALPHA_DISABLE;
91146d12f91SDave Airlie
91246d12f91SDave Airlie switch (plane_state->hw.pixel_blend_mode) {
91346d12f91SDave Airlie case DRM_MODE_BLEND_PIXEL_NONE:
91446d12f91SDave Airlie return PLANE_COLOR_ALPHA_DISABLE;
91546d12f91SDave Airlie case DRM_MODE_BLEND_PREMULTI:
91646d12f91SDave Airlie return PLANE_COLOR_ALPHA_SW_PREMULTIPLY;
91746d12f91SDave Airlie case DRM_MODE_BLEND_COVERAGE:
91846d12f91SDave Airlie return PLANE_COLOR_ALPHA_HW_PREMULTIPLY;
91946d12f91SDave Airlie default:
92046d12f91SDave Airlie MISSING_CASE(plane_state->hw.pixel_blend_mode);
92146d12f91SDave Airlie return PLANE_COLOR_ALPHA_DISABLE;
92246d12f91SDave Airlie }
92346d12f91SDave Airlie }
92446d12f91SDave Airlie
skl_plane_ctl_tiling(u64 fb_modifier)92546d12f91SDave Airlie static u32 skl_plane_ctl_tiling(u64 fb_modifier)
92646d12f91SDave Airlie {
92746d12f91SDave Airlie switch (fb_modifier) {
92846d12f91SDave Airlie case DRM_FORMAT_MOD_LINEAR:
92946d12f91SDave Airlie break;
93046d12f91SDave Airlie case I915_FORMAT_MOD_X_TILED:
93146d12f91SDave Airlie return PLANE_CTL_TILED_X;
93246d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED:
93346d12f91SDave Airlie return PLANE_CTL_TILED_Y;
934072ce416SStanislav Lisovskiy case I915_FORMAT_MOD_4_TILED:
935072ce416SStanislav Lisovskiy return PLANE_CTL_TILED_4;
9364c3afa72SMatt Roper case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
9374c3afa72SMatt Roper return PLANE_CTL_TILED_4 |
9384c3afa72SMatt Roper PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
9394c3afa72SMatt Roper PLANE_CTL_CLEAR_COLOR_DISABLE;
9404c3afa72SMatt Roper case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
9414c3afa72SMatt Roper return PLANE_CTL_TILED_4 |
9424c3afa72SMatt Roper PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE |
9434c3afa72SMatt Roper PLANE_CTL_CLEAR_COLOR_DISABLE;
944680025dcSJuha-Pekka Heikkilä case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
945680025dcSJuha-Pekka Heikkilä return PLANE_CTL_TILED_4 | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
946f2eb43f0SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
947f2eb43f0SJuha-Pekka Heikkila return PLANE_CTL_TILED_4 |
948f2eb43f0SJuha-Pekka Heikkila PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
949f2eb43f0SJuha-Pekka Heikkila PLANE_CTL_CLEAR_COLOR_DISABLE;
950f2eb43f0SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
951f2eb43f0SJuha-Pekka Heikkila return PLANE_CTL_TILED_4 | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
952f2eb43f0SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
953f2eb43f0SJuha-Pekka Heikkila return PLANE_CTL_TILED_4 | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
954fca0abb2SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_BMG_CCS:
955fca0abb2SJuha-Pekka Heikkila case I915_FORMAT_MOD_4_TILED_LNL_CCS:
956fca0abb2SJuha-Pekka Heikkila return PLANE_CTL_TILED_4 | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
95746d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_CCS:
95846d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
95946d12f91SDave Airlie return PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
96046d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
96146d12f91SDave Airlie return PLANE_CTL_TILED_Y |
96246d12f91SDave Airlie PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
96346d12f91SDave Airlie PLANE_CTL_CLEAR_COLOR_DISABLE;
96446d12f91SDave Airlie case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
96546d12f91SDave Airlie return PLANE_CTL_TILED_Y | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
96646d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED:
96746d12f91SDave Airlie return PLANE_CTL_TILED_YF;
96846d12f91SDave Airlie case I915_FORMAT_MOD_Yf_TILED_CCS:
96946d12f91SDave Airlie return PLANE_CTL_TILED_YF | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
97046d12f91SDave Airlie default:
97146d12f91SDave Airlie MISSING_CASE(fb_modifier);
97246d12f91SDave Airlie }
97346d12f91SDave Airlie
97446d12f91SDave Airlie return 0;
97546d12f91SDave Airlie }
97646d12f91SDave Airlie
skl_plane_ctl_rotate(unsigned int rotate)97746d12f91SDave Airlie static u32 skl_plane_ctl_rotate(unsigned int rotate)
97846d12f91SDave Airlie {
97946d12f91SDave Airlie switch (rotate) {
98046d12f91SDave Airlie case DRM_MODE_ROTATE_0:
98146d12f91SDave Airlie break;
98246d12f91SDave Airlie /*
98346d12f91SDave Airlie * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
98446d12f91SDave Airlie * while i915 HW rotation is clockwise, thats why this swapping.
98546d12f91SDave Airlie */
98646d12f91SDave Airlie case DRM_MODE_ROTATE_90:
98746d12f91SDave Airlie return PLANE_CTL_ROTATE_270;
98846d12f91SDave Airlie case DRM_MODE_ROTATE_180:
98946d12f91SDave Airlie return PLANE_CTL_ROTATE_180;
99046d12f91SDave Airlie case DRM_MODE_ROTATE_270:
99146d12f91SDave Airlie return PLANE_CTL_ROTATE_90;
99246d12f91SDave Airlie default:
99346d12f91SDave Airlie MISSING_CASE(rotate);
99446d12f91SDave Airlie }
99546d12f91SDave Airlie
99646d12f91SDave Airlie return 0;
99746d12f91SDave Airlie }
99846d12f91SDave Airlie
icl_plane_ctl_flip(unsigned int reflect)999c988d2dcSLucas De Marchi static u32 icl_plane_ctl_flip(unsigned int reflect)
100046d12f91SDave Airlie {
100146d12f91SDave Airlie switch (reflect) {
100246d12f91SDave Airlie case 0:
100346d12f91SDave Airlie break;
100446d12f91SDave Airlie case DRM_MODE_REFLECT_X:
100546d12f91SDave Airlie return PLANE_CTL_FLIP_HORIZONTAL;
100646d12f91SDave Airlie case DRM_MODE_REFLECT_Y:
100746d12f91SDave Airlie default:
100846d12f91SDave Airlie MISSING_CASE(reflect);
100946d12f91SDave Airlie }
101046d12f91SDave Airlie
101146d12f91SDave Airlie return 0;
101246d12f91SDave Airlie }
101346d12f91SDave Airlie
adlp_plane_ctl_arb_slots(const struct intel_plane_state * plane_state)10140b86952dSVille Syrjälä static u32 adlp_plane_ctl_arb_slots(const struct intel_plane_state *plane_state)
10150b86952dSVille Syrjälä {
10160b86952dSVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
10170b86952dSVille Syrjälä
10180b86952dSVille Syrjälä if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
10190b86952dSVille Syrjälä switch (fb->format->cpp[0]) {
10200b86952dSVille Syrjälä case 2:
10210b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(1);
10220b86952dSVille Syrjälä default:
10230b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(0);
10240b86952dSVille Syrjälä }
10250b86952dSVille Syrjälä } else {
10260b86952dSVille Syrjälä switch (fb->format->cpp[0]) {
10270b86952dSVille Syrjälä case 8:
10280b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(3);
10290b86952dSVille Syrjälä case 4:
10300b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(1);
10310b86952dSVille Syrjälä default:
10320b86952dSVille Syrjälä return PLANE_CTL_ARB_SLOTS(0);
10330b86952dSVille Syrjälä }
10340b86952dSVille Syrjälä }
10350b86952dSVille Syrjälä }
10360b86952dSVille Syrjälä
skl_plane_ctl_crtc(const struct intel_crtc_state * crtc_state)103746d12f91SDave Airlie static u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
103846d12f91SDave Airlie {
103946d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
104046d12f91SDave Airlie u32 plane_ctl = 0;
104146d12f91SDave Airlie
10422b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10)
104346d12f91SDave Airlie return plane_ctl;
104446d12f91SDave Airlie
104546d12f91SDave Airlie if (crtc_state->gamma_enable)
104646d12f91SDave Airlie plane_ctl |= PLANE_CTL_PIPE_GAMMA_ENABLE;
104746d12f91SDave Airlie
104846d12f91SDave Airlie if (crtc_state->csc_enable)
104946d12f91SDave Airlie plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
105046d12f91SDave Airlie
105146d12f91SDave Airlie return plane_ctl;
105246d12f91SDave Airlie }
105346d12f91SDave Airlie
skl_plane_ctl(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)105446d12f91SDave Airlie static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
105546d12f91SDave Airlie const struct intel_plane_state *plane_state)
105646d12f91SDave Airlie {
105746d12f91SDave Airlie struct drm_i915_private *dev_priv =
105846d12f91SDave Airlie to_i915(plane_state->uapi.plane->dev);
105946d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
106046d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
106146d12f91SDave Airlie const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
106246d12f91SDave Airlie u32 plane_ctl;
106346d12f91SDave Airlie
106446d12f91SDave Airlie plane_ctl = PLANE_CTL_ENABLE;
106546d12f91SDave Airlie
1066ad314fecSVille Syrjälä if (DISPLAY_VER(dev_priv) < 10) {
106746d12f91SDave Airlie plane_ctl |= skl_plane_ctl_alpha(plane_state);
106846d12f91SDave Airlie plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
106946d12f91SDave Airlie
107046d12f91SDave Airlie if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
107146d12f91SDave Airlie plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709;
107246d12f91SDave Airlie
107346d12f91SDave Airlie if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
107446d12f91SDave Airlie plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE;
107546d12f91SDave Airlie }
107646d12f91SDave Airlie
107746d12f91SDave Airlie plane_ctl |= skl_plane_ctl_format(fb->format->format);
107846d12f91SDave Airlie plane_ctl |= skl_plane_ctl_tiling(fb->modifier);
107946d12f91SDave Airlie plane_ctl |= skl_plane_ctl_rotate(rotation & DRM_MODE_ROTATE_MASK);
108046d12f91SDave Airlie
1081c988d2dcSLucas De Marchi if (DISPLAY_VER(dev_priv) >= 11)
1082c988d2dcSLucas De Marchi plane_ctl |= icl_plane_ctl_flip(rotation &
108346d12f91SDave Airlie DRM_MODE_REFLECT_MASK);
108446d12f91SDave Airlie
108546d12f91SDave Airlie if (key->flags & I915_SET_COLORKEY_DESTINATION)
108646d12f91SDave Airlie plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
108746d12f91SDave Airlie else if (key->flags & I915_SET_COLORKEY_SOURCE)
108846d12f91SDave Airlie plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
108946d12f91SDave Airlie
10901d2b8fd9SJosé Roberto de Souza /* Wa_22012358565:adl-p */
10910b86952dSVille Syrjälä if (DISPLAY_VER(dev_priv) == 13)
10920b86952dSVille Syrjälä plane_ctl |= adlp_plane_ctl_arb_slots(plane_state);
10930b86952dSVille Syrjälä
109446d12f91SDave Airlie return plane_ctl;
109546d12f91SDave Airlie }
109646d12f91SDave Airlie
glk_plane_color_ctl_crtc(const struct intel_crtc_state * crtc_state)109746d12f91SDave Airlie static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
109846d12f91SDave Airlie {
109946d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
110046d12f91SDave Airlie u32 plane_color_ctl = 0;
110146d12f91SDave Airlie
1102005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11)
110346d12f91SDave Airlie return plane_color_ctl;
110446d12f91SDave Airlie
110546d12f91SDave Airlie if (crtc_state->gamma_enable)
110646d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
110746d12f91SDave Airlie
110846d12f91SDave Airlie if (crtc_state->csc_enable)
110946d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
111046d12f91SDave Airlie
111146d12f91SDave Airlie return plane_color_ctl;
111246d12f91SDave Airlie }
111346d12f91SDave Airlie
glk_plane_color_ctl(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)111446d12f91SDave Airlie static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
111546d12f91SDave Airlie const struct intel_plane_state *plane_state)
111646d12f91SDave Airlie {
111746d12f91SDave Airlie struct drm_i915_private *dev_priv =
111846d12f91SDave Airlie to_i915(plane_state->uapi.plane->dev);
111946d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
112046d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
112146d12f91SDave Airlie u32 plane_color_ctl = 0;
112246d12f91SDave Airlie
112346d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
112446d12f91SDave Airlie plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
112546d12f91SDave Airlie
112646d12f91SDave Airlie if (fb->format->is_yuv && !icl_is_hdr_plane(dev_priv, plane->id)) {
112746d12f91SDave Airlie switch (plane_state->hw.color_encoding) {
112846d12f91SDave Airlie case DRM_COLOR_YCBCR_BT709:
112946d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
113046d12f91SDave Airlie break;
113146d12f91SDave Airlie case DRM_COLOR_YCBCR_BT2020:
113246d12f91SDave Airlie plane_color_ctl |=
113346d12f91SDave Airlie PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
113446d12f91SDave Airlie break;
113546d12f91SDave Airlie default:
113646d12f91SDave Airlie plane_color_ctl |=
113746d12f91SDave Airlie PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
113846d12f91SDave Airlie }
113946d12f91SDave Airlie if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
114046d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
114146d12f91SDave Airlie } else if (fb->format->is_yuv) {
114246d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
114346d12f91SDave Airlie if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
114446d12f91SDave Airlie plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
114546d12f91SDave Airlie }
114646d12f91SDave Airlie
1147841f262eSVille Syrjälä if (plane_state->force_black)
1148841f262eSVille Syrjälä plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
1149841f262eSVille Syrjälä
115046d12f91SDave Airlie return plane_color_ctl;
115146d12f91SDave Airlie }
115246d12f91SDave Airlie
skl_surf_address(const struct intel_plane_state * plane_state,int color_plane)115333e7a975SVille Syrjälä static u32 skl_surf_address(const struct intel_plane_state *plane_state,
115433e7a975SVille Syrjälä int color_plane)
115533e7a975SVille Syrjälä {
11565acbdcd1SJani Nikula struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
115733e7a975SVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
115833e7a975SVille Syrjälä u32 offset = plane_state->view.color_plane[color_plane].offset;
115933e7a975SVille Syrjälä
116033e7a975SVille Syrjälä if (intel_fb_uses_dpt(fb)) {
116192dff6c7SImre Deak /*
116292dff6c7SImre Deak * The DPT object contains only one vma, so the VMA's offset
116392dff6c7SImre Deak * within the DPT is always 0.
116492dff6c7SImre Deak */
1165185b2488SJuha-Pekka Heikkila drm_WARN_ON(&i915->drm, plane_state->dpt_vma &&
11666dbd43dcSRodrigo Vivi intel_dpt_offset(plane_state->dpt_vma));
11675acbdcd1SJani Nikula drm_WARN_ON(&i915->drm, offset & 0x1fffff);
116833e7a975SVille Syrjälä return offset >> 9;
116933e7a975SVille Syrjälä } else {
11705acbdcd1SJani Nikula drm_WARN_ON(&i915->drm, offset & 0xfff);
117133e7a975SVille Syrjälä return offset;
117233e7a975SVille Syrjälä }
117333e7a975SVille Syrjälä }
117433e7a975SVille Syrjälä
skl_plane_surf(const struct intel_plane_state * plane_state,int color_plane)117550faf7a1SVille Syrjälä static u32 skl_plane_surf(const struct intel_plane_state *plane_state,
117650faf7a1SVille Syrjälä int color_plane)
117750faf7a1SVille Syrjälä {
117850faf7a1SVille Syrjälä u32 plane_surf;
117950faf7a1SVille Syrjälä
118050faf7a1SVille Syrjälä plane_surf = intel_plane_ggtt_offset(plane_state) +
118150faf7a1SVille Syrjälä skl_surf_address(plane_state, color_plane);
118250faf7a1SVille Syrjälä
118350faf7a1SVille Syrjälä if (plane_state->decrypt)
118450faf7a1SVille Syrjälä plane_surf |= PLANE_SURF_DECRYPT;
118550faf7a1SVille Syrjälä
118650faf7a1SVille Syrjälä return plane_surf;
118750faf7a1SVille Syrjälä }
118850faf7a1SVille Syrjälä
skl_plane_aux_dist(const struct intel_plane_state * plane_state,int color_plane)1189366714b0SVille Syrjälä static u32 skl_plane_aux_dist(const struct intel_plane_state *plane_state,
1190366714b0SVille Syrjälä int color_plane)
1191366714b0SVille Syrjälä {
1192366714b0SVille Syrjälä struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
1193366714b0SVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
1194366714b0SVille Syrjälä int aux_plane = skl_main_to_aux_plane(fb, color_plane);
1195366714b0SVille Syrjälä u32 aux_dist;
1196366714b0SVille Syrjälä
1197366714b0SVille Syrjälä if (!aux_plane)
1198366714b0SVille Syrjälä return 0;
1199366714b0SVille Syrjälä
1200366714b0SVille Syrjälä aux_dist = skl_surf_address(plane_state, aux_plane) -
1201366714b0SVille Syrjälä skl_surf_address(plane_state, color_plane);
1202366714b0SVille Syrjälä
1203366714b0SVille Syrjälä if (DISPLAY_VER(i915) < 12)
1204366714b0SVille Syrjälä aux_dist |= PLANE_AUX_STRIDE(skl_plane_stride(plane_state, aux_plane));
1205366714b0SVille Syrjälä
1206366714b0SVille Syrjälä return aux_dist;
1207366714b0SVille Syrjälä }
1208366714b0SVille Syrjälä
skl_plane_keyval(const struct intel_plane_state * plane_state)12094682a6d9SVille Syrjälä static u32 skl_plane_keyval(const struct intel_plane_state *plane_state)
12104682a6d9SVille Syrjälä {
12114682a6d9SVille Syrjälä const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
12124682a6d9SVille Syrjälä
12134682a6d9SVille Syrjälä return key->min_value;
12144682a6d9SVille Syrjälä }
12154682a6d9SVille Syrjälä
skl_plane_keymax(const struct intel_plane_state * plane_state)12164682a6d9SVille Syrjälä static u32 skl_plane_keymax(const struct intel_plane_state *plane_state)
12174682a6d9SVille Syrjälä {
12184682a6d9SVille Syrjälä const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
12194682a6d9SVille Syrjälä u8 alpha = plane_state->hw.alpha >> 8;
12204682a6d9SVille Syrjälä
12214682a6d9SVille Syrjälä return (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
12224682a6d9SVille Syrjälä }
12234682a6d9SVille Syrjälä
skl_plane_keymsk(const struct intel_plane_state * plane_state)12244682a6d9SVille Syrjälä static u32 skl_plane_keymsk(const struct intel_plane_state *plane_state)
12254682a6d9SVille Syrjälä {
12264682a6d9SVille Syrjälä const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
12274682a6d9SVille Syrjälä u8 alpha = plane_state->hw.alpha >> 8;
12284682a6d9SVille Syrjälä u32 keymsk;
12294682a6d9SVille Syrjälä
12304682a6d9SVille Syrjälä keymsk = key->channel_mask & 0x7ffffff;
12314682a6d9SVille Syrjälä if (alpha < 0xff)
12324682a6d9SVille Syrjälä keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
12334682a6d9SVille Syrjälä
12344682a6d9SVille Syrjälä return keymsk;
12354682a6d9SVille Syrjälä }
12364682a6d9SVille Syrjälä
icl_plane_csc_load_black(struct intel_plane * plane)123717dbbe7bSVille Syrjälä static void icl_plane_csc_load_black(struct intel_plane *plane)
12386eba56f6SAnshuman Gupta {
123917dbbe7bSVille Syrjälä struct drm_i915_private *i915 = to_i915(plane->base.dev);
124017dbbe7bSVille Syrjälä enum plane_id plane_id = plane->id;
124117dbbe7bSVille Syrjälä enum pipe pipe = plane->pipe;
12426eba56f6SAnshuman Gupta
124317dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 0), 0);
124417dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 1), 0);
12456eba56f6SAnshuman Gupta
124617dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 2), 0);
124717dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 3), 0);
12486eba56f6SAnshuman Gupta
124917dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 4), 0);
125017dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_COEFF(pipe, plane_id, 5), 0);
12516eba56f6SAnshuman Gupta
125217dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 0), 0);
125317dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 1), 0);
125417dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_PREOFF(pipe, plane_id, 2), 0);
12556eba56f6SAnshuman Gupta
125617dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 0), 0);
125717dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 1), 0);
125817dbbe7bSVille Syrjälä intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0);
12596eba56f6SAnshuman Gupta }
12606eba56f6SAnshuman Gupta
icl_plane_color_plane(const struct intel_plane_state * plane_state)1261f8a005ebSVille Syrjälä static int icl_plane_color_plane(const struct intel_plane_state *plane_state)
1262fee07601SVille Syrjälä {
1263fee07601SVille Syrjälä /* Program the UV plane on planar master */
1264fee07601SVille Syrjälä if (plane_state->planar_linked_plane && !plane_state->planar_slave)
1265fee07601SVille Syrjälä return 1;
1266fee07601SVille Syrjälä else
1267fee07601SVille Syrjälä return 0;
1268fee07601SVille Syrjälä }
1269fee07601SVille Syrjälä
127046d12f91SDave 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)1271fee07601SVille Syrjälä skl_plane_update_noarm(struct intel_plane *plane,
127246d12f91SDave Airlie const struct intel_crtc_state *crtc_state,
1273fee07601SVille Syrjälä const struct intel_plane_state *plane_state)
127446d12f91SDave Airlie {
127546d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
127646d12f91SDave Airlie enum plane_id plane_id = plane->id;
127746d12f91SDave Airlie enum pipe pipe = plane->pipe;
1278f8a005ebSVille Syrjälä u32 stride = skl_plane_stride(plane_state, 0);
127946d12f91SDave Airlie int crtc_x = plane_state->uapi.dst.x1;
128046d12f91SDave Airlie int crtc_y = plane_state->uapi.dst.y1;
128146d12f91SDave Airlie u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
128246d12f91SDave Airlie u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
128346d12f91SDave Airlie
128446d12f91SDave Airlie /* The scaler will handle the output position */
128546d12f91SDave Airlie if (plane_state->scaler_id >= 0) {
128646d12f91SDave Airlie crtc_x = 0;
128746d12f91SDave Airlie crtc_y = 0;
128846d12f91SDave Airlie }
128946d12f91SDave Airlie
129012d7d858SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
129112d7d858SVille Syrjälä PLANE_STRIDE_(stride));
129246d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
129312d7d858SVille Syrjälä PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
129446d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
129512d7d858SVille Syrjälä PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
129646d12f91SDave Airlie
129746d12f91SDave Airlie skl_write_plane_wm(plane, crtc_state);
1298890b6ec4SVille Syrjälä }
1299890b6ec4SVille Syrjälä
1300890b6ec4SVille 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)1301fee07601SVille Syrjälä skl_plane_update_arm(struct intel_plane *plane,
1302890b6ec4SVille Syrjälä const struct intel_crtc_state *crtc_state,
1303fee07601SVille Syrjälä const struct intel_plane_state *plane_state)
1304890b6ec4SVille Syrjälä {
1305890b6ec4SVille Syrjälä struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1306890b6ec4SVille Syrjälä enum plane_id plane_id = plane->id;
1307890b6ec4SVille Syrjälä enum pipe pipe = plane->pipe;
1308f8a005ebSVille Syrjälä u32 x = plane_state->view.color_plane[0].x;
1309f8a005ebSVille Syrjälä u32 y = plane_state->view.color_plane[0].y;
1310f8a005ebSVille Syrjälä u32 plane_ctl, plane_color_ctl = 0;
1311890b6ec4SVille Syrjälä
1312f8a005ebSVille Syrjälä plane_ctl = plane_state->ctl |
1313f8a005ebSVille Syrjälä skl_plane_ctl_crtc(crtc_state);
1314890b6ec4SVille Syrjälä
1315b24d3614SVille Syrjälä /* see intel_plane_atomic_calc_changes() */
13162081c6aeSVille Syrjälä if (plane->need_async_flip_toggle_wa &&
1317b24d3614SVille Syrjälä crtc_state->async_flip_planes & BIT(plane->id))
1318b24d3614SVille Syrjälä plane_ctl |= PLANE_CTL_ASYNC_FLIP;
1319b24d3614SVille Syrjälä
1320890b6ec4SVille Syrjälä if (DISPLAY_VER(dev_priv) >= 10)
1321890b6ec4SVille Syrjälä plane_color_ctl = plane_state->color_ctl |
1322890b6ec4SVille Syrjälä glk_plane_color_ctl_crtc(crtc_state);
1323890b6ec4SVille Syrjälä
13244682a6d9SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
13254682a6d9SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
13264682a6d9SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
132746d12f91SDave Airlie
132846d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
132912d7d858SVille Syrjälä PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
133046d12f91SDave Airlie
1331366714b0SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
1332f8a005ebSVille Syrjälä skl_plane_aux_dist(plane_state, 0));
1333890b6ec4SVille Syrjälä
133446d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
133512d7d858SVille Syrjälä PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
133612d7d858SVille Syrjälä PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
133746d12f91SDave Airlie
1338890b6ec4SVille Syrjälä if (DISPLAY_VER(dev_priv) >= 10)
1339890b6ec4SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
134046d12f91SDave Airlie
134146d12f91SDave Airlie /*
13427c653e15SVille Syrjälä * Enable the scaler before the plane so that we don't
13437c653e15SVille Syrjälä * get a catastrophic underrun even if the two operations
13447c653e15SVille Syrjälä * end up happening in two different frames.
1345890b6ec4SVille Syrjälä *
1346890b6ec4SVille Syrjälä * TODO: split into noarm+arm pair
13477c653e15SVille Syrjälä */
13487c653e15SVille Syrjälä if (plane_state->scaler_id >= 0)
13497c653e15SVille Syrjälä skl_program_plane_scaler(plane, crtc_state, plane_state);
13507c653e15SVille Syrjälä
13517c653e15SVille Syrjälä /*
135246d12f91SDave Airlie * The control register self-arms if the plane was previously
135346d12f91SDave Airlie * disabled. Try to make the plane enable atomic by writing
135446d12f91SDave Airlie * the control register just before the surface register.
135546d12f91SDave Airlie */
135646d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
135750faf7a1SVille Syrjälä intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
1358f8a005ebSVille Syrjälä skl_plane_surf(plane_state, 0));
1359f8a005ebSVille Syrjälä }
1360f8a005ebSVille Syrjälä
icl_plane_update_sel_fetch_noarm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,int color_plane)1361b1f5279bSJouni Högander static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane,
1362b1f5279bSJouni Högander const struct intel_crtc_state *crtc_state,
1363b1f5279bSJouni Högander const struct intel_plane_state *plane_state,
1364b1f5279bSJouni Högander int color_plane)
1365b1f5279bSJouni Högander {
1366b1f5279bSJouni Högander struct drm_i915_private *i915 = to_i915(plane->base.dev);
1367b1f5279bSJouni Högander enum pipe pipe = plane->pipe;
1368b1f5279bSJouni Högander const struct drm_rect *clip;
1369b1f5279bSJouni Högander u32 val;
1370b1f5279bSJouni Högander int x, y;
1371b1f5279bSJouni Högander
1372b1f5279bSJouni Högander if (!crtc_state->enable_psr2_sel_fetch)
1373b1f5279bSJouni Högander return;
1374b1f5279bSJouni Högander
1375b1f5279bSJouni Högander clip = &plane_state->psr2_sel_fetch_area;
1376b1f5279bSJouni Högander
137716b65af8SJouni Högander if (crtc_state->enable_psr2_su_region_et)
137816b65af8SJouni Högander y = max(0, plane_state->uapi.dst.y1 - crtc_state->psr2_su_area.y1);
137916b65af8SJouni Högander else
138016b65af8SJouni Högander y = (clip->y1 + plane_state->uapi.dst.y1);
138116b65af8SJouni Högander val = y << 16;
1382b1f5279bSJouni Högander val |= plane_state->uapi.dst.x1;
13830ff7639bSVille Syrjälä intel_de_write_fw(i915, SEL_FETCH_PLANE_POS(pipe, plane->id), val);
1384b1f5279bSJouni Högander
1385b1f5279bSJouni Högander x = plane_state->view.color_plane[color_plane].x;
1386b1f5279bSJouni Högander
1387b1f5279bSJouni Högander /*
1388b1f5279bSJouni Högander * From Bspec: UV surface Start Y Position = half of Y plane Y
1389b1f5279bSJouni Högander * start position.
1390b1f5279bSJouni Högander */
1391b1f5279bSJouni Högander if (!color_plane)
1392b1f5279bSJouni Högander y = plane_state->view.color_plane[color_plane].y + clip->y1;
1393b1f5279bSJouni Högander else
1394b1f5279bSJouni Högander y = plane_state->view.color_plane[color_plane].y + clip->y1 / 2;
1395b1f5279bSJouni Högander
1396b1f5279bSJouni Högander val = y << 16 | x;
1397b1f5279bSJouni Högander
13980ff7639bSVille Syrjälä intel_de_write_fw(i915, SEL_FETCH_PLANE_OFFSET(pipe, plane->id),
1399b1f5279bSJouni Högander val);
1400b1f5279bSJouni Högander
1401b1f5279bSJouni Högander /* Sizes are 0 based */
1402b1f5279bSJouni Högander val = (drm_rect_height(clip) - 1) << 16;
1403b1f5279bSJouni Högander val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1;
14040ff7639bSVille Syrjälä intel_de_write_fw(i915, SEL_FETCH_PLANE_SIZE(pipe, plane->id), val);
1405b1f5279bSJouni Högander }
1406b1f5279bSJouni Högander
1407f8a005ebSVille 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)1408f8a005ebSVille Syrjälä icl_plane_update_noarm(struct intel_plane *plane,
1409f8a005ebSVille Syrjälä const struct intel_crtc_state *crtc_state,
1410f8a005ebSVille Syrjälä const struct intel_plane_state *plane_state)
1411f8a005ebSVille Syrjälä {
1412f8a005ebSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1413f8a005ebSVille Syrjälä enum plane_id plane_id = plane->id;
1414f8a005ebSVille Syrjälä enum pipe pipe = plane->pipe;
1415f8a005ebSVille Syrjälä int color_plane = icl_plane_color_plane(plane_state);
1416f8a005ebSVille Syrjälä u32 stride = skl_plane_stride(plane_state, color_plane);
1417f8a005ebSVille Syrjälä const struct drm_framebuffer *fb = plane_state->hw.fb;
1418f8a005ebSVille Syrjälä int crtc_x = plane_state->uapi.dst.x1;
1419f8a005ebSVille Syrjälä int crtc_y = plane_state->uapi.dst.y1;
1420f8a005ebSVille Syrjälä int x = plane_state->view.color_plane[color_plane].x;
1421f8a005ebSVille Syrjälä int y = plane_state->view.color_plane[color_plane].y;
1422f8a005ebSVille Syrjälä int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1423f8a005ebSVille Syrjälä int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1424f8a005ebSVille Syrjälä u32 plane_color_ctl;
1425f8a005ebSVille Syrjälä
1426f8a005ebSVille Syrjälä plane_color_ctl = plane_state->color_ctl |
1427f8a005ebSVille Syrjälä glk_plane_color_ctl_crtc(crtc_state);
1428f8a005ebSVille Syrjälä
1429f8a005ebSVille Syrjälä /* The scaler will handle the output position */
1430f8a005ebSVille Syrjälä if (plane_state->scaler_id >= 0) {
1431f8a005ebSVille Syrjälä crtc_x = 0;
1432f8a005ebSVille Syrjälä crtc_y = 0;
1433f8a005ebSVille Syrjälä }
1434f8a005ebSVille Syrjälä
1435f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
1436f8a005ebSVille Syrjälä PLANE_STRIDE_(stride));
1437f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
1438f8a005ebSVille Syrjälä PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
1439f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
1440f8a005ebSVille Syrjälä PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
1441f8a005ebSVille Syrjälä
1442f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
1443f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
1444f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
1445f8a005ebSVille Syrjälä
1446f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
1447f8a005ebSVille Syrjälä PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
1448f8a005ebSVille Syrjälä
1449f8a005ebSVille Syrjälä if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) {
1450f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0),
1451f8a005ebSVille Syrjälä lower_32_bits(plane_state->ccval));
1452f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 1),
1453f8a005ebSVille Syrjälä upper_32_bits(plane_state->ccval));
1454f8a005ebSVille Syrjälä }
1455f8a005ebSVille Syrjälä
1456680025dcSJuha-Pekka Heikkilä /* FLAT CCS doesn't need to program AUX_DIST */
14578ee35345SMatt Roper if (!HAS_FLAT_CCS(dev_priv) && DISPLAY_VER(dev_priv) < 20)
1458f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
1459f8a005ebSVille Syrjälä skl_plane_aux_dist(plane_state, color_plane));
1460f8a005ebSVille Syrjälä
1461f8a005ebSVille Syrjälä if (icl_is_hdr_plane(dev_priv, plane_id))
1462f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
1463f8a005ebSVille Syrjälä plane_state->cus_ctl);
1464f8a005ebSVille Syrjälä
1465f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
1466f8a005ebSVille Syrjälä
1467f8a005ebSVille Syrjälä if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
1468f8a005ebSVille Syrjälä icl_program_input_csc(plane, crtc_state, plane_state);
1469f8a005ebSVille Syrjälä
1470f8a005ebSVille Syrjälä skl_write_plane_wm(plane, crtc_state);
1471f8a005ebSVille Syrjälä
1472f8a005ebSVille Syrjälä /*
1473f8a005ebSVille Syrjälä * FIXME: pxp session invalidation can hit any time even at time of commit
1474f8a005ebSVille Syrjälä * or after the commit, display content will be garbage.
1475f8a005ebSVille Syrjälä */
1476f8a005ebSVille Syrjälä if (plane_state->force_black)
1477f8a005ebSVille Syrjälä icl_plane_csc_load_black(plane);
1478f8a005ebSVille Syrjälä
1479b1f5279bSJouni Högander icl_plane_update_sel_fetch_noarm(plane, crtc_state, plane_state, color_plane);
1480b1f5279bSJouni Högander }
1481b1f5279bSJouni Högander
icl_plane_update_sel_fetch_arm(struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)1482b1f5279bSJouni Högander static void icl_plane_update_sel_fetch_arm(struct intel_plane *plane,
1483b1f5279bSJouni Högander const struct intel_crtc_state *crtc_state,
1484b1f5279bSJouni Högander const struct intel_plane_state *plane_state)
1485b1f5279bSJouni Högander {
1486b1f5279bSJouni Högander struct drm_i915_private *i915 = to_i915(plane->base.dev);
1487b1f5279bSJouni Högander enum pipe pipe = plane->pipe;
1488b1f5279bSJouni Högander
1489b1f5279bSJouni Högander if (!crtc_state->enable_psr2_sel_fetch)
1490b1f5279bSJouni Högander return;
1491b1f5279bSJouni Högander
1492a4f477e6SJouni Högander if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0)
14930ff7639bSVille Syrjälä intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id),
14940ff7639bSVille Syrjälä SEL_FETCH_PLANE_CTL_ENABLE);
1495a4f477e6SJouni Högander else
1496a4f477e6SJouni Högander icl_plane_disable_sel_fetch_arm(plane, crtc_state);
1497f8a005ebSVille Syrjälä }
1498f8a005ebSVille Syrjälä
1499f8a005ebSVille 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)1500f8a005ebSVille Syrjälä icl_plane_update_arm(struct intel_plane *plane,
1501f8a005ebSVille Syrjälä const struct intel_crtc_state *crtc_state,
1502f8a005ebSVille Syrjälä const struct intel_plane_state *plane_state)
1503f8a005ebSVille Syrjälä {
1504f8a005ebSVille Syrjälä struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1505f8a005ebSVille Syrjälä enum plane_id plane_id = plane->id;
1506f8a005ebSVille Syrjälä enum pipe pipe = plane->pipe;
1507f8a005ebSVille Syrjälä int color_plane = icl_plane_color_plane(plane_state);
1508f8a005ebSVille Syrjälä u32 plane_ctl;
1509f8a005ebSVille Syrjälä
1510f8a005ebSVille Syrjälä plane_ctl = plane_state->ctl |
1511f8a005ebSVille Syrjälä skl_plane_ctl_crtc(crtc_state);
1512f8a005ebSVille Syrjälä
1513f8a005ebSVille Syrjälä /*
1514f8a005ebSVille Syrjälä * Enable the scaler before the plane so that we don't
1515f8a005ebSVille Syrjälä * get a catastrophic underrun even if the two operations
1516f8a005ebSVille Syrjälä * end up happening in two different frames.
1517f8a005ebSVille Syrjälä *
1518f8a005ebSVille Syrjälä * TODO: split into noarm+arm pair
1519f8a005ebSVille Syrjälä */
1520f8a005ebSVille Syrjälä if (plane_state->scaler_id >= 0)
1521f8a005ebSVille Syrjälä skl_program_plane_scaler(plane, crtc_state, plane_state);
1522f8a005ebSVille Syrjälä
1523b1f5279bSJouni Högander icl_plane_update_sel_fetch_arm(plane, crtc_state, plane_state);
1524c22cf04cSJouni Högander
1525f8a005ebSVille Syrjälä /*
1526f8a005ebSVille Syrjälä * The control register self-arms if the plane was previously
1527f8a005ebSVille Syrjälä * disabled. Try to make the plane enable atomic by writing
1528f8a005ebSVille Syrjälä * the control register just before the surface register.
1529f8a005ebSVille Syrjälä */
1530f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
1531f8a005ebSVille Syrjälä intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
153250faf7a1SVille Syrjälä skl_plane_surf(plane_state, color_plane));
153346d12f91SDave Airlie }
153446d12f91SDave Airlie
153546d12f91SDave 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)153646d12f91SDave Airlie skl_plane_async_flip(struct intel_plane *plane,
153746d12f91SDave Airlie const struct intel_crtc_state *crtc_state,
153846d12f91SDave Airlie const struct intel_plane_state *plane_state,
153946d12f91SDave Airlie bool async_flip)
154046d12f91SDave Airlie {
154146d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
154246d12f91SDave Airlie enum plane_id plane_id = plane->id;
154346d12f91SDave Airlie enum pipe pipe = plane->pipe;
154446d12f91SDave Airlie u32 plane_ctl = plane_state->ctl;
154546d12f91SDave Airlie
154646d12f91SDave Airlie plane_ctl |= skl_plane_ctl_crtc(crtc_state);
154746d12f91SDave Airlie
154846d12f91SDave Airlie if (async_flip)
154946d12f91SDave Airlie plane_ctl |= PLANE_CTL_ASYNC_FLIP;
155046d12f91SDave Airlie
155146d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
155246d12f91SDave Airlie intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
155350faf7a1SVille Syrjälä skl_plane_surf(plane_state, 0));
155446d12f91SDave Airlie }
155546d12f91SDave Airlie
intel_format_is_p01x(u32 format)155646d12f91SDave Airlie static bool intel_format_is_p01x(u32 format)
155746d12f91SDave Airlie {
155846d12f91SDave Airlie switch (format) {
155946d12f91SDave Airlie case DRM_FORMAT_P010:
156046d12f91SDave Airlie case DRM_FORMAT_P012:
156146d12f91SDave Airlie case DRM_FORMAT_P016:
156246d12f91SDave Airlie return true;
156346d12f91SDave Airlie default:
156446d12f91SDave Airlie return false;
156546d12f91SDave Airlie }
156646d12f91SDave Airlie }
156746d12f91SDave Airlie
skl_plane_check_fb(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)156846d12f91SDave Airlie static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
156946d12f91SDave Airlie const struct intel_plane_state *plane_state)
157046d12f91SDave Airlie {
157146d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
157246d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
157346d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
157446d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
157546d12f91SDave Airlie
157646d12f91SDave Airlie if (!fb)
157746d12f91SDave Airlie return 0;
157846d12f91SDave Airlie
157946d12f91SDave Airlie if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1580e359c47bSImre Deak intel_fb_is_ccs_modifier(fb->modifier)) {
158146d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
158246d12f91SDave Airlie "RC support only with 0/180 degree rotation (%x)\n",
158346d12f91SDave Airlie rotation);
158446d12f91SDave Airlie return -EINVAL;
158546d12f91SDave Airlie }
158646d12f91SDave Airlie
158746d12f91SDave Airlie if (rotation & DRM_MODE_REFLECT_X &&
158846d12f91SDave Airlie fb->modifier == DRM_FORMAT_MOD_LINEAR) {
158946d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
159046d12f91SDave Airlie "horizontal flip is not supported with linear surface formats\n");
159146d12f91SDave Airlie return -EINVAL;
159246d12f91SDave Airlie }
159346d12f91SDave Airlie
1594*ffafd126SJuha-Pekka Heikkila /*
1595*ffafd126SJuha-Pekka Heikkila * Display20 onward tile4 hflip is not supported
1596*ffafd126SJuha-Pekka Heikkila */
1597*ffafd126SJuha-Pekka Heikkila if (rotation & DRM_MODE_REFLECT_X &&
1598*ffafd126SJuha-Pekka Heikkila intel_fb_is_tile4_modifier(fb->modifier) &&
1599*ffafd126SJuha-Pekka Heikkila DISPLAY_VER(dev_priv) >= 20) {
1600*ffafd126SJuha-Pekka Heikkila drm_dbg_kms(&dev_priv->drm,
1601*ffafd126SJuha-Pekka Heikkila "horizontal flip is not supported with tile4 surface formats\n");
1602*ffafd126SJuha-Pekka Heikkila return -EINVAL;
1603*ffafd126SJuha-Pekka Heikkila }
1604*ffafd126SJuha-Pekka Heikkila
160546d12f91SDave Airlie if (drm_rotation_90_or_270(rotation)) {
1606d3b4aa43SImre Deak if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) {
160746d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
160846d12f91SDave Airlie "Y/Yf tiling required for 90/270!\n");
160946d12f91SDave Airlie return -EINVAL;
161046d12f91SDave Airlie }
161146d12f91SDave Airlie
161246d12f91SDave Airlie /*
161346d12f91SDave Airlie * 90/270 is not allowed with RGB64 16:16:16:16 and
161446d12f91SDave Airlie * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
161546d12f91SDave Airlie */
161646d12f91SDave Airlie switch (fb->format->format) {
161746d12f91SDave Airlie case DRM_FORMAT_RGB565:
1618005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11)
161946d12f91SDave Airlie break;
162046d12f91SDave Airlie fallthrough;
162146d12f91SDave Airlie case DRM_FORMAT_C8:
162246d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
162346d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
162446d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
162546d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
162646d12f91SDave Airlie case DRM_FORMAT_Y210:
162746d12f91SDave Airlie case DRM_FORMAT_Y212:
162846d12f91SDave Airlie case DRM_FORMAT_Y216:
162946d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
163046d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
163146d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
1632e3c2f187SStephen Rothwell "Unsupported pixel format %p4cc for 90/270!\n",
1633e3c2f187SStephen Rothwell &fb->format->format);
163446d12f91SDave Airlie return -EINVAL;
163546d12f91SDave Airlie default:
163646d12f91SDave Airlie break;
163746d12f91SDave Airlie }
163846d12f91SDave Airlie }
163946d12f91SDave Airlie
164046d12f91SDave Airlie /* Y-tiling is not supported in IF-ID Interlace mode */
164146d12f91SDave Airlie if (crtc_state->hw.enable &&
164246d12f91SDave Airlie crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1643d89357deSImre Deak fb->modifier != DRM_FORMAT_MOD_LINEAR &&
1644d89357deSImre Deak fb->modifier != I915_FORMAT_MOD_X_TILED) {
164546d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
164646d12f91SDave Airlie "Y/Yf tiling not supported in IF-ID mode\n");
164746d12f91SDave Airlie return -EINVAL;
164846d12f91SDave Airlie }
164946d12f91SDave Airlie
165046d12f91SDave Airlie /* Wa_1606054188:tgl,adl-s */
165146d12f91SDave Airlie if ((IS_ALDERLAKE_S(dev_priv) || IS_TIGERLAKE(dev_priv)) &&
165246d12f91SDave Airlie plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE &&
165346d12f91SDave Airlie intel_format_is_p01x(fb->format->format)) {
165446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
165546d12f91SDave Airlie "Source color keying not supported with P01x formats\n");
165646d12f91SDave Airlie return -EINVAL;
165746d12f91SDave Airlie }
165846d12f91SDave Airlie
165946d12f91SDave Airlie return 0;
166046d12f91SDave Airlie }
166146d12f91SDave Airlie
skl_plane_check_dst_coordinates(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)166246d12f91SDave Airlie static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
166346d12f91SDave Airlie const struct intel_plane_state *plane_state)
166446d12f91SDave Airlie {
166546d12f91SDave Airlie struct drm_i915_private *dev_priv =
166646d12f91SDave Airlie to_i915(plane_state->uapi.plane->dev);
166746d12f91SDave Airlie int crtc_x = plane_state->uapi.dst.x1;
166846d12f91SDave Airlie int crtc_w = drm_rect_width(&plane_state->uapi.dst);
166926111a16SVille Syrjälä int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
167046d12f91SDave Airlie
167146d12f91SDave Airlie /*
1672244dba4cSLucas De Marchi * Display WA #1175: glk
167346d12f91SDave Airlie * Planes other than the cursor may cause FIFO underflow and display
167446d12f91SDave Airlie * corruption if starting less than 4 pixels from the right edge of
167546d12f91SDave Airlie * the screen.
167646d12f91SDave Airlie * Besides the above WA fix the similar problem, where planes other
167746d12f91SDave Airlie * than the cursor ending less than 4 pixels from the left edge of the
167846d12f91SDave Airlie * screen may cause FIFO underflow and display corruption.
167946d12f91SDave Airlie */
168093e7e61eSLucas De Marchi if (DISPLAY_VER(dev_priv) == 10 &&
168146d12f91SDave Airlie (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
168246d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
168346d12f91SDave Airlie "requested plane X %s position %d invalid (valid range %d-%d)\n",
168446d12f91SDave Airlie crtc_x + crtc_w < 4 ? "end" : "start",
168546d12f91SDave Airlie crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
168646d12f91SDave Airlie 4, pipe_src_w - 4);
168746d12f91SDave Airlie return -ERANGE;
168846d12f91SDave Airlie }
168946d12f91SDave Airlie
169046d12f91SDave Airlie return 0;
169146d12f91SDave Airlie }
169246d12f91SDave Airlie
skl_plane_check_nv12_rotation(const struct intel_plane_state * plane_state)169346d12f91SDave Airlie static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
169446d12f91SDave Airlie {
16955acbdcd1SJani Nikula struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
169646d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
169746d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
169846d12f91SDave Airlie int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
169946d12f91SDave Airlie
170046d12f91SDave Airlie /* Display WA #1106 */
170146d12f91SDave Airlie if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
170246d12f91SDave Airlie src_w & 3 &&
170346d12f91SDave Airlie (rotation == DRM_MODE_ROTATE_270 ||
170446d12f91SDave Airlie rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
17055acbdcd1SJani Nikula drm_dbg_kms(&i915->drm, "src width must be multiple of 4 for rotated planar YUV\n");
170646d12f91SDave Airlie return -EINVAL;
170746d12f91SDave Airlie }
170846d12f91SDave Airlie
170946d12f91SDave Airlie return 0;
171046d12f91SDave Airlie }
171146d12f91SDave Airlie
skl_plane_max_scale(struct drm_i915_private * dev_priv,const struct drm_framebuffer * fb)171246d12f91SDave Airlie static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
171346d12f91SDave Airlie const struct drm_framebuffer *fb)
171446d12f91SDave Airlie {
171546d12f91SDave Airlie /*
171646d12f91SDave Airlie * We don't yet know the final source width nor
171746d12f91SDave Airlie * whether we can use the HQ scaler mode. Assume
171846d12f91SDave Airlie * the best case.
171946d12f91SDave Airlie * FIXME need to properly check this later.
172046d12f91SDave Airlie */
17212b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10 ||
172246d12f91SDave Airlie !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
172346d12f91SDave Airlie return 0x30000 - 1;
172446d12f91SDave Airlie else
172546d12f91SDave Airlie return 0x20000 - 1;
172646d12f91SDave Airlie }
172746d12f91SDave Airlie
intel_plane_min_width(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)172846d12f91SDave Airlie static int intel_plane_min_width(struct intel_plane *plane,
172946d12f91SDave Airlie const struct drm_framebuffer *fb,
173046d12f91SDave Airlie int color_plane,
173146d12f91SDave Airlie unsigned int rotation)
173246d12f91SDave Airlie {
173346d12f91SDave Airlie if (plane->min_width)
173446d12f91SDave Airlie return plane->min_width(fb, color_plane, rotation);
173546d12f91SDave Airlie else
173646d12f91SDave Airlie return 1;
173746d12f91SDave Airlie }
173846d12f91SDave Airlie
intel_plane_max_width(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)173946d12f91SDave Airlie static int intel_plane_max_width(struct intel_plane *plane,
174046d12f91SDave Airlie const struct drm_framebuffer *fb,
174146d12f91SDave Airlie int color_plane,
174246d12f91SDave Airlie unsigned int rotation)
174346d12f91SDave Airlie {
174446d12f91SDave Airlie if (plane->max_width)
174546d12f91SDave Airlie return plane->max_width(fb, color_plane, rotation);
174646d12f91SDave Airlie else
174746d12f91SDave Airlie return INT_MAX;
174846d12f91SDave Airlie }
174946d12f91SDave Airlie
intel_plane_max_height(struct intel_plane * plane,const struct drm_framebuffer * fb,int color_plane,unsigned int rotation)175046d12f91SDave Airlie static int intel_plane_max_height(struct intel_plane *plane,
175146d12f91SDave Airlie const struct drm_framebuffer *fb,
175246d12f91SDave Airlie int color_plane,
175346d12f91SDave Airlie unsigned int rotation)
175446d12f91SDave Airlie {
175546d12f91SDave Airlie if (plane->max_height)
175646d12f91SDave Airlie return plane->max_height(fb, color_plane, rotation);
175746d12f91SDave Airlie else
175846d12f91SDave Airlie return INT_MAX;
175946d12f91SDave Airlie }
176046d12f91SDave Airlie
176146d12f91SDave 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)176246d12f91SDave Airlie skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
176346d12f91SDave Airlie int main_x, int main_y, u32 main_offset,
176446d12f91SDave Airlie int ccs_plane)
176546d12f91SDave Airlie {
1766195b7a0dSVille Syrjälä struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
176746d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
176861169987SImre Deak int aux_x = plane_state->view.color_plane[ccs_plane].x;
176961169987SImre Deak int aux_y = plane_state->view.color_plane[ccs_plane].y;
177061169987SImre Deak u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
1771195b7a0dSVille Syrjälä unsigned int alignment = plane->min_alignment(plane, fb, ccs_plane);
177246d12f91SDave Airlie int hsub;
177346d12f91SDave Airlie int vsub;
177446d12f91SDave Airlie
177546d12f91SDave Airlie intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
177646d12f91SDave Airlie while (aux_offset >= main_offset && aux_y <= main_y) {
177746d12f91SDave Airlie int x, y;
177846d12f91SDave Airlie
177946d12f91SDave Airlie if (aux_x == main_x && aux_y == main_y)
178046d12f91SDave Airlie break;
178146d12f91SDave Airlie
178246d12f91SDave Airlie if (aux_offset == 0)
178346d12f91SDave Airlie break;
178446d12f91SDave Airlie
178546d12f91SDave Airlie x = aux_x / hsub;
178646d12f91SDave Airlie y = aux_y / vsub;
178746d12f91SDave Airlie aux_offset = intel_plane_adjust_aligned_offset(&x, &y,
178846d12f91SDave Airlie plane_state,
178946d12f91SDave Airlie ccs_plane,
179046d12f91SDave Airlie aux_offset,
179156ac367dSVille Syrjälä aux_offset - alignment);
179246d12f91SDave Airlie aux_x = x * hsub + aux_x % hsub;
179346d12f91SDave Airlie aux_y = y * vsub + aux_y % vsub;
179446d12f91SDave Airlie }
179546d12f91SDave Airlie
179646d12f91SDave Airlie if (aux_x != main_x || aux_y != main_y)
179746d12f91SDave Airlie return false;
179846d12f91SDave Airlie
179961169987SImre Deak plane_state->view.color_plane[ccs_plane].offset = aux_offset;
180061169987SImre Deak plane_state->view.color_plane[ccs_plane].x = aux_x;
180161169987SImre Deak plane_state->view.color_plane[ccs_plane].y = aux_y;
180246d12f91SDave Airlie
180346d12f91SDave Airlie return true;
180446d12f91SDave Airlie }
180546d12f91SDave Airlie
180646d12f91SDave Airlie
skl_calc_main_surface_offset(const struct intel_plane_state * plane_state,int * x,int * y,u32 * offset)180746d12f91SDave Airlie int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
180846d12f91SDave Airlie int *x, int *y, u32 *offset)
180946d12f91SDave Airlie {
181046d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
181146d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
181246d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
181356ac367dSVille Syrjälä int aux_plane = skl_main_to_aux_plane(fb, 0);
181456ac367dSVille Syrjälä u32 aux_offset = plane_state->view.color_plane[aux_plane].offset;
1815195b7a0dSVille Syrjälä unsigned int alignment = plane->min_alignment(plane, fb, 0);
181656ac367dSVille Syrjälä int w = drm_rect_width(&plane_state->uapi.src) >> 16;
181746d12f91SDave Airlie
181846d12f91SDave Airlie intel_add_fb_offsets(x, y, plane_state, 0);
181946d12f91SDave Airlie *offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0);
182046d12f91SDave Airlie if (drm_WARN_ON(&dev_priv->drm, alignment && !is_power_of_2(alignment)))
182146d12f91SDave Airlie return -EINVAL;
182246d12f91SDave Airlie
182346d12f91SDave Airlie /*
182446d12f91SDave Airlie * AUX surface offset is specified as the distance from the
182546d12f91SDave Airlie * main surface offset, and it must be non-negative. Make
182646d12f91SDave Airlie * sure that is what we will get.
182746d12f91SDave Airlie */
182846d12f91SDave Airlie if (aux_plane && *offset > aux_offset)
182946d12f91SDave Airlie *offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
183046d12f91SDave Airlie *offset,
183146d12f91SDave Airlie aux_offset & ~(alignment - 1));
183246d12f91SDave Airlie
183346d12f91SDave Airlie /*
183446d12f91SDave Airlie * When using an X-tiled surface, the plane blows up
183546d12f91SDave Airlie * if the x offset + width exceed the stride.
183646d12f91SDave Airlie *
183746d12f91SDave Airlie * TODO: linear and Y-tiled seem fine, Yf untested,
183846d12f91SDave Airlie */
183946d12f91SDave Airlie if (fb->modifier == I915_FORMAT_MOD_X_TILED) {
184046d12f91SDave Airlie int cpp = fb->format->cpp[0];
184146d12f91SDave Airlie
1842be6c1dd5SImre Deak while ((*x + w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
184346d12f91SDave Airlie if (*offset == 0) {
184446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
184546d12f91SDave Airlie "Unable to find suitable display surface offset due to X-tiling\n");
184646d12f91SDave Airlie return -EINVAL;
184746d12f91SDave Airlie }
184846d12f91SDave Airlie
184946d12f91SDave Airlie *offset = intel_plane_adjust_aligned_offset(x, y, plane_state, 0,
185046d12f91SDave Airlie *offset,
185146d12f91SDave Airlie *offset - alignment);
185246d12f91SDave Airlie }
185346d12f91SDave Airlie }
185446d12f91SDave Airlie
185546d12f91SDave Airlie return 0;
185646d12f91SDave Airlie }
185746d12f91SDave Airlie
skl_check_main_surface(struct intel_plane_state * plane_state)185846d12f91SDave Airlie static int skl_check_main_surface(struct intel_plane_state *plane_state)
185946d12f91SDave Airlie {
186046d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
186146d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
186246d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
186356ac367dSVille Syrjälä unsigned int rotation = plane_state->hw.rotation;
186446d12f91SDave Airlie int x = plane_state->uapi.src.x1 >> 16;
186546d12f91SDave Airlie int y = plane_state->uapi.src.y1 >> 16;
186656ac367dSVille Syrjälä int w = drm_rect_width(&plane_state->uapi.src) >> 16;
186756ac367dSVille Syrjälä int h = drm_rect_height(&plane_state->uapi.src) >> 16;
186856ac367dSVille Syrjälä int min_width = intel_plane_min_width(plane, fb, 0, rotation);
186956ac367dSVille Syrjälä int max_width = intel_plane_max_width(plane, fb, 0, rotation);
187056ac367dSVille Syrjälä int max_height = intel_plane_max_height(plane, fb, 0, rotation);
1871195b7a0dSVille Syrjälä unsigned int alignment = plane->min_alignment(plane, fb, 0);
187256ac367dSVille Syrjälä int aux_plane = skl_main_to_aux_plane(fb, 0);
187346d12f91SDave Airlie u32 offset;
187446d12f91SDave Airlie int ret;
187546d12f91SDave Airlie
18760fe76b19SDrew Davenport if (w > max_width || w < min_width || h > max_height || h < 1) {
187746d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
187846d12f91SDave Airlie "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n",
187946d12f91SDave Airlie w, h, min_width, max_width, max_height);
188046d12f91SDave Airlie return -EINVAL;
188146d12f91SDave Airlie }
188246d12f91SDave Airlie
188346d12f91SDave Airlie ret = skl_calc_main_surface_offset(plane_state, &x, &y, &offset);
188446d12f91SDave Airlie if (ret)
188546d12f91SDave Airlie return ret;
188646d12f91SDave Airlie
188746d12f91SDave Airlie /*
188846d12f91SDave Airlie * CCS AUX surface doesn't have its own x/y offsets, we must make sure
1889680025dcSJuha-Pekka Heikkilä * they match with the main surface x/y offsets. On DG2
1890680025dcSJuha-Pekka Heikkilä * there's no aux plane on fb so skip this checking.
189146d12f91SDave Airlie */
1892680025dcSJuha-Pekka Heikkilä if (intel_fb_is_ccs_modifier(fb->modifier) && aux_plane) {
189346d12f91SDave Airlie while (!skl_check_main_ccs_coordinates(plane_state, x, y,
189446d12f91SDave Airlie offset, aux_plane)) {
189546d12f91SDave Airlie if (offset == 0)
189646d12f91SDave Airlie break;
189746d12f91SDave Airlie
189846d12f91SDave Airlie offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
189946d12f91SDave Airlie offset, offset - alignment);
190046d12f91SDave Airlie }
190146d12f91SDave Airlie
190261169987SImre Deak if (x != plane_state->view.color_plane[aux_plane].x ||
190361169987SImre Deak y != plane_state->view.color_plane[aux_plane].y) {
190446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
190546d12f91SDave Airlie "Unable to find suitable display surface offset due to CCS\n");
190646d12f91SDave Airlie return -EINVAL;
190746d12f91SDave Airlie }
190846d12f91SDave Airlie }
190946d12f91SDave Airlie
1910e7367af1SJuha-Pekka Heikkilä if (DISPLAY_VER(dev_priv) >= 13)
1911e7367af1SJuha-Pekka Heikkilä drm_WARN_ON(&dev_priv->drm, x > 65535 || y > 65535);
1912e7367af1SJuha-Pekka Heikkilä else
191346d12f91SDave Airlie drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191);
191446d12f91SDave Airlie
191561169987SImre Deak plane_state->view.color_plane[0].offset = offset;
191661169987SImre Deak plane_state->view.color_plane[0].x = x;
191761169987SImre Deak plane_state->view.color_plane[0].y = y;
191846d12f91SDave Airlie
191946d12f91SDave Airlie /*
192046d12f91SDave Airlie * Put the final coordinates back so that the src
192146d12f91SDave Airlie * coordinate checks will see the right values.
192246d12f91SDave Airlie */
192346d12f91SDave Airlie drm_rect_translate_to(&plane_state->uapi.src,
192446d12f91SDave Airlie x << 16, y << 16);
192546d12f91SDave Airlie
192646d12f91SDave Airlie return 0;
192746d12f91SDave Airlie }
192846d12f91SDave Airlie
skl_check_nv12_aux_surface(struct intel_plane_state * plane_state)192946d12f91SDave Airlie static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
193046d12f91SDave Airlie {
193146d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
193246d12f91SDave Airlie struct drm_i915_private *i915 = to_i915(plane->base.dev);
193346d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
193446d12f91SDave Airlie unsigned int rotation = plane_state->hw.rotation;
193546d12f91SDave Airlie int uv_plane = 1;
1936680025dcSJuha-Pekka Heikkilä int ccs_plane = intel_fb_is_ccs_modifier(fb->modifier) ?
1937680025dcSJuha-Pekka Heikkilä skl_main_to_aux_plane(fb, uv_plane) : 0;
193846d12f91SDave Airlie int max_width = intel_plane_max_width(plane, fb, uv_plane, rotation);
193946d12f91SDave Airlie int max_height = intel_plane_max_height(plane, fb, uv_plane, rotation);
194046d12f91SDave Airlie int x = plane_state->uapi.src.x1 >> 17;
194146d12f91SDave Airlie int y = plane_state->uapi.src.y1 >> 17;
194246d12f91SDave Airlie int w = drm_rect_width(&plane_state->uapi.src) >> 17;
194346d12f91SDave Airlie int h = drm_rect_height(&plane_state->uapi.src) >> 17;
194446d12f91SDave Airlie u32 offset;
194546d12f91SDave Airlie
194646d12f91SDave Airlie /* FIXME not quite sure how/if these apply to the chroma plane */
194746d12f91SDave Airlie if (w > max_width || h > max_height) {
194846d12f91SDave Airlie drm_dbg_kms(&i915->drm,
194946d12f91SDave Airlie "CbCr source size %dx%d too big (limit %dx%d)\n",
195046d12f91SDave Airlie w, h, max_width, max_height);
195146d12f91SDave Airlie return -EINVAL;
195246d12f91SDave Airlie }
195346d12f91SDave Airlie
195446d12f91SDave Airlie intel_add_fb_offsets(&x, &y, plane_state, uv_plane);
195546d12f91SDave Airlie offset = intel_plane_compute_aligned_offset(&x, &y,
195646d12f91SDave Airlie plane_state, uv_plane);
195746d12f91SDave Airlie
1958680025dcSJuha-Pekka Heikkilä if (ccs_plane) {
195961169987SImre Deak u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
1960195b7a0dSVille Syrjälä unsigned int alignment = plane->min_alignment(plane, fb, uv_plane);
196146d12f91SDave Airlie
196246d12f91SDave Airlie if (offset > aux_offset)
196346d12f91SDave Airlie offset = intel_plane_adjust_aligned_offset(&x, &y,
196446d12f91SDave Airlie plane_state,
196546d12f91SDave Airlie uv_plane,
196646d12f91SDave Airlie offset,
196746d12f91SDave Airlie aux_offset & ~(alignment - 1));
196846d12f91SDave Airlie
196946d12f91SDave Airlie while (!skl_check_main_ccs_coordinates(plane_state, x, y,
197046d12f91SDave Airlie offset, ccs_plane)) {
197146d12f91SDave Airlie if (offset == 0)
197246d12f91SDave Airlie break;
197346d12f91SDave Airlie
197446d12f91SDave Airlie offset = intel_plane_adjust_aligned_offset(&x, &y,
197546d12f91SDave Airlie plane_state,
197646d12f91SDave Airlie uv_plane,
197746d12f91SDave Airlie offset, offset - alignment);
197846d12f91SDave Airlie }
197946d12f91SDave Airlie
198061169987SImre Deak if (x != plane_state->view.color_plane[ccs_plane].x ||
198161169987SImre Deak y != plane_state->view.color_plane[ccs_plane].y) {
198246d12f91SDave Airlie drm_dbg_kms(&i915->drm,
198346d12f91SDave Airlie "Unable to find suitable display surface offset due to CCS\n");
198446d12f91SDave Airlie return -EINVAL;
198546d12f91SDave Airlie }
198646d12f91SDave Airlie }
198746d12f91SDave Airlie
1988e7367af1SJuha-Pekka Heikkilä if (DISPLAY_VER(i915) >= 13)
1989e7367af1SJuha-Pekka Heikkilä drm_WARN_ON(&i915->drm, x > 65535 || y > 65535);
1990e7367af1SJuha-Pekka Heikkilä else
199146d12f91SDave Airlie drm_WARN_ON(&i915->drm, x > 8191 || y > 8191);
199246d12f91SDave Airlie
199361169987SImre Deak plane_state->view.color_plane[uv_plane].offset = offset;
199461169987SImre Deak plane_state->view.color_plane[uv_plane].x = x;
199561169987SImre Deak plane_state->view.color_plane[uv_plane].y = y;
199646d12f91SDave Airlie
199746d12f91SDave Airlie return 0;
199846d12f91SDave Airlie }
199946d12f91SDave Airlie
skl_check_ccs_aux_surface(struct intel_plane_state * plane_state)200046d12f91SDave Airlie static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
200146d12f91SDave Airlie {
200246d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
200346d12f91SDave Airlie int src_x = plane_state->uapi.src.x1 >> 16;
200446d12f91SDave Airlie int src_y = plane_state->uapi.src.y1 >> 16;
200546d12f91SDave Airlie u32 offset;
200646d12f91SDave Airlie int ccs_plane;
200746d12f91SDave Airlie
200846d12f91SDave Airlie for (ccs_plane = 0; ccs_plane < fb->format->num_planes; ccs_plane++) {
200946d12f91SDave Airlie int main_hsub, main_vsub;
201046d12f91SDave Airlie int hsub, vsub;
201146d12f91SDave Airlie int x, y;
201246d12f91SDave Airlie
2013f5042343SImre Deak if (!intel_fb_is_ccs_aux_plane(fb, ccs_plane))
201446d12f91SDave Airlie continue;
201546d12f91SDave Airlie
201646d12f91SDave Airlie intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, fb,
201746d12f91SDave Airlie skl_ccs_to_main_plane(fb, ccs_plane));
201846d12f91SDave Airlie intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane);
201946d12f91SDave Airlie
202046d12f91SDave Airlie hsub *= main_hsub;
202146d12f91SDave Airlie vsub *= main_vsub;
202246d12f91SDave Airlie x = src_x / hsub;
202346d12f91SDave Airlie y = src_y / vsub;
202446d12f91SDave Airlie
202546d12f91SDave Airlie intel_add_fb_offsets(&x, &y, plane_state, ccs_plane);
202646d12f91SDave Airlie
202746d12f91SDave Airlie offset = intel_plane_compute_aligned_offset(&x, &y,
202846d12f91SDave Airlie plane_state,
202946d12f91SDave Airlie ccs_plane);
203046d12f91SDave Airlie
203161169987SImre Deak plane_state->view.color_plane[ccs_plane].offset = offset;
203261169987SImre Deak plane_state->view.color_plane[ccs_plane].x = (x * hsub + src_x % hsub) / main_hsub;
203361169987SImre Deak plane_state->view.color_plane[ccs_plane].y = (y * vsub + src_y % vsub) / main_vsub;
203446d12f91SDave Airlie }
203546d12f91SDave Airlie
203646d12f91SDave Airlie return 0;
203746d12f91SDave Airlie }
203846d12f91SDave Airlie
skl_check_plane_surface(struct intel_plane_state * plane_state)203946d12f91SDave Airlie static int skl_check_plane_surface(struct intel_plane_state *plane_state)
204046d12f91SDave Airlie {
204146d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
2042ee456a4cSImre Deak int ret;
204346d12f91SDave Airlie
204446d12f91SDave Airlie ret = intel_plane_compute_gtt(plane_state);
204546d12f91SDave Airlie if (ret)
204646d12f91SDave Airlie return ret;
204746d12f91SDave Airlie
204846d12f91SDave Airlie if (!plane_state->uapi.visible)
204946d12f91SDave Airlie return 0;
205046d12f91SDave Airlie
205146d12f91SDave Airlie /*
205246d12f91SDave Airlie * Handle the AUX surface first since the main surface setup depends on
205346d12f91SDave Airlie * it.
205446d12f91SDave Airlie */
2055e359c47bSImre Deak if (intel_fb_is_ccs_modifier(fb->modifier)) {
205646d12f91SDave Airlie ret = skl_check_ccs_aux_surface(plane_state);
205746d12f91SDave Airlie if (ret)
205846d12f91SDave Airlie return ret;
205946d12f91SDave Airlie }
206046d12f91SDave Airlie
206146d12f91SDave Airlie if (intel_format_info_is_yuv_semiplanar(fb->format,
206246d12f91SDave Airlie fb->modifier)) {
206346d12f91SDave Airlie ret = skl_check_nv12_aux_surface(plane_state);
206446d12f91SDave Airlie if (ret)
206546d12f91SDave Airlie return ret;
206646d12f91SDave Airlie }
206746d12f91SDave Airlie
206846d12f91SDave Airlie ret = skl_check_main_surface(plane_state);
206946d12f91SDave Airlie if (ret)
207046d12f91SDave Airlie return ret;
207146d12f91SDave Airlie
207246d12f91SDave Airlie return 0;
207346d12f91SDave Airlie }
207446d12f91SDave Airlie
skl_fb_scalable(const struct drm_framebuffer * fb)207514cebc1fSDave Airlie static bool skl_fb_scalable(const struct drm_framebuffer *fb)
207646d12f91SDave Airlie {
207746d12f91SDave Airlie if (!fb)
207846d12f91SDave Airlie return false;
207946d12f91SDave Airlie
208046d12f91SDave Airlie switch (fb->format->format) {
208146d12f91SDave Airlie case DRM_FORMAT_C8:
208246d12f91SDave Airlie return false;
208346d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
208446d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
208546d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
208646d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
2087005e9537SMatt Roper return DISPLAY_VER(to_i915(fb->dev)) >= 11;
208846d12f91SDave Airlie default:
208946d12f91SDave Airlie return true;
209046d12f91SDave Airlie }
209146d12f91SDave Airlie }
209246d12f91SDave Airlie
check_protection(struct intel_plane_state * plane_state)209388a6e46cSJani Nikula static void check_protection(struct intel_plane_state *plane_state)
209488a6e46cSJani Nikula {
209588a6e46cSJani Nikula struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
209688a6e46cSJani Nikula struct drm_i915_private *i915 = to_i915(plane->base.dev);
209788a6e46cSJani Nikula const struct drm_framebuffer *fb = plane_state->hw.fb;
20989b1c97fcSJani Nikula struct drm_i915_gem_object *obj = intel_fb_obj(fb);
209988a6e46cSJani Nikula
210088a6e46cSJani Nikula if (DISPLAY_VER(i915) < 11)
210188a6e46cSJani Nikula return;
210288a6e46cSJani Nikula
21039b1c97fcSJani Nikula plane_state->decrypt = intel_pxp_key_check(i915->pxp, obj, false) == 0;
21049b1c97fcSJani Nikula plane_state->force_black = i915_gem_object_is_protected(obj) &&
21059b1c97fcSJani Nikula !plane_state->decrypt;
210688a6e46cSJani Nikula }
210788a6e46cSJani Nikula
skl_plane_check(struct intel_crtc_state * crtc_state,struct intel_plane_state * plane_state)210846d12f91SDave Airlie static int skl_plane_check(struct intel_crtc_state *crtc_state,
210946d12f91SDave Airlie struct intel_plane_state *plane_state)
211046d12f91SDave Airlie {
211146d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
211246d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
211346d12f91SDave Airlie const struct drm_framebuffer *fb = plane_state->hw.fb;
2114cce32e4eSThomas Zimmermann int min_scale = DRM_PLANE_NO_SCALING;
2115cce32e4eSThomas Zimmermann int max_scale = DRM_PLANE_NO_SCALING;
211646d12f91SDave Airlie int ret;
211746d12f91SDave Airlie
211846d12f91SDave Airlie ret = skl_plane_check_fb(crtc_state, plane_state);
211946d12f91SDave Airlie if (ret)
212046d12f91SDave Airlie return ret;
212146d12f91SDave Airlie
212246d12f91SDave Airlie /* use scaler when colorkey is not required */
212314cebc1fSDave Airlie if (!plane_state->ckey.flags && skl_fb_scalable(fb)) {
212446d12f91SDave Airlie min_scale = 1;
212546d12f91SDave Airlie max_scale = skl_plane_max_scale(dev_priv, fb);
212646d12f91SDave Airlie }
212746d12f91SDave Airlie
212846d12f91SDave Airlie ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
212946d12f91SDave Airlie min_scale, max_scale, true);
213046d12f91SDave Airlie if (ret)
213146d12f91SDave Airlie return ret;
213246d12f91SDave Airlie
213346d12f91SDave Airlie ret = skl_check_plane_surface(plane_state);
213446d12f91SDave Airlie if (ret)
213546d12f91SDave Airlie return ret;
213646d12f91SDave Airlie
213746d12f91SDave Airlie if (!plane_state->uapi.visible)
213846d12f91SDave Airlie return 0;
213946d12f91SDave Airlie
214046d12f91SDave Airlie ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
214146d12f91SDave Airlie if (ret)
214246d12f91SDave Airlie return ret;
214346d12f91SDave Airlie
214446d12f91SDave Airlie ret = intel_plane_check_src_coordinates(plane_state);
214546d12f91SDave Airlie if (ret)
214646d12f91SDave Airlie return ret;
214746d12f91SDave Airlie
214846d12f91SDave Airlie ret = skl_plane_check_nv12_rotation(plane_state);
214946d12f91SDave Airlie if (ret)
215046d12f91SDave Airlie return ret;
215146d12f91SDave Airlie
215288a6e46cSJani Nikula check_protection(plane_state);
2153f9a7b19cSVille Syrjälä
215446d12f91SDave Airlie /* HW only has 8 bits pixel precision, disable plane if invisible */
215546d12f91SDave Airlie if (!(plane_state->hw.alpha >> 8))
215646d12f91SDave Airlie plane_state->uapi.visible = false;
215746d12f91SDave Airlie
215846d12f91SDave Airlie plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
215946d12f91SDave Airlie
21602b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10)
216146d12f91SDave Airlie plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
216246d12f91SDave Airlie plane_state);
216346d12f91SDave Airlie
216446d12f91SDave Airlie if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
216546d12f91SDave Airlie icl_is_hdr_plane(dev_priv, plane->id))
216646d12f91SDave Airlie /* Enable and use MPEG-2 chroma siting */
216746d12f91SDave Airlie plane_state->cus_ctl = PLANE_CUS_ENABLE |
216846d12f91SDave Airlie PLANE_CUS_HPHASE_0 |
216946d12f91SDave Airlie PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
217046d12f91SDave Airlie else
217146d12f91SDave Airlie plane_state->cus_ctl = 0;
217246d12f91SDave Airlie
217346d12f91SDave Airlie return 0;
217446d12f91SDave Airlie }
217546d12f91SDave Airlie
skl_fbc_id_for_pipe(enum pipe pipe)2176b8ca477eSVille Syrjälä static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
217746d12f91SDave Airlie {
2178b8ca477eSVille Syrjälä return pipe - PIPE_A + INTEL_FBC_A;
2179b8ca477eSVille Syrjälä }
2180b8ca477eSVille Syrjälä
skl_plane_has_fbc(struct drm_i915_private * i915,enum intel_fbc_id fbc_id,enum plane_id plane_id)2181de1ee4e4SVinod Govindapillai static bool skl_plane_has_fbc(struct drm_i915_private *i915,
2182b8ca477eSVille Syrjälä enum intel_fbc_id fbc_id, enum plane_id plane_id)
2183b8ca477eSVille Syrjälä {
2184de1ee4e4SVinod Govindapillai if ((DISPLAY_RUNTIME_INFO(i915)->fbc_mask & BIT(fbc_id)) == 0)
218546d12f91SDave Airlie return false;
218646d12f91SDave Airlie
2187de1ee4e4SVinod Govindapillai if (DISPLAY_VER(i915) >= 20)
2188de1ee4e4SVinod Govindapillai return icl_is_hdr_plane(i915, plane_id);
2189de1ee4e4SVinod Govindapillai else
2190df798d43SVille Syrjälä return plane_id == PLANE_1;
219146d12f91SDave Airlie }
219246d12f91SDave Airlie
skl_plane_fbc(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)2193825bd833SVille Syrjälä static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
2194825bd833SVille Syrjälä enum pipe pipe, enum plane_id plane_id)
2195825bd833SVille Syrjälä {
2196b8ca477eSVille Syrjälä enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe);
2197b8ca477eSVille Syrjälä
2198b8ca477eSVille Syrjälä if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id))
219980b3842fSJani Nikula return dev_priv->display.fbc[fbc_id];
2200825bd833SVille Syrjälä else
2201825bd833SVille Syrjälä return NULL;
2202825bd833SVille Syrjälä }
2203825bd833SVille Syrjälä
skl_plane_has_planar(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)220446d12f91SDave Airlie static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
220546d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id)
220646d12f91SDave Airlie {
220746d12f91SDave Airlie /* Display WA #0870: skl, bxt */
220846d12f91SDave Airlie if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
220946d12f91SDave Airlie return false;
221046d12f91SDave Airlie
221193e7e61eSLucas De Marchi if (DISPLAY_VER(dev_priv) == 9 && pipe == PIPE_C)
221246d12f91SDave Airlie return false;
221346d12f91SDave Airlie
2214df798d43SVille Syrjälä if (plane_id != PLANE_1 && plane_id != PLANE_2)
221546d12f91SDave Airlie return false;
221646d12f91SDave Airlie
221746d12f91SDave Airlie return true;
221846d12f91SDave Airlie }
221946d12f91SDave Airlie
skl_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)222046d12f91SDave Airlie static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
222146d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id,
222246d12f91SDave Airlie int *num_formats)
222346d12f91SDave Airlie {
222446d12f91SDave Airlie if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
222546d12f91SDave Airlie *num_formats = ARRAY_SIZE(skl_planar_formats);
222646d12f91SDave Airlie return skl_planar_formats;
222746d12f91SDave Airlie } else {
222846d12f91SDave Airlie *num_formats = ARRAY_SIZE(skl_plane_formats);
222946d12f91SDave Airlie return skl_plane_formats;
223046d12f91SDave Airlie }
223146d12f91SDave Airlie }
223246d12f91SDave Airlie
glk_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)223346d12f91SDave Airlie static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
223446d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id,
223546d12f91SDave Airlie int *num_formats)
223646d12f91SDave Airlie {
223746d12f91SDave Airlie if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
223846d12f91SDave Airlie *num_formats = ARRAY_SIZE(glk_planar_formats);
223946d12f91SDave Airlie return glk_planar_formats;
224046d12f91SDave Airlie } else {
224146d12f91SDave Airlie *num_formats = ARRAY_SIZE(skl_plane_formats);
224246d12f91SDave Airlie return skl_plane_formats;
224346d12f91SDave Airlie }
224446d12f91SDave Airlie }
224546d12f91SDave Airlie
icl_get_plane_formats(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id,int * num_formats)224646d12f91SDave Airlie static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
224746d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id,
224846d12f91SDave Airlie int *num_formats)
224946d12f91SDave Airlie {
225046d12f91SDave Airlie if (icl_is_hdr_plane(dev_priv, plane_id)) {
225146d12f91SDave Airlie *num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
225246d12f91SDave Airlie return icl_hdr_plane_formats;
225346d12f91SDave Airlie } else if (icl_is_nv12_y_plane(dev_priv, plane_id)) {
225446d12f91SDave Airlie *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
225546d12f91SDave Airlie return icl_sdr_y_plane_formats;
225646d12f91SDave Airlie } else {
225746d12f91SDave Airlie *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
225846d12f91SDave Airlie return icl_sdr_uv_plane_formats;
225946d12f91SDave Airlie }
226046d12f91SDave Airlie }
226146d12f91SDave Airlie
skl_plane_format_mod_supported(struct drm_plane * _plane,u32 format,u64 modifier)226246d12f91SDave Airlie static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
226346d12f91SDave Airlie u32 format, u64 modifier)
226446d12f91SDave Airlie {
226546d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(_plane);
226646d12f91SDave Airlie
2267e2b83294SImre Deak if (!intel_fb_plane_supports_modifier(plane, modifier))
226846d12f91SDave Airlie return false;
226946d12f91SDave Airlie
227046d12f91SDave Airlie switch (format) {
227146d12f91SDave Airlie case DRM_FORMAT_XRGB8888:
227246d12f91SDave Airlie case DRM_FORMAT_XBGR8888:
227346d12f91SDave Airlie case DRM_FORMAT_ARGB8888:
227446d12f91SDave Airlie case DRM_FORMAT_ABGR8888:
2275e359c47bSImre Deak if (intel_fb_is_ccs_modifier(modifier))
227646d12f91SDave Airlie return true;
227746d12f91SDave Airlie fallthrough;
227846d12f91SDave Airlie case DRM_FORMAT_RGB565:
227946d12f91SDave Airlie case DRM_FORMAT_XRGB2101010:
228046d12f91SDave Airlie case DRM_FORMAT_XBGR2101010:
228146d12f91SDave Airlie case DRM_FORMAT_ARGB2101010:
228246d12f91SDave Airlie case DRM_FORMAT_ABGR2101010:
228346d12f91SDave Airlie case DRM_FORMAT_YUYV:
228446d12f91SDave Airlie case DRM_FORMAT_YVYU:
228546d12f91SDave Airlie case DRM_FORMAT_UYVY:
228646d12f91SDave Airlie case DRM_FORMAT_VYUY:
228746d12f91SDave Airlie case DRM_FORMAT_NV12:
228846d12f91SDave Airlie case DRM_FORMAT_XYUV8888:
228946d12f91SDave Airlie case DRM_FORMAT_P010:
229046d12f91SDave Airlie case DRM_FORMAT_P012:
229146d12f91SDave Airlie case DRM_FORMAT_P016:
229246d12f91SDave Airlie case DRM_FORMAT_XVYU2101010:
229346d12f91SDave Airlie if (modifier == I915_FORMAT_MOD_Yf_TILED)
229446d12f91SDave Airlie return true;
229546d12f91SDave Airlie fallthrough;
229646d12f91SDave Airlie case DRM_FORMAT_C8:
229746d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
229846d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
229946d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
230046d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
230146d12f91SDave Airlie case DRM_FORMAT_Y210:
230246d12f91SDave Airlie case DRM_FORMAT_Y212:
230346d12f91SDave Airlie case DRM_FORMAT_Y216:
230446d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
230546d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
230646d12f91SDave Airlie if (modifier == DRM_FORMAT_MOD_LINEAR ||
230746d12f91SDave Airlie modifier == I915_FORMAT_MOD_X_TILED ||
230846d12f91SDave Airlie modifier == I915_FORMAT_MOD_Y_TILED)
230946d12f91SDave Airlie return true;
231046d12f91SDave Airlie fallthrough;
231146d12f91SDave Airlie default:
231246d12f91SDave Airlie return false;
231346d12f91SDave Airlie }
231446d12f91SDave Airlie }
231546d12f91SDave Airlie
gen12_plane_format_mod_supported(struct drm_plane * _plane,u32 format,u64 modifier)231646d12f91SDave Airlie static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
231746d12f91SDave Airlie u32 format, u64 modifier)
231846d12f91SDave Airlie {
231946d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(_plane);
232046d12f91SDave Airlie
2321e2b83294SImre Deak if (!intel_fb_plane_supports_modifier(plane, modifier))
232246d12f91SDave Airlie return false;
232346d12f91SDave Airlie
232446d12f91SDave Airlie switch (format) {
232546d12f91SDave Airlie case DRM_FORMAT_XRGB8888:
232646d12f91SDave Airlie case DRM_FORMAT_XBGR8888:
232746d12f91SDave Airlie case DRM_FORMAT_ARGB8888:
232846d12f91SDave Airlie case DRM_FORMAT_ABGR8888:
2329e359c47bSImre Deak if (intel_fb_is_ccs_modifier(modifier))
233046d12f91SDave Airlie return true;
233146d12f91SDave Airlie fallthrough;
233246d12f91SDave Airlie case DRM_FORMAT_YUYV:
233346d12f91SDave Airlie case DRM_FORMAT_YVYU:
233446d12f91SDave Airlie case DRM_FORMAT_UYVY:
233546d12f91SDave Airlie case DRM_FORMAT_VYUY:
233646d12f91SDave Airlie case DRM_FORMAT_NV12:
233746d12f91SDave Airlie case DRM_FORMAT_XYUV8888:
233846d12f91SDave Airlie case DRM_FORMAT_P010:
233946d12f91SDave Airlie case DRM_FORMAT_P012:
234046d12f91SDave Airlie case DRM_FORMAT_P016:
23410b2c31ddSImre Deak if (intel_fb_is_mc_ccs_modifier(modifier))
234246d12f91SDave Airlie return true;
234346d12f91SDave Airlie fallthrough;
234446d12f91SDave Airlie case DRM_FORMAT_RGB565:
234546d12f91SDave Airlie case DRM_FORMAT_XRGB2101010:
234646d12f91SDave Airlie case DRM_FORMAT_XBGR2101010:
234746d12f91SDave Airlie case DRM_FORMAT_ARGB2101010:
234846d12f91SDave Airlie case DRM_FORMAT_ABGR2101010:
234946d12f91SDave Airlie case DRM_FORMAT_XVYU2101010:
235046d12f91SDave Airlie case DRM_FORMAT_C8:
235146d12f91SDave Airlie case DRM_FORMAT_XBGR16161616F:
235246d12f91SDave Airlie case DRM_FORMAT_ABGR16161616F:
235346d12f91SDave Airlie case DRM_FORMAT_XRGB16161616F:
235446d12f91SDave Airlie case DRM_FORMAT_ARGB16161616F:
235546d12f91SDave Airlie case DRM_FORMAT_Y210:
235646d12f91SDave Airlie case DRM_FORMAT_Y212:
235746d12f91SDave Airlie case DRM_FORMAT_Y216:
235846d12f91SDave Airlie case DRM_FORMAT_XVYU12_16161616:
235946d12f91SDave Airlie case DRM_FORMAT_XVYU16161616:
2360072ce416SStanislav Lisovskiy if (!intel_fb_is_ccs_modifier(modifier))
236146d12f91SDave Airlie return true;
236246d12f91SDave Airlie fallthrough;
236346d12f91SDave Airlie default:
236446d12f91SDave Airlie return false;
236546d12f91SDave Airlie }
236646d12f91SDave Airlie }
236746d12f91SDave Airlie
236846d12f91SDave Airlie static const struct drm_plane_funcs skl_plane_funcs = {
236946d12f91SDave Airlie .update_plane = drm_atomic_helper_update_plane,
237046d12f91SDave Airlie .disable_plane = drm_atomic_helper_disable_plane,
237146d12f91SDave Airlie .destroy = intel_plane_destroy,
237246d12f91SDave Airlie .atomic_duplicate_state = intel_plane_duplicate_state,
237346d12f91SDave Airlie .atomic_destroy_state = intel_plane_destroy_state,
237446d12f91SDave Airlie .format_mod_supported = skl_plane_format_mod_supported,
237546d12f91SDave Airlie };
237646d12f91SDave Airlie
237746d12f91SDave Airlie static const struct drm_plane_funcs gen12_plane_funcs = {
237846d12f91SDave Airlie .update_plane = drm_atomic_helper_update_plane,
237946d12f91SDave Airlie .disable_plane = drm_atomic_helper_disable_plane,
238046d12f91SDave Airlie .destroy = intel_plane_destroy,
238146d12f91SDave Airlie .atomic_duplicate_state = intel_plane_duplicate_state,
238246d12f91SDave Airlie .atomic_destroy_state = intel_plane_destroy_state,
238346d12f91SDave Airlie .format_mod_supported = gen12_plane_format_mod_supported,
238446d12f91SDave Airlie };
238546d12f91SDave Airlie
238646d12f91SDave Airlie static void
skl_plane_enable_flip_done(struct intel_plane * plane)238746d12f91SDave Airlie skl_plane_enable_flip_done(struct intel_plane *plane)
238846d12f91SDave Airlie {
238946d12f91SDave Airlie struct drm_i915_private *i915 = to_i915(plane->base.dev);
239046d12f91SDave Airlie enum pipe pipe = plane->pipe;
239146d12f91SDave Airlie
239246d12f91SDave Airlie spin_lock_irq(&i915->irq_lock);
239346d12f91SDave Airlie bdw_enable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
239446d12f91SDave Airlie spin_unlock_irq(&i915->irq_lock);
239546d12f91SDave Airlie }
239646d12f91SDave Airlie
239746d12f91SDave Airlie static void
skl_plane_disable_flip_done(struct intel_plane * plane)239846d12f91SDave Airlie skl_plane_disable_flip_done(struct intel_plane *plane)
239946d12f91SDave Airlie {
240046d12f91SDave Airlie struct drm_i915_private *i915 = to_i915(plane->base.dev);
240146d12f91SDave Airlie enum pipe pipe = plane->pipe;
240246d12f91SDave Airlie
240346d12f91SDave Airlie spin_lock_irq(&i915->irq_lock);
240446d12f91SDave Airlie bdw_disable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
240546d12f91SDave Airlie spin_unlock_irq(&i915->irq_lock);
240646d12f91SDave Airlie }
240746d12f91SDave Airlie
skl_plane_has_rc_ccs(struct drm_i915_private * i915,enum pipe pipe,enum plane_id plane_id)2408e2b83294SImre Deak static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915,
2409e2b83294SImre Deak enum pipe pipe, enum plane_id plane_id)
2410e2b83294SImre Deak {
2411e2b83294SImre Deak /* Wa_22011186057 */
2412cc0c986aSDnyaneshwar Bhadane if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
2413e2b83294SImre Deak return false;
2414e2b83294SImre Deak
2415e2b83294SImre Deak if (DISPLAY_VER(i915) >= 11)
2416e2b83294SImre Deak return true;
2417e2b83294SImre Deak
2418e2b83294SImre Deak if (IS_GEMINILAKE(i915))
2419e2b83294SImre Deak return pipe != PIPE_C;
2420e2b83294SImre Deak
2421e2b83294SImre Deak return pipe != PIPE_C &&
2422df798d43SVille Syrjälä (plane_id == PLANE_1 || plane_id == PLANE_2);
2423e2b83294SImre Deak }
2424e2b83294SImre Deak
gen12_plane_has_mc_ccs(struct drm_i915_private * i915,enum plane_id plane_id)2425e2b83294SImre Deak static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915,
2426e2b83294SImre Deak enum plane_id plane_id)
2427e2b83294SImre Deak {
2428da0c3e2cSImre Deak if (DISPLAY_VER(i915) < 12)
2429da0c3e2cSImre Deak return false;
2430da0c3e2cSImre Deak
2431d1702963SMatt Roper /* Wa_14010477008 */
2432e2b83294SImre Deak if (IS_DG1(i915) || IS_ROCKETLAKE(i915) ||
243348077b0bSDnyaneshwar Bhadane (IS_TIGERLAKE(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_D0)))
2434e2b83294SImre Deak return false;
2435e2b83294SImre Deak
2436e2b83294SImre Deak /* Wa_22011186057 */
2437cc0c986aSDnyaneshwar Bhadane if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
2438e2b83294SImre Deak return false;
2439e2b83294SImre Deak
2440df798d43SVille Syrjälä return plane_id < PLANE_6;
2441e2b83294SImre Deak }
2442e2b83294SImre Deak
skl_get_plane_caps(struct drm_i915_private * i915,enum pipe pipe,enum plane_id plane_id)244310a657ddSImre Deak static u8 skl_get_plane_caps(struct drm_i915_private *i915,
244410a657ddSImre Deak enum pipe pipe, enum plane_id plane_id)
244510a657ddSImre Deak {
244610a657ddSImre Deak u8 caps = INTEL_PLANE_CAP_TILING_X;
244710a657ddSImre Deak
244810a657ddSImre Deak if (DISPLAY_VER(i915) < 13 || IS_ALDERLAKE_P(i915))
244910a657ddSImre Deak caps |= INTEL_PLANE_CAP_TILING_Y;
245010a657ddSImre Deak if (DISPLAY_VER(i915) < 12)
245110a657ddSImre Deak caps |= INTEL_PLANE_CAP_TILING_Yf;
2452072ce416SStanislav Lisovskiy if (HAS_4TILE(i915))
2453072ce416SStanislav Lisovskiy caps |= INTEL_PLANE_CAP_TILING_4;
245410a657ddSImre Deak
2455b7232a73SJuha-Pekka Heikkila if (!IS_ENABLED(I915) && !HAS_FLAT_CCS(i915))
2456b7232a73SJuha-Pekka Heikkila return caps;
2457b7232a73SJuha-Pekka Heikkila
245810a657ddSImre Deak if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) {
245910a657ddSImre Deak caps |= INTEL_PLANE_CAP_CCS_RC;
246010a657ddSImre Deak if (DISPLAY_VER(i915) >= 12)
246110a657ddSImre Deak caps |= INTEL_PLANE_CAP_CCS_RC_CC;
246210a657ddSImre Deak }
246310a657ddSImre Deak
246410a657ddSImre Deak if (gen12_plane_has_mc_ccs(i915, plane_id))
246510a657ddSImre Deak caps |= INTEL_PLANE_CAP_CCS_MC;
246610a657ddSImre Deak
2467f7e3885aSJuha-Pekka Heikkila if (DISPLAY_VER(i915) >= 14 && IS_DGFX(i915))
2468f7e3885aSJuha-Pekka Heikkila caps |= INTEL_PLANE_CAP_NEED64K_PHYS;
2469f7e3885aSJuha-Pekka Heikkila
247010a657ddSImre Deak return caps;
247110a657ddSImre Deak }
247210a657ddSImre Deak
247346d12f91SDave Airlie struct intel_plane *
skl_universal_plane_create(struct drm_i915_private * dev_priv,enum pipe pipe,enum plane_id plane_id)247446d12f91SDave Airlie skl_universal_plane_create(struct drm_i915_private *dev_priv,
247546d12f91SDave Airlie enum pipe pipe, enum plane_id plane_id)
247646d12f91SDave Airlie {
247746d12f91SDave Airlie const struct drm_plane_funcs *plane_funcs;
247846d12f91SDave Airlie struct intel_plane *plane;
247946d12f91SDave Airlie enum drm_plane_type plane_type;
248046d12f91SDave Airlie unsigned int supported_rotations;
248146d12f91SDave Airlie unsigned int supported_csc;
248246d12f91SDave Airlie const u64 *modifiers;
248346d12f91SDave Airlie const u32 *formats;
248446d12f91SDave Airlie int num_formats;
248546d12f91SDave Airlie int ret;
248646d12f91SDave Airlie
248746d12f91SDave Airlie plane = intel_plane_alloc();
248846d12f91SDave Airlie if (IS_ERR(plane))
248946d12f91SDave Airlie return plane;
249046d12f91SDave Airlie
249146d12f91SDave Airlie plane->pipe = pipe;
249246d12f91SDave Airlie plane->id = plane_id;
249346d12f91SDave Airlie plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
249446d12f91SDave Airlie
2495825bd833SVille Syrjälä intel_fbc_add_plane(skl_plane_fbc(dev_priv, pipe, plane_id), plane);
249646d12f91SDave Airlie
2497005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11) {
249846d12f91SDave Airlie plane->min_width = icl_plane_min_width;
24990e959b4eSVidya Srinivas if (icl_is_hdr_plane(dev_priv, plane_id))
25000e959b4eSVidya Srinivas plane->max_width = icl_hdr_plane_max_width;
25010e959b4eSVidya Srinivas else
25020e959b4eSVidya Srinivas plane->max_width = icl_sdr_plane_max_width;
250346d12f91SDave Airlie plane->max_height = icl_plane_max_height;
25046195f850SVille Syrjälä plane->min_cdclk = icl_plane_min_cdclk;
25052b5a4562SMatt Roper } else if (DISPLAY_VER(dev_priv) >= 10) {
250646d12f91SDave Airlie plane->max_width = glk_plane_max_width;
250746d12f91SDave Airlie plane->max_height = skl_plane_max_height;
2508efc52308SVille Syrjälä plane->min_cdclk = glk_plane_min_cdclk;
250946d12f91SDave Airlie } else {
251046d12f91SDave Airlie plane->max_width = skl_plane_max_width;
251146d12f91SDave Airlie plane->max_height = skl_plane_max_height;
2512efc52308SVille Syrjälä plane->min_cdclk = skl_plane_min_cdclk;
251346d12f91SDave Airlie }
251446d12f91SDave Airlie
25151301ce34SVille Syrjälä if (DISPLAY_VER(dev_priv) >= 13)
25161301ce34SVille Syrjälä plane->max_stride = adl_plane_max_stride;
25171301ce34SVille Syrjälä else
251846d12f91SDave Airlie plane->max_stride = skl_plane_max_stride;
25191301ce34SVille Syrjälä
25207652126cSVille Syrjälä if (DISPLAY_VER(dev_priv) >= 12)
25217652126cSVille Syrjälä plane->min_alignment = tgl_plane_min_alignment;
25227652126cSVille Syrjälä else
2523ee3c3e33SVille Syrjälä plane->min_alignment = skl_plane_min_alignment;
2524195b7a0dSVille Syrjälä
2525f8a005ebSVille Syrjälä if (DISPLAY_VER(dev_priv) >= 11) {
2526f8a005ebSVille Syrjälä plane->update_noarm = icl_plane_update_noarm;
2527f8a005ebSVille Syrjälä plane->update_arm = icl_plane_update_arm;
2528f8a005ebSVille Syrjälä plane->disable_arm = icl_plane_disable_arm;
2529f8a005ebSVille Syrjälä } else {
2530890b6ec4SVille Syrjälä plane->update_noarm = skl_plane_update_noarm;
25318ac80733SVille Syrjälä plane->update_arm = skl_plane_update_arm;
25328ac80733SVille Syrjälä plane->disable_arm = skl_plane_disable_arm;
2533f8a005ebSVille Syrjälä }
253446d12f91SDave Airlie plane->get_hw_state = skl_plane_get_hw_state;
253546d12f91SDave Airlie plane->check_plane = skl_plane_check;
253646d12f91SDave Airlie
2537df798d43SVille Syrjälä if (plane_id == PLANE_1) {
25382081c6aeSVille Syrjälä plane->need_async_flip_toggle_wa = IS_DISPLAY_VER(dev_priv, 9, 10);
253946d12f91SDave Airlie plane->async_flip = skl_plane_async_flip;
254046d12f91SDave Airlie plane->enable_flip_done = skl_plane_enable_flip_done;
254146d12f91SDave Airlie plane->disable_flip_done = skl_plane_disable_flip_done;
254246d12f91SDave Airlie }
254346d12f91SDave Airlie
2544005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11)
254546d12f91SDave Airlie formats = icl_get_plane_formats(dev_priv, pipe,
254646d12f91SDave Airlie plane_id, &num_formats);
25472b5a4562SMatt Roper else if (DISPLAY_VER(dev_priv) >= 10)
254846d12f91SDave Airlie formats = glk_get_plane_formats(dev_priv, pipe,
254946d12f91SDave Airlie plane_id, &num_formats);
255046d12f91SDave Airlie else
255146d12f91SDave Airlie formats = skl_get_plane_formats(dev_priv, pipe,
255246d12f91SDave Airlie plane_id, &num_formats);
255346d12f91SDave Airlie
2554e2b83294SImre Deak if (DISPLAY_VER(dev_priv) >= 12)
255546d12f91SDave Airlie plane_funcs = &gen12_plane_funcs;
255646d12f91SDave Airlie else
255746d12f91SDave Airlie plane_funcs = &skl_plane_funcs;
255846d12f91SDave Airlie
2559df798d43SVille Syrjälä if (plane_id == PLANE_1)
256046d12f91SDave Airlie plane_type = DRM_PLANE_TYPE_PRIMARY;
256146d12f91SDave Airlie else
256246d12f91SDave Airlie plane_type = DRM_PLANE_TYPE_OVERLAY;
256346d12f91SDave Airlie
256410a657ddSImre Deak modifiers = intel_fb_plane_get_modifiers(dev_priv,
256510a657ddSImre Deak skl_get_plane_caps(dev_priv, pipe, plane_id));
2566e2b83294SImre Deak
256746d12f91SDave Airlie ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
256846d12f91SDave Airlie 0, plane_funcs,
256946d12f91SDave Airlie formats, num_formats, modifiers,
257046d12f91SDave Airlie plane_type,
257146d12f91SDave Airlie "plane %d%c", plane_id + 1,
257246d12f91SDave Airlie pipe_name(pipe));
2573e2b83294SImre Deak
2574e2b83294SImre Deak kfree(modifiers);
2575e2b83294SImre Deak
257646d12f91SDave Airlie if (ret)
257746d12f91SDave Airlie goto fail;
257846d12f91SDave Airlie
25791649a4ccSMatt Roper if (DISPLAY_VER(dev_priv) >= 13)
25801649a4ccSMatt Roper supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
25811649a4ccSMatt Roper else
258246d12f91SDave Airlie supported_rotations =
258346d12f91SDave Airlie DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
258446d12f91SDave Airlie DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
258546d12f91SDave Airlie
2586c988d2dcSLucas De Marchi if (DISPLAY_VER(dev_priv) >= 11)
258746d12f91SDave Airlie supported_rotations |= DRM_MODE_REFLECT_X;
258846d12f91SDave Airlie
258946d12f91SDave Airlie drm_plane_create_rotation_property(&plane->base,
259046d12f91SDave Airlie DRM_MODE_ROTATE_0,
259146d12f91SDave Airlie supported_rotations);
259246d12f91SDave Airlie
259346d12f91SDave Airlie supported_csc = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709);
259446d12f91SDave Airlie
25952b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10)
259646d12f91SDave Airlie supported_csc |= BIT(DRM_COLOR_YCBCR_BT2020);
259746d12f91SDave Airlie
259846d12f91SDave Airlie drm_plane_create_color_properties(&plane->base,
259946d12f91SDave Airlie supported_csc,
260046d12f91SDave Airlie BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
260146d12f91SDave Airlie BIT(DRM_COLOR_YCBCR_FULL_RANGE),
260246d12f91SDave Airlie DRM_COLOR_YCBCR_BT709,
260346d12f91SDave Airlie DRM_COLOR_YCBCR_LIMITED_RANGE);
260446d12f91SDave Airlie
260546d12f91SDave Airlie drm_plane_create_alpha_property(&plane->base);
260646d12f91SDave Airlie drm_plane_create_blend_mode_property(&plane->base,
260746d12f91SDave Airlie BIT(DRM_MODE_BLEND_PIXEL_NONE) |
260846d12f91SDave Airlie BIT(DRM_MODE_BLEND_PREMULTI) |
260946d12f91SDave Airlie BIT(DRM_MODE_BLEND_COVERAGE));
261046d12f91SDave Airlie
261146d12f91SDave Airlie drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
261246d12f91SDave Airlie
2613005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 12)
261446d12f91SDave Airlie drm_plane_enable_fb_damage_clips(&plane->base);
261546d12f91SDave Airlie
2616c988d2dcSLucas De Marchi if (DISPLAY_VER(dev_priv) >= 11)
261746d12f91SDave Airlie drm_plane_create_scaling_filter_property(&plane->base,
261846d12f91SDave Airlie BIT(DRM_SCALING_FILTER_DEFAULT) |
261946d12f91SDave Airlie BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
262046d12f91SDave Airlie
2621d372ba42SJani Nikula intel_plane_helper_add(plane);
262246d12f91SDave Airlie
262346d12f91SDave Airlie return plane;
262446d12f91SDave Airlie
262546d12f91SDave Airlie fail:
262646d12f91SDave Airlie intel_plane_free(plane);
262746d12f91SDave Airlie
262846d12f91SDave Airlie return ERR_PTR(ret);
262946d12f91SDave Airlie }
263046d12f91SDave Airlie
263146d12f91SDave Airlie void
skl_get_initial_plane_config(struct intel_crtc * crtc,struct intel_initial_plane_config * plane_config)263246d12f91SDave Airlie skl_get_initial_plane_config(struct intel_crtc *crtc,
263346d12f91SDave Airlie struct intel_initial_plane_config *plane_config)
263446d12f91SDave Airlie {
263546d12f91SDave Airlie struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
263646d12f91SDave Airlie struct drm_device *dev = crtc->base.dev;
263746d12f91SDave Airlie struct drm_i915_private *dev_priv = to_i915(dev);
263846d12f91SDave Airlie struct intel_plane *plane = to_intel_plane(crtc->base.primary);
263946d12f91SDave Airlie enum plane_id plane_id = plane->id;
264046d12f91SDave Airlie enum pipe pipe;
264146d12f91SDave Airlie u32 val, base, offset, stride_mult, tiling, alpha;
264246d12f91SDave Airlie int fourcc, pixel_format;
264346d12f91SDave Airlie unsigned int aligned_height;
264446d12f91SDave Airlie struct drm_framebuffer *fb;
264546d12f91SDave Airlie struct intel_framebuffer *intel_fb;
2646072ce416SStanislav Lisovskiy static_assert(PLANE_CTL_TILED_YF == PLANE_CTL_TILED_4);
264746d12f91SDave Airlie
264846d12f91SDave Airlie if (!plane->get_hw_state(plane, &pipe))
264946d12f91SDave Airlie return;
265046d12f91SDave Airlie
265146d12f91SDave Airlie drm_WARN_ON(dev, pipe != crtc->pipe);
265246d12f91SDave Airlie
2653fb494357SStanislav Lisovskiy if (crtc_state->joiner_pipes) {
265446d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
2655fb494357SStanislav Lisovskiy "Unsupported joiner configuration for initial FB\n");
265646d12f91SDave Airlie return;
265746d12f91SDave Airlie }
265846d12f91SDave Airlie
265946d12f91SDave Airlie intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
266046d12f91SDave Airlie if (!intel_fb) {
266146d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n");
266246d12f91SDave Airlie return;
266346d12f91SDave Airlie }
266446d12f91SDave Airlie
266546d12f91SDave Airlie fb = &intel_fb->base;
266646d12f91SDave Airlie
266746d12f91SDave Airlie fb->dev = dev;
266846d12f91SDave Airlie
266946d12f91SDave Airlie val = intel_de_read(dev_priv, PLANE_CTL(pipe, plane_id));
267046d12f91SDave Airlie
2671005e9537SMatt Roper if (DISPLAY_VER(dev_priv) >= 11)
267212d7d858SVille Syrjälä pixel_format = val & PLANE_CTL_FORMAT_MASK_ICL;
267346d12f91SDave Airlie else
267412d7d858SVille Syrjälä pixel_format = val & PLANE_CTL_FORMAT_MASK_SKL;
267546d12f91SDave Airlie
26762b5a4562SMatt Roper if (DISPLAY_VER(dev_priv) >= 10) {
267712d7d858SVille Syrjälä u32 color_ctl;
267812d7d858SVille Syrjälä
267912d7d858SVille Syrjälä color_ctl = intel_de_read(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
268012d7d858SVille Syrjälä alpha = REG_FIELD_GET(PLANE_COLOR_ALPHA_MASK, color_ctl);
268146d12f91SDave Airlie } else {
268212d7d858SVille Syrjälä alpha = REG_FIELD_GET(PLANE_CTL_ALPHA_MASK, val);
268346d12f91SDave Airlie }
268446d12f91SDave Airlie
268546d12f91SDave Airlie fourcc = skl_format_to_fourcc(pixel_format,
268646d12f91SDave Airlie val & PLANE_CTL_ORDER_RGBX, alpha);
268746d12f91SDave Airlie fb->format = drm_format_info(fourcc);
268846d12f91SDave Airlie
268946d12f91SDave Airlie tiling = val & PLANE_CTL_TILED_MASK;
269046d12f91SDave Airlie switch (tiling) {
269146d12f91SDave Airlie case PLANE_CTL_TILED_LINEAR:
269246d12f91SDave Airlie fb->modifier = DRM_FORMAT_MOD_LINEAR;
269346d12f91SDave Airlie break;
269446d12f91SDave Airlie case PLANE_CTL_TILED_X:
269546d12f91SDave Airlie plane_config->tiling = I915_TILING_X;
269646d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_X_TILED;
269746d12f91SDave Airlie break;
269846d12f91SDave Airlie case PLANE_CTL_TILED_Y:
269946d12f91SDave Airlie plane_config->tiling = I915_TILING_Y;
270046d12f91SDave Airlie if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
2701f2eb43f0SJuha-Pekka Heikkila if (DISPLAY_VER(dev_priv) >= 14)
2702f2eb43f0SJuha-Pekka Heikkila fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_RC_CCS;
2703f2eb43f0SJuha-Pekka Heikkila else if (DISPLAY_VER(dev_priv) >= 12)
27044c3afa72SMatt Roper fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS;
27054c3afa72SMatt Roper else
27064c3afa72SMatt Roper fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
270746d12f91SDave Airlie else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
2708f2eb43f0SJuha-Pekka Heikkila if (DISPLAY_VER(dev_priv) >= 14)
2709f2eb43f0SJuha-Pekka Heikkila fb->modifier = I915_FORMAT_MOD_4_TILED_MTL_MC_CCS;
2710f2eb43f0SJuha-Pekka Heikkila else
271146d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS;
271246d12f91SDave Airlie else
271346d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_Y_TILED;
271446d12f91SDave Airlie break;
2715072ce416SStanislav Lisovskiy case PLANE_CTL_TILED_YF: /* aka PLANE_CTL_TILED_4 on XE_LPD+ */
2716072ce416SStanislav Lisovskiy if (HAS_4TILE(dev_priv)) {
2717680025dcSJuha-Pekka Heikkilä u32 rc_mask = PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
2718680025dcSJuha-Pekka Heikkilä PLANE_CTL_CLEAR_COLOR_DISABLE;
2719680025dcSJuha-Pekka Heikkilä
2720680025dcSJuha-Pekka Heikkilä if ((val & rc_mask) == rc_mask)
27214c3afa72SMatt Roper fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_RC_CCS;
27224c3afa72SMatt Roper else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
27234c3afa72SMatt Roper fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_MC_CCS;
2724680025dcSJuha-Pekka Heikkilä else if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
2725680025dcSJuha-Pekka Heikkilä fb->modifier = I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
27264c3afa72SMatt Roper else
2727072ce416SStanislav Lisovskiy fb->modifier = I915_FORMAT_MOD_4_TILED;
2728072ce416SStanislav Lisovskiy } else {
272946d12f91SDave Airlie if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
273046d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
273146d12f91SDave Airlie else
273246d12f91SDave Airlie fb->modifier = I915_FORMAT_MOD_Yf_TILED;
2733072ce416SStanislav Lisovskiy }
273446d12f91SDave Airlie break;
273546d12f91SDave Airlie default:
273646d12f91SDave Airlie MISSING_CASE(tiling);
273746d12f91SDave Airlie goto error;
273846d12f91SDave Airlie }
273946d12f91SDave Airlie
274004da42b4SJouni Högander if (!dev_priv->display.params.enable_dpt &&
2741c5de2484SVille Syrjälä intel_fb_modifier_uses_dpt(dev_priv, fb->modifier)) {
2742c5de2484SVille Syrjälä drm_dbg_kms(&dev_priv->drm, "DPT disabled, skipping initial FB\n");
2743c5de2484SVille Syrjälä goto error;
2744c5de2484SVille Syrjälä }
2745c5de2484SVille Syrjälä
274646d12f91SDave Airlie /*
274746d12f91SDave Airlie * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr
274846d12f91SDave Airlie * while i915 HW rotation is clockwise, thats why this swapping.
274946d12f91SDave Airlie */
275046d12f91SDave Airlie switch (val & PLANE_CTL_ROTATE_MASK) {
275146d12f91SDave Airlie case PLANE_CTL_ROTATE_0:
275246d12f91SDave Airlie plane_config->rotation = DRM_MODE_ROTATE_0;
275346d12f91SDave Airlie break;
275446d12f91SDave Airlie case PLANE_CTL_ROTATE_90:
275546d12f91SDave Airlie plane_config->rotation = DRM_MODE_ROTATE_270;
275646d12f91SDave Airlie break;
275746d12f91SDave Airlie case PLANE_CTL_ROTATE_180:
275846d12f91SDave Airlie plane_config->rotation = DRM_MODE_ROTATE_180;
275946d12f91SDave Airlie break;
276046d12f91SDave Airlie case PLANE_CTL_ROTATE_270:
276146d12f91SDave Airlie plane_config->rotation = DRM_MODE_ROTATE_90;
276246d12f91SDave Airlie break;
276346d12f91SDave Airlie }
276446d12f91SDave Airlie
2765c988d2dcSLucas De Marchi if (DISPLAY_VER(dev_priv) >= 11 && val & PLANE_CTL_FLIP_HORIZONTAL)
276646d12f91SDave Airlie plane_config->rotation |= DRM_MODE_REFLECT_X;
276746d12f91SDave Airlie
276846d12f91SDave Airlie /* 90/270 degree rotation would require extra work */
276946d12f91SDave Airlie if (drm_rotation_90_or_270(plane_config->rotation))
277046d12f91SDave Airlie goto error;
277146d12f91SDave Airlie
277212d7d858SVille Syrjälä base = intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & PLANE_SURF_ADDR_MASK;
277346d12f91SDave Airlie plane_config->base = base;
277446d12f91SDave Airlie
277546d12f91SDave Airlie offset = intel_de_read(dev_priv, PLANE_OFFSET(pipe, plane_id));
277647e157a5SJani Nikula drm_WARN_ON(&dev_priv->drm, offset != 0);
277746d12f91SDave Airlie
277846d12f91SDave Airlie val = intel_de_read(dev_priv, PLANE_SIZE(pipe, plane_id));
277912d7d858SVille Syrjälä fb->height = REG_FIELD_GET(PLANE_HEIGHT_MASK, val) + 1;
278012d7d858SVille Syrjälä fb->width = REG_FIELD_GET(PLANE_WIDTH_MASK, val) + 1;
278146d12f91SDave Airlie
278246d12f91SDave Airlie val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
278346d12f91SDave Airlie stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
2784e7367af1SJuha-Pekka Heikkilä
278512d7d858SVille Syrjälä fb->pitches[0] = REG_FIELD_GET(PLANE_STRIDE__MASK, val) * stride_mult;
278646d12f91SDave Airlie
278746d12f91SDave Airlie aligned_height = intel_fb_align_height(fb, 0, fb->height);
278846d12f91SDave Airlie
278946d12f91SDave Airlie plane_config->size = fb->pitches[0] * aligned_height;
279046d12f91SDave Airlie
279146d12f91SDave Airlie drm_dbg_kms(&dev_priv->drm,
279246d12f91SDave Airlie "%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
279346d12f91SDave Airlie crtc->base.name, plane->base.name, fb->width, fb->height,
279446d12f91SDave Airlie fb->format->cpp[0] * 8, base, fb->pitches[0],
279546d12f91SDave Airlie plane_config->size);
279646d12f91SDave Airlie
279746d12f91SDave Airlie plane_config->fb = intel_fb;
279846d12f91SDave Airlie return;
279946d12f91SDave Airlie
280046d12f91SDave Airlie error:
280146d12f91SDave Airlie kfree(intel_fb);
280246d12f91SDave Airlie }
2803a8153627SVille Syrjälä
skl_fixup_initial_plane_config(struct intel_crtc * crtc,const struct intel_initial_plane_config * plane_config)2804a8153627SVille Syrjälä bool skl_fixup_initial_plane_config(struct intel_crtc *crtc,
2805a8153627SVille Syrjälä const struct intel_initial_plane_config *plane_config)
2806a8153627SVille Syrjälä {
2807a8153627SVille Syrjälä struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2808a8153627SVille Syrjälä struct intel_plane *plane = to_intel_plane(crtc->base.primary);
2809a8153627SVille Syrjälä const struct intel_plane_state *plane_state =
2810a8153627SVille Syrjälä to_intel_plane_state(plane->base.state);
2811a8153627SVille Syrjälä enum plane_id plane_id = plane->id;
2812a8153627SVille Syrjälä enum pipe pipe = crtc->pipe;
2813a8153627SVille Syrjälä u32 base;
2814a8153627SVille Syrjälä
2815a8153627SVille Syrjälä if (!plane_state->uapi.visible)
2816a8153627SVille Syrjälä return false;
2817a8153627SVille Syrjälä
2818a8153627SVille Syrjälä base = intel_plane_ggtt_offset(plane_state);
2819a8153627SVille Syrjälä
2820a8153627SVille Syrjälä /*
2821a8153627SVille Syrjälä * We may have moved the surface to a different
2822a8153627SVille Syrjälä * part of ggtt, make the plane aware of that.
2823a8153627SVille Syrjälä */
2824a8153627SVille Syrjälä if (plane_config->base == base)
2825a8153627SVille Syrjälä return false;
2826a8153627SVille Syrjälä
2827a8153627SVille Syrjälä intel_de_write(i915, PLANE_SURF(pipe, plane_id), base);
2828a8153627SVille Syrjälä
2829a8153627SVille Syrjälä return true;
2830a8153627SVille Syrjälä }
2831