Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/bridge: dw-hdmi-qp: Add support for missing HPD

Add support for the dw-hdmi-qp driver to handle devices with missing
HPD pins.

Since in this situation we are now polling for the EDID data via i2c
change the error message to a rate limited debug message when we are
unable to complete an i2c read, as a disconnected device would
otherwise fill dmesg with i2c read errors.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20251119225526.70588-3-macroalpha82@gmail.com

authored by

Chris Morgan and committed by
Heiko Stuebner
bafb6863 db04f0d4

+30 -4
+30 -4
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
··· 165 165 struct regmap *regm; 166 166 167 167 unsigned long tmds_char_rate; 168 + bool no_hpd; 168 169 }; 169 170 170 171 static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val, ··· 556 555 557 556 stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); 558 557 if (!stat) { 559 - dev_err(hdmi->dev, "i2c read timed out\n"); 558 + if (hdmi->no_hpd) 559 + dev_dbg_ratelimited(hdmi->dev, 560 + "i2c read timed out\n"); 561 + else 562 + dev_err(hdmi->dev, "i2c read timed out\n"); 560 563 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); 561 564 return -EAGAIN; 562 565 } 563 566 564 567 /* Check for error condition on the bus */ 565 568 if (i2c->stat & I2CM_NACK_RCVD_IRQ) { 566 - dev_err(hdmi->dev, "i2c read error\n"); 569 + if (hdmi->no_hpd) 570 + dev_dbg_ratelimited(hdmi->dev, 571 + "i2c read error\n"); 572 + else 573 + dev_err(hdmi->dev, "i2c read error\n"); 567 574 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); 568 575 return -EIO; 569 576 } ··· 909 900 dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector) 910 901 { 911 902 struct dw_hdmi_qp *hdmi = bridge->driver_private; 903 + const struct drm_edid *drm_edid; 904 + 905 + if (hdmi->no_hpd) { 906 + drm_edid = drm_edid_read_ddc(connector, bridge->ddc); 907 + if (drm_edid) 908 + return connector_status_connected; 909 + else 910 + return connector_status_disconnected; 911 + } 912 912 913 913 return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); 914 914 } ··· 943 925 { 944 926 struct dw_hdmi_qp *hdmi = bridge->driver_private; 945 927 928 + /* 929 + * TODO: when hdmi->no_hpd is 1 we must not support modes that 930 + * require scrambling, including every mode with a clock above 931 + * HDMI14_MAX_TMDSCLK. 932 + */ 946 933 if (rate > HDMI14_MAX_TMDSCLK) { 947 934 dev_dbg(hdmi->dev, "Unsupported TMDS char rate: %lld\n", rate); 948 935 return MODE_CLOCK_HIGH; ··· 1300 1277 if (ret) 1301 1278 return ERR_PTR(ret); 1302 1279 1280 + hdmi->no_hpd = device_property_read_bool(dev, "no-hpd"); 1281 + 1303 1282 hdmi->bridge.driver_private = hdmi; 1304 1283 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | 1305 1284 DRM_BRIDGE_OP_EDID | 1306 1285 DRM_BRIDGE_OP_HDMI | 1307 - DRM_BRIDGE_OP_HDMI_AUDIO | 1308 - DRM_BRIDGE_OP_HPD; 1286 + DRM_BRIDGE_OP_HDMI_AUDIO; 1287 + if (!hdmi->no_hpd) 1288 + hdmi->bridge.ops |= DRM_BRIDGE_OP_HPD; 1309 1289 hdmi->bridge.of_node = pdev->dev.of_node; 1310 1290 hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 1311 1291 hdmi->bridge.vendor = "Synopsys";