From a89289334ecdc2a4543de64efe650a9f58b95060 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Mon, 24 Jan 2022 18:00:19 +0100 Subject: [PATCH] TEST linux (RPi): add patch to delay cec_phys_addr_invalidate Signed-off-by: Matthias Reichl --- ...-test-delay-cec_phys_addr_invalidate.patch | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 packages/linux/patches/raspberrypi/linux-001-test-delay-cec_phys_addr_invalidate.patch diff --git a/packages/linux/patches/raspberrypi/linux-001-test-delay-cec_phys_addr_invalidate.patch b/packages/linux/patches/raspberrypi/linux-001-test-delay-cec_phys_addr_invalidate.patch new file mode 100644 index 0000000000..3abacb3ac5 --- /dev/null +++ b/packages/linux/patches/raspberrypi/linux-001-test-delay-cec_phys_addr_invalidate.patch @@ -0,0 +1,87 @@ +From b5c047738ca72ac345820a4573b576a466584234 Mon Sep 17 00:00:00 2001 +From: Dom Cobley +Date: Thu, 20 Jan 2022 18:09:18 +0000 +Subject: [PATCH] drm/vc4:hdmi: Delay cec_phys_addr_invalidate + +Wait briefly before generating the cec_phys_addr_invalidate, +and skip it if it's immediately followed by a valid one. + +This avoids the confusion of TV generating a powered up event +and libcec generating an active source message which swicthes +everything back on after a power off. + +See: +https://forum.libreelec.tv/thread/24783-tv-avr-turns-back-on-right-after-turning-them-off +Signed-off-by: Dom Cobley +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 16 +++++++++++++++- + drivers/gpu/drm/vc4/vc4_hdmi.h | 1 + + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c +index d71cd43785053..7f68faedba669 100644 +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -224,6 +224,8 @@ static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {} + + static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder); + ++#define CEC_POLLING_DELAY_MS 1000 ++ + static enum drm_connector_status + vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) + { +@@ -250,6 +252,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) + struct edid *edid = drm_get_edid(connector, vc4_hdmi->ddc); + + if (edid) { ++ if (delayed_work_pending(&vc4_hdmi->cec_work)) ++ cancel_delayed_work_sync(&vc4_hdmi->cec_work); + cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid); + vc4_hdmi->encoder.hdmi_monitor = drm_detect_hdmi_monitor(edid); + kfree(edid); +@@ -266,7 +270,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) + + vc4_hdmi->encoder.hdmi_monitor = false; + +- cec_phys_addr_invalidate(vc4_hdmi->cec_adap); ++ queue_delayed_work(system_wq, &vc4_hdmi->cec_work, ++ msecs_to_jiffies(CEC_POLLING_DELAY_MS)); + + out: + pm_runtime_put(&vc4_hdmi->pdev->dev); +@@ -751,6 +756,14 @@ static void vc4_hdmi_scrambling_wq(struct work_struct *work) + msecs_to_jiffies(SCRAMBLING_POLLING_DELAY_MS)); + } + ++static void vc4_hdmi_cec_wq(struct work_struct *work) ++{ ++ struct vc4_hdmi *vc4_hdmi = container_of(to_delayed_work(work), ++ struct vc4_hdmi, ++ cec_work); ++ cec_phys_addr_invalidate(vc4_hdmi->cec_adap); ++} ++ + static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder, + struct drm_atomic_state *state) + { +@@ -2956,6 +2969,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) + mutex_init(&vc4_hdmi->mutex); + spin_lock_init(&vc4_hdmi->hw_lock); + INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq); ++ INIT_DELAYED_WORK(&vc4_hdmi->cec_work, vc4_hdmi_cec_wq); + + dev_set_drvdata(dev, vc4_hdmi); + encoder = &vc4_hdmi->encoder.base.base; +diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h +index 3dd0d2a53a445..2125633f72e3d 100644 +--- a/drivers/gpu/drm/vc4/vc4_hdmi.h ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h +@@ -141,6 +141,7 @@ struct vc4_hdmi { + struct drm_connector connector; + + struct delayed_work scrambling_work; ++ struct delayed_work cec_work; + + struct i2c_adapter *ddc; + void __iomem *hdmicore_regs;