vc4/hvs: Updates to support D0 alpha and csc changes
authorDom Cobley <popcornmix@gmail.com>
Fri, 12 Jan 2024 15:48:14 +0000 (15:48 +0000)
committerDom Cobley <popcornmix@gmail.com>
Mon, 19 Feb 2024 11:35:29 +0000 (11:35 +0000)
2712D0 has a simpler colourspace conversion matrix block
so set that up.

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
drivers/gpu/drm/vc4/vc4_hvs.c
drivers/gpu/drm/vc4/vc4_plane.c
drivers/gpu/drm/vc4/vc4_regs.h

index 479768f..8872a55 100644 (file)
@@ -1933,6 +1933,17 @@ static int vc4_hvs_hw_init(struct vc4_hvs *hvs)
 #define CFC1_N_MA_CSC_COEFF_C23(x)     (0xa03c + ((x) * 0x3000))
 #define CFC1_N_MA_CSC_COEFF_C24(x)     (0xa040 + ((x) * 0x3000))
 
+#define SCALER_PI_CMP_CSC_RED0(x)              (0x200 + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_RED1(x)              (0x204 + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_RED_CLAMP(x)         (0x208 + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_CFG(x)               (0x20c + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_GREEN0(x)            (0x210 + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_GREEN1(x)            (0x214 + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_GREEN_CLAMP(x)       (0x218 + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_BLUE0(x)             (0x220 + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_BLUE1(x)             (0x224 + ((x) * 0x40))
+#define SCALER_PI_CMP_CSC_BLUE_CLAMP(x)                (0x228 + ((x) * 0x40))
+
 /* 4 S2.22 multiplication factors, and 1 S9.15 addititive element for each of 3
  * output components
  */
@@ -2003,31 +2014,43 @@ static int vc6_hvs_hw_init(struct vc4_hvs *hvs)
        HVS_WRITE(SCALER6(PRI_MAP0), 0xffffffff);
        HVS_WRITE(SCALER6(PRI_MAP1), 0xffffffff);
 
-       if (hvs->vc4->step_d0)
-               return;
-
-       for (i = 0; i < 6; i++) {
-               coeffs = &csc_coeffs[i / 3][i % 3];
-
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C00(i), coeffs->csc[0][0]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C01(i), coeffs->csc[0][1]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C02(i), coeffs->csc[0][2]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C03(i), coeffs->csc[0][3]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C04(i), coeffs->csc[0][4]);
-
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C10(i), coeffs->csc[1][0]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C11(i), coeffs->csc[1][1]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C12(i), coeffs->csc[1][2]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C13(i), coeffs->csc[1][3]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C14(i), coeffs->csc[1][4]);
-
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C20(i), coeffs->csc[2][0]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C21(i), coeffs->csc[2][1]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C22(i), coeffs->csc[2][2]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C23(i), coeffs->csc[2][3]);
-               HVS_WRITE(CFC1_N_MA_CSC_COEFF_C24(i), coeffs->csc[2][4]);
-
-               HVS_WRITE(CFC1_N_NL_CSC_CTRL(i), BIT(15));
+       if (hvs->vc4->step_d0) {
+               for (i = 0; i < 8; i++) {
+                       HVS_WRITE(SCALER_PI_CMP_CSC_RED0(i), 0x1f002566);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_RED1(i), 0x3994);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_RED_CLAMP(i), 0xfff00000);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_CFG(i), 0x1);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_GREEN0(i), 0x18002566);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_GREEN1(i), 0xf927eee2);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_GREEN_CLAMP(i), 0xfff00000);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_BLUE0(i), 0x18002566);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_BLUE1(i), 0x43d80000);
+                       HVS_WRITE(SCALER_PI_CMP_CSC_BLUE_CLAMP(i), 0xfff00000);
+               }
+       } else {
+               for (i = 0; i < 6; i++) {
+                       coeffs = &csc_coeffs[i / 3][i % 3];
+
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C00(i), coeffs->csc[0][0]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C01(i), coeffs->csc[0][1]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C02(i), coeffs->csc[0][2]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C03(i), coeffs->csc[0][3]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C04(i), coeffs->csc[0][4]);
+
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C10(i), coeffs->csc[1][0]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C11(i), coeffs->csc[1][1]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C12(i), coeffs->csc[1][2]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C13(i), coeffs->csc[1][3]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C14(i), coeffs->csc[1][4]);
+
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C20(i), coeffs->csc[2][0]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C21(i), coeffs->csc[2][1]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C22(i), coeffs->csc[2][2]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C23(i), coeffs->csc[2][3]);
+                       HVS_WRITE(CFC1_N_MA_CSC_COEFF_C24(i), coeffs->csc[2][4]);
+
+                       HVS_WRITE(CFC1_N_NL_CSC_CTRL(i), BIT(15));
+               }
        }
 
        return 0;
