+++ /dev/null
-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
-@@ -538,6 +538,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;
-@@ -554,6 +556,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)
-@@ -572,6 +577,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);
-
-@@ -579,6 +587,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)
- {
-@@ -2275,6 +2299,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;