From: Dom Cobley popcornmix@gmail.com
[ Upstream commit 4d8602b8ec16f5721a4d1339c610a81f95df1856 ]
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 since our controller wouldn't have a physical address anymore.
Set it back up again on the hotplug assert.
Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support") Signed-off-by: Dom Cobley popcornmix@gmail.com Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Dave Stevenson dave.stevenson@raspberrypi.com Acked-by: Hans Verkuil hverkuil-cisco@xs4all.nl Tested-by: Hans Verkuil hverkuil-cisco@xs4all.nl Link: https://patchwork.freedesktop.org/patch/msgid/20210111142309.193441-6-maxime... (cherry picked from commit b06eecb5158e5f3eb47b9d05aea8c259985cc5f7) Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 3d473638dbe18..a9a6552bdae93 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -123,20 +123,32 @@ 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; + connected = true; + } else if (drm_probe_ddc(vc4_hdmi->ddc)) { + connected = true; + } else if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) { + connected = true; }
- if (drm_probe_ddc(vc4_hdmi->ddc)) - return connector_status_connected; + 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); + kfree(edid); + } + }
- if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) return connector_status_connected; + } + cec_phys_addr_invalidate(vc4_hdmi->cec_adap); return connector_status_disconnected; }