diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0602-drm-vc4-hdmi-Add-a-workqueue-to-set-scrambling.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.10/950-0602-drm-vc4-hdmi-Add-a-workqueue-to-set-scrambling.patch | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0602-drm-vc4-hdmi-Add-a-workqueue-to-set-scrambling.patch b/target/linux/bcm27xx/patches-5.10/950-0602-drm-vc4-hdmi-Add-a-workqueue-to-set-scrambling.patch new file mode 100644 index 0000000000..ab461f383c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.10/950-0602-drm-vc4-hdmi-Add-a-workqueue-to-set-scrambling.patch @@ -0,0 +1,91 @@ +From c20cb28d802aa148cfa90c0682323e9d52dc0466 Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Fri, 7 May 2021 15:28:21 +0200 +Subject: [PATCH] drm/vc4: hdmi: Add a workqueue to set scrambling + +It looks like some displays (like the LG 27UL850-W) don't enable the +scrambling when the HDMI driver enables it. However, if we set later the +scrambler enable bit, the display will work as expected. + +Let's create delayed work queue to periodically look at the display +scrambling status, and if it's not set yet try to enable it again. + +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +++++++++++++++++++++++++ + drivers/gpu/drm/vc4/vc4_hdmi.h | 2 ++ + 2 files changed, 27 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -537,6 +537,8 @@ static bool vc4_hdmi_supports_scrambling + return true; + } + ++#define SCRAMBLING_POLLING_DELAY_MS 1000 ++ + static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder) + { + struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; +@@ -553,6 +555,9 @@ static void vc4_hdmi_enable_scrambling(s + + HDMI_WRITE(HDMI_SCRAMBLER_CTL, HDMI_READ(HDMI_SCRAMBLER_CTL) | + VC5_HDMI_SCRAMBLER_CTL_ENABLE); ++ ++ queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work, ++ msecs_to_jiffies(SCRAMBLING_POLLING_DELAY_MS)); + } + + static void vc4_hdmi_disable_scrambling(struct drm_encoder *encoder) +@@ -571,6 +576,9 @@ static void vc4_hdmi_disable_scrambling( + if (crtc && !vc4_hdmi_mode_needs_scrambling(&crtc->mode)) + return; + ++ if (delayed_work_pending(&vc4_hdmi->scrambling_work)) ++ cancel_delayed_work_sync(&vc4_hdmi->scrambling_work); ++ + HDMI_WRITE(HDMI_SCRAMBLER_CTL, HDMI_READ(HDMI_SCRAMBLER_CTL) & + ~VC5_HDMI_SCRAMBLER_CTL_ENABLE); + +@@ -578,6 +586,22 @@ static void vc4_hdmi_disable_scrambling( + drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, false); + } + ++static void vc4_hdmi_scrambling_wq(struct work_struct *work) ++{ ++ struct vc4_hdmi *vc4_hdmi = container_of(to_delayed_work(work), ++ struct vc4_hdmi, ++ scrambling_work); ++ ++ if (drm_scdc_get_scrambling_status(vc4_hdmi->ddc)) ++ return; ++ ++ drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true); ++ drm_scdc_set_scrambling(vc4_hdmi->ddc, true); ++ ++ queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work, ++ msecs_to_jiffies(SCRAMBLING_POLLING_DELAY_MS)); ++} ++ + static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder, + struct drm_atomic_state *state) + { +@@ -2274,6 +2298,7 @@ static int vc4_hdmi_bind(struct device * + vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL); + if (!vc4_hdmi) + return -ENOMEM; ++ INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq); + + dev_set_drvdata(dev, vc4_hdmi); + encoder = &vc4_hdmi->encoder.base.base; +--- a/drivers/gpu/drm/vc4/vc4_hdmi.h ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h +@@ -131,6 +131,8 @@ struct vc4_hdmi { + struct vc4_hdmi_encoder encoder; + struct drm_connector connector; + ++ struct delayed_work scrambling_work; ++ + struct i2c_adapter *ddc; + void __iomem *hdmicore_regs; + void __iomem *hd_regs; |