Similarly to the previous patches, the CSC setup is slightly different in
the BCM2711 than in the previous generations. Let's add a callback for it.

Signed-off-by: Maxime Ripard <max...@cerno.tech>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 142 +++++++++++++++++++---------------
 drivers/gpu/drm/vc4/vc4_hdmi.h |   7 ++-
 2 files changed, 89 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 19897d6525ac..a50220bfd5dd 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -334,12 +334,44 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder 
*encoder)
                DRM_ERROR("Failed to release power domain: %d\n", ret);
 }
 
-static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
+static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
+{
+       u32 csc_ctl;
+
+       csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
+                               VC4_HD_CSC_CTL_ORDER);
+
+       if (enable) {
+               /* CEA VICs other than #1 requre limited range RGB
+                * output unless overridden by an AVI infoframe.
+                * Apply a colorspace conversion to squash 0-255 down
+                * to 16-235.  The matrix here is:
+                *
+                * [ 0      0      0.8594 16]
+                * [ 0      0.8594 0      16]
+                * [ 0.8594 0      0      16]
+                * [ 0      0      0       1]
+                */
+               csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
+               csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
+               csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
+                                        VC4_HD_CSC_CTL_MODE);
+
+               HDMI_WRITE(HDMI_CSC_12_11, (0x000 << 16) | 0x000);
+               HDMI_WRITE(HDMI_CSC_14_13, (0x100 << 16) | 0x6e0);
+               HDMI_WRITE(HDMI_CSC_22_21, (0x6e0 << 16) | 0x000);
+               HDMI_WRITE(HDMI_CSC_24_23, (0x100 << 16) | 0x000);
+               HDMI_WRITE(HDMI_CSC_32_31, (0x000 << 16) | 0x6e0);
+               HDMI_WRITE(HDMI_CSC_34_33, (0x100 << 16) | 0x000);
+       }
+
+       /* The RGB order applies even when CSC is disabled. */
+       HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
+}
+
+static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+                                struct drm_display_mode *mode)
 {
-       struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
-       struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-       struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder;
-       bool debug_dump_regs = false;
        bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
        bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
        bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -357,7 +389,41 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
*encoder)
                                        mode->crtc_vsync_end -
                                        interlaced,
                                        VC4_HDMI_VERTB_VBP));
