diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch new file mode 100644 index 0000000000..0106470d93 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch @@ -0,0 +1,134 @@ +From 110cf6bdc1d79f2ee7a435bc9d1ec900aba11ed5 Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Thu, 26 Dec 2019 18:41:53 +0100 +Subject: [PATCH] drm/vc4: hdmi: Add a CSC setup callback + +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 <maxime@cerno.tech> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 71 ++++++++++++++++++++-------------- + drivers/gpu/drm/vc4/vc4_hdmi.h | 3 ++ + 2 files changed, 45 insertions(+), 29 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -337,6 +337,41 @@ static void vc4_hdmi_encoder_disable(str + DRM_ERROR("Failed to release power domain: %d\n", ret); + } + ++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_encoder_enable(struct drm_encoder *encoder) + { + struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; +@@ -360,7 +395,6 @@ static void vc4_hdmi_encoder_enable(stru + mode->crtc_vsync_end - + interlaced, + VC4_HDMI_VERTB_VBP)); +- u32 csc_ctl; + int ret; + + ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev); +@@ -431,41 +465,19 @@ static void vc4_hdmi_encoder_enable(stru + (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_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) { +@@ -1427,6 +1439,7 @@ static const struct vc4_hdmi_variant bcm + .num_registers = ARRAY_SIZE(vc4_hdmi_fields), + + .init_resources = vc4_hdmi_init_resources, ++ .csc_setup = vc4_hdmi_csc_setup, + .reset = vc4_hdmi_reset, + .phy_init = vc4_hdmi_phy_init, + .phy_disable = vc4_hdmi_phy_disable, +--- a/drivers/gpu/drm/vc4/vc4_hdmi.h ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h +@@ -41,6 +41,9 @@ 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 initialize the PHY according to the mode */ + void (*phy_init)(struct vc4_hdmi *vc4_hdmi, + struct drm_display_mode *mode); |