On DisplayPort and eDP connectors DDC is tunneled over the AUX channel,
but amdgpu_dm registers the physical i2c bus ("AMDGPU DM i2c hw bus N")
as the connector's ddc adapter. The "ddc" sysfs symlink therefore points
at a bus that does not reach the sink, while the AUX backed adapter
("AMDGPU DM aux hw bus N"), which is registered as a child of the
connector, does. Userspace such as fwupd, which uses the "ddc" link for
DDC/CI, has to work around this.
Pass the AUX ddc adapter to drm_connector_init_with_ddc() for DP and eDP
connectors. The adapter is registered in late_register, before the core
creates the "ddc" link, so the link resolves correctly. Other connector
types keep using the physical i2c bus.
Reported-by: [email protected]
Closes: https://github.com/fwupd/fwupd/pull/11308
Signed-off-by: Mario Limonciello <[email protected]>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
index b498fc5fbb140..656249dc3f69b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
@@ -3483,6 +3483,7 @@ int amdgpu_dm_connector_init(struct
amdgpu_display_manager *dm,
struct dc *dc = dm->dc;
struct dc_link *link = dc_get_link_at_index(dc, link_index);
struct amdgpu_i2c_adapter *i2c;
+ struct i2c_adapter *ddc;
/* Not needed for writeback connector */
link->priv = aconnector;
@@ -3504,12 +3505,24 @@ int amdgpu_dm_connector_init(struct
amdgpu_display_manager *dm,
connector_type = to_drm_connector_type(link->connector_signal,
link->link_id.id);
+ /*
+ * On DisplayPort DDC is tunneled over the AUX channel, so expose the
+ * AUX backed i2c adapter (registered in late_register) as the
+ * connector's "ddc" sysfs link. The physical i2c bus doesn't reach
+ * the sink.
+ */
+ if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
+ connector_type == DRM_MODE_CONNECTOR_eDP)
+ ddc = &aconnector->dm_dp_aux.aux.ddc;
+ else
+ ddc = &i2c->base;
+
res = drm_connector_init_with_ddc(
dm->ddev,
&aconnector->base,
&amdgpu_dm_connector_funcs,
connector_type,
- &i2c->base);
+ ddc);
if (res) {
drm_err(adev_to_drm(dm->adev), "connector_init failed\n");
---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261102-superm1-amdgpu-ddc-63f0eb10c022
Best regards,
--
Mario Limonciello <[email protected]>