Re: [PATCH v4 55/78] drm/vc4: hdmi: Add a CSC setup callback

2020-07-28 Thread Dave Stevenson
Hi Maxime

On Wed, 8 Jul 2020 at 18:43, Maxime Ripard  wrote:
>
> 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.

We've gained the set_timings callback in this patch as well as
csc_setup. Was that an accidental squash as we had them as independent
commits in v1.

  Dave

> Signed-off-by: Maxime Ripard 
> ---
>  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;

[PATCH v4 55/78] drm/vc4: hdmi: Add a CSC setup callback

2020-07-08 Thread Maxime Ripard
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 
---
 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_HD