aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch56
1 files changed, 56 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch b/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch
new file mode 100644
index 0000000000..d42f61d2e4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch
@@ -0,0 +1,56 @@
+From 7776a876ce7a6eeda164aebacc965116821d3095 Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Wed, 3 Jun 2020 12:20:19 +0100
+Subject: [PATCH] vc4: cec: Restore cec physical address on reconnect
+
+Currently we call cec_phys_addr_invalidate on a hotplug deassert.
+That may be due to a TV power cycling, or an AVR being switched
+on (and switching edid). This makes CEC unusable.
+
+Set it back up again on the hotplug assert.
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -113,20 +113,29 @@ static enum drm_connector_status
+ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
+ {
+ struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
++ bool connected = false;
+
+ if (vc4_hdmi->hpd_gpio) {
+ if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
+ vc4_hdmi->hpd_active_low)
+- return connector_status_connected;
+- cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
+- return connector_status_disconnected;
+- }
+-
+- if (drm_probe_ddc(vc4_hdmi->ddc))
+- return connector_status_connected;
+-
++ connected = true;
++ } else if (drm_probe_ddc(vc4_hdmi->ddc))
++ connected = true;
+ if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
++ connected = true;
++ if (connected) {
++ if (connector->status != connector_status_connected) {
++ struct edid *edid = drm_get_edid(connector, vc4_hdmi->ddc);
++
++ if (edid) {
++ cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid);
++ vc4_hdmi->encoder.hdmi_monitor = drm_detect_hdmi_monitor(edid);
++ drm_connector_update_edid_property(connector, edid);
++ kfree(edid);
++ }
++ }
+ return connector_status_connected;
++ }
+ cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
+ return connector_status_disconnected;
+ }