From: Priit Laes
Even though HDMI connector features hotplug detect pin (HPD), there
are older devices which do not support it. For these devices fall
back to additional check on I2C bus to probe for EDID data.
One known example is HDMI/DVI display with following edid:
$ xxd -p display.edid
000005a1e0030100150f0103800f05780a0f6ea05748
9a2610474f20010101010101010101010101010101012a08804520e0
0b10200040009536001800fd0034441a2403000a202020202020
001000310a202020202020202020202000102a4030701300
782d111e006b
$ edid-decode display.edid
EDID version: 1.3
Manufacturer: AMA Model 3e0 Serial Number 1
Digital display
Maximum image size: 15 cm x 5 cm
Gamma: 2.20
RGB color display
First detailed timing is preferred timing
Display x,y Chromaticity:
Red: 0.6250, 0.3398
Green: 0.2841, 0.6044
Blue: 0.1494, 0.0644
White: 0.2802, 0.3105
Established timings supported:
640x480@60Hz 4:3 HorFreq: 31469 Hz Clock: 25.175 MHz
Standard timings supported:
Detailed mode: Clock 20.900 MHz, 149 mm x 54 mm
640 672 672 709 hborder 0
480 484 484 491 vborder 0
-hsync -vsync
VertFreq: 60 Hz, HorFreq: 29478 Hz
Monitor ranges (GTF): 52-68Hz V, 26-36kHz H, max dotclock 30MHz
Dummy block
Dummy block
Checksum: 0x6b (valid)
Now, current implementation is still flawed, as HDMI uses the
HPD signal to indicate that the source should re-read the EDID
due to change in device capabilities. With current HPD polling
implementation we would most certainly miss those notifications
as one can try just swapping two HDMI monitors really fast.
Proper fix would be skipping the HPD pin detection and relying
on just EDID fetching and acting on its changes.
CC: Russell King
Signed-off-by: Priit Laes
---
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 20
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 416da5376701..44d5d50b7ada 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -242,14 +242,18 @@ sun4i_hdmi_connector_detect(struct drm_connector
*connector, bool force)
struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
unsigned long reg;
- if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_HPD_REG, reg,
- reg & SUN4I_HDMI_HPD_HIGH,
- 0, 50)) {
- cec_phys_addr_invalidate(hdmi->cec_adap);
- return connector_status_disconnected;
- }
-
- return connector_status_connected;
+ /* TODO: Drop HPD polling and instead keep track of EDID changes */
+ if (!readl_poll_timeout(hdmi->base + SUN4I_HDMI_HPD_REG, reg,
+ reg & SUN4I_HDMI_HPD_HIGH,
+ 0, 50))
+ return connector_status_connected;
+
+ /* Fall back to EDID in case display does not support HPD */
+ if (!IS_ERR(hdmi->i2c) && drm_probe_ddc(hdmi->i2c))
+ return connector_status_connected;
+
+ cec_phys_addr_invalidate(hdmi->cec_adap);
+ return connector_status_disconnected;
}
static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
--
2.11.0
--
You received this message because you are subscribed to the Google Groups
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.