index 6289d90..b0bde13 100644 (file)
@@ -1054,6 +1054,12 @@ static u32 vc4_hvs5_get_alpha_blend_mode(struct drm_plane_state *state)
 
        WARN_ON_ONCE(vc4->gen != VC4_GEN_5 && vc4->gen != VC4_GEN_6);
 
+       if (vc4->gen == VC4_GEN_6 && vc4->step_d0) {
+               return state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI ?
+                       SCALER5_CTL2_ALPHA_PREMULT : 0;
+       }
+
+
        if (!state->fb->format->has_alpha)
                return VC4_SET_FIELD(SCALER5_CTL2_ALPHA_MODE_FIXED,
                                     SCALER5_CTL2_ALPHA_MODE);
@@ -1569,14 +1575,13 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
 static u32 vc6_plane_get_csc_mode(struct vc4_plane_state *vc4_state)
 {
        struct drm_plane_state *state = &vc4_state->base;
+       struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev);
        u32 ret = 0;
 
        if (vc4_state->is_yuv) {
                enum drm_color_encoding color_encoding = state->color_encoding;
                enum drm_color_range color_range = state->color_range;
 
-               ret |= SCALER6_CTL2_CSC_ENABLE;
-
                /* CSC pre-loaded with:
                 * 0 = BT601 limited range
                 * 1 = BT709 limited range
@@ -1590,8 +1595,15 @@ static u32 vc6_plane_get_csc_mode(struct vc4_plane_state *vc4_state)
                if (color_range > DRM_COLOR_YCBCR_FULL_RANGE)
                        color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
 
-               ret |= VC4_SET_FIELD(color_encoding + (color_range * 3),
-                                    SCALER6_CTL2_BRCM_CFC_CONTROL);
+               if (vc4->step_d0) {
+                       ret |= SCALER6D0_CTL2_CSC_ENABLE;
+                       ret |= VC4_SET_FIELD(color_encoding + (color_range * 3),
+                                       SCALER6D0_CTL2_BRCM_CFC_CONTROL);
+               } else {
+                       ret |= SCALER6_CTL2_CSC_ENABLE;
+                       ret |= VC4_SET_FIELD(color_encoding + (color_range * 3),
+                                       SCALER6_CTL2_BRCM_CFC_CONTROL);
+               }
        }
 
        return ret;
index 5c4f643..2f7b6da 100644 (file)
@@ -1417,6 +1417,9 @@ enum hvs_pixel_format {
 #define SCALER6_CTL2_BRCM_CFC_CONTROL_MASK     VC4_MASK(18, 16)
 #define SCALER6_CTL2_ALPHA_MASK                        VC4_MASK(15, 4)
 
+#define SCALER6D0_CTL2_CSC_ENABLE              BIT(19)
+#define SCALER6D0_CTL2_BRCM_CFC_CONTROL_MASK   VC4_MASK(22, 20)
+
 #define SCALER6_POS1_SCL_LINES_MASK            VC4_MASK(28, 16)
 #define SCALER6_POS1_SCL_WIDTH_MASK            VC4_MASK(12, 0)