-       u32 csc_ctl;
+
+       HDMI_WRITE(HDMI_HORZA,
+                  (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
+                  (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
+                  VC4_SET_FIELD(mode->hdisplay * pixel_rep,
+                                VC4_HDMI_HORZA_HAP));
+
+       HDMI_WRITE(HDMI_HORZB,
+                  VC4_SET_FIELD((mode->htotal -
+                                 mode->hsync_end) * pixel_rep,
+                                VC4_HDMI_HORZB_HBP) |
+                  VC4_SET_FIELD((mode->hsync_end -
+                                 mode->hsync_start) * pixel_rep,
+                                VC4_HDMI_HORZB_HSP) |
+                  VC4_SET_FIELD((mode->hsync_start -
+                                 mode->hdisplay) * pixel_rep,
+                                VC4_HDMI_HORZB_HFP));
+
+       HDMI_WRITE(HDMI_VERTA0, verta);
+       HDMI_WRITE(HDMI_VERTA1, verta);
+
+       HDMI_WRITE(HDMI_VERTB0, vertb_even);
+       HDMI_WRITE(HDMI_VERTB1, vertb);
+
+       HDMI_WRITE(HDMI_VID_CTL,
+                  (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
+                  (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
+}
+
+static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
+{
+       struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
+       struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+       struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+       bool debug_dump_regs = false;
        int ret;
 
        ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
@@ -401,68 +467,22 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder 
*encoder)
                   VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
                   VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
 
-       HDMI_WRITE(HDMI_HORZA,
-                  (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
-                  (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
-                  VC4_SET_FIELD(mode->hdisplay * pixel_rep,
-                                VC4_HDMI_HORZA_HAP));
-
-       HDMI_WRITE(HDMI_HORZB,
-                  VC4_SET_FIELD((mode->htotal -
-                                 mode->hsync_end) * pixel_rep,
-                                VC4_HDMI_HORZB_HBP) |
-                  VC4_SET_FIELD((mode->hsync_end -
-                                 mode->hsync_start) * pixel_rep,
-                                VC4_HDMI_HORZB_HSP) |
-                  VC4_SET_FIELD((mode->hsync_start -
-                                 mode->hdisplay) * pixel_rep,
-                                VC4_HDMI_HORZB_HFP));
-
-       HDMI_WRITE(HDMI_VERTA0, verta);
-       HDMI_WRITE(HDMI_VERTA1, verta);
-
-       HDMI_WRITE(HDMI_VERTB0, vertb_even);
-       HDMI_WRITE(HDMI_VERTB1, vertb);
-
-       HDMI_WRITE(HDMI_VID_CTL,
-                  (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
-                  (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
-
-       csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
-                               VC4_HD_CSC_CTL_ORDER);
+       if (vc4_hdmi->variant->set_timings)
+               vc4_hdmi->variant->set_timings(vc4_hdmi, mode);
 
        if (vc4_encoder->hdmi_monitor &&
-           drm_default_rgb_quant_range(mode) ==
-           HDMI_QUANTIZATION_RANGE_LIMITED) {
-               /* CEA VICs other than #1 requre limited range RGB
-                * output unless overridden by an AVI infoframe.
-                * Apply a colorspace conversion to squash 0-255 down
-                * to 16-235.  The matrix here is:
-                *
-                * [ 0      0      0.8594 16]
-                * [ 0      0.8594 0      16]
-                * [ 0.8594 0      0      16]
-                * [ 0      0      0       1]
-                */
-               csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
-               csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
-               csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
-                                        VC4_HD_CSC_CTL_MODE);
+           drm_default_rgb_quant_range(mode) == 
HDMI_QUANTIZATION_RANGE_LIMITED) {
+               if (vc4_hdmi->variant->csc_setup)
+                       vc4_hdmi->variant->csc_setup(vc4_hdmi, true);
 
-               HDMI_WRITE(HDMI_CSC_12_11, (0x000 << 16) | 0x000);
-               HDMI_WRITE(HDMI_CSC_14_13, (0x100 << 16) | 0x6e0);
-               HDMI_WRITE(HDMI_CSC_22_21, (0x6e0 << 16) | 0x000);
-               HDMI_WRITE(HDMI_CSC_24_23, (0x100 << 16) | 0x000);
-               HDMI_WRITE(HDMI_CSC_32_31, (0x000 << 16) | 0x6e0);
-               HDMI_WRITE(HDMI_CSC_34_33, (0x100 << 16) | 0x000);
                vc4_encoder->limited_rgb_range = true;
        } else {
+               if (vc4_hdmi->variant->csc_setup)
+                       vc4_hdmi->variant->csc_setup(vc4_hdmi, false);
+
                vc4_encoder->limited_rgb_range = false;
        }
 
-       /* The RGB order applies even when CSC is disabled. */
-       HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
-
        HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
 
        if (debug_dump_regs) {
@@ -1431,7 +1451,9 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
        .num_registers          = ARRAY_SIZE(vc4_hdmi_fields),
 
        .init_resources         = vc4_hdmi_init_resources,
+       .csc_setup              = vc4_hdmi_csc_setup,
        .reset                  = vc4_hdmi_reset,
+       .set_timings            = vc4_hdmi_set_timings,
        .phy_init               = vc4_hdmi_phy_init,
        .phy_disable            = vc4_hdmi_phy_disable,
        .phy_rng_enable         = vc4_hdmi_phy_rng_enable,
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 950accbc44e4..0c32dc46d289 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -41,6 +41,13 @@ struct vc4_hdmi_variant {
        /* Callback to reset the HDMI block */
        void (*reset)(struct vc4_hdmi *vc4_hdmi);
 
+       /* Callback to enable / disable the CSC */
+       void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, bool enable);
+
+       /* Callback to configure the video timings in the HDMI block */
+       void (*set_timings)(struct vc4_hdmi *vc4_hdmi,
+                           struct drm_display_mode *mode);
+
        /* Callback to initialize the PHY according to the mode */
        void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
                         struct drm_display_mode *mode);
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to