amd-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/20] Analog connector support in DC
@ 2025-07-23 15:57 Timur Kristóf
  2025-07-23 15:57 ` [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately Timur Kristóf
                   ` (20 more replies)
  0 siblings, 21 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:57 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

This series adds support for analog connectors to DC for DCE6-10.
There are two reasons to add this support:

1. GPUs that already use DC by default and have analog connectors.
Some Tonga and Hawaii graphics cards in fact have DVI-I connectors,
and the analog part doesn't work by default. This functionality
regressed when switching from the amdgpu legacy display code to DC.

2. GPUs that don't use amdgpu by default yet.
Currently, SI (GFX6) and CIK (GFX7) don't use amdgpu by default
yet, and missing analog connector support is cited as one of the
main reasons why not.

With this analog support added to DC, we could already fully switch
CIK discrete GPUs to use DC and switch them to the amdgpu driver.
For GFX7 APUs and SI, further fixes are needed before enabling DC.

Before starting this work, I asked Harry and Alex about how best
to do it and we agreed that we'd like to use the VBIOS to set up
the DAC. So I used the amdgpu legacy display code as a reference.
The first few commits add some minor changes to DC to prepare for
supporting analog stream and link encoders, then analog link
detection is added along with polling, and finally DAC load
detection support, which is useful for old displays and adapters.

Please let me know what you think.

Timur Kristóf (20):
  drm/amd/display: Determine DRM connector type more accurately
  drm/amd/display: Add analog bit to edid_caps
  drm/amd/display: Introduce MAX_LINK_ENCODERS
  drm/amd/display: Hook up DAC to bios_parser_encoder_control
  drm/amd/display: Add SelectCRTC_Source to BIOS parser
  drm/amd/display: Get maximum pixel clock from VBIOS
  drm/amd/display: Don't use stereo sync and audio on RGB signals
  drm/amd/display: Don't try to enable/disable HPD when unavailable
  drm/amd/display: Add concept of analog encoders
  drm/amd/display: Implement DCE analog stream encoders
  drm/amd/display: Implement DCE analog link encoders
  drm/amd/display: Support DAC in dce110_hwseq
  drm/amd/display: Add analog link detection
  drm/amd/display: Poll analog connectors
  drm/amd/display: Add DCE BIOS_SCRATCH_0 register
  drm/amd/display: Make get_support_mask_for_device_id reusable
  drm/amd/display: Add DAC_LoadDetection to BIOS parser
  drm/amd/display: Use DAC load detection on analog connectors
  drm/amd/display: Add common modes to analog displays without EDID
  drm/amdgpu: Use DC by default for Bonaire

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |   1 -
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 144 +++++++--
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |   5 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |   1 +
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |   8 +
 .../gpu/drm/amd/display/dc/bios/bios_parser.c |  95 +++++-
 .../drm/amd/display/dc/bios/command_table.c   | 286 ++++++++++++++++++
 .../drm/amd/display/dc/bios/command_table.h   |   6 +
 .../drm/amd/display/dc/core/dc_link_enc_cfg.c |   4 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |   8 +
 .../gpu/drm/amd/display/dc/dc_bios_types.h    |   9 +
 drivers/gpu/drm/amd/display/dc/dc_types.h     |   5 +
 .../drm/amd/display/dc/dce/dce_link_encoder.c | 100 ++++++
 .../drm/amd/display/dc/dce/dce_link_encoder.h |  21 +-
 .../amd/display/dc/dce/dce_stream_encoder.c   |  14 +
 .../amd/display/dc/dce/dce_stream_encoder.h   |   5 +
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  75 ++++-
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   8 +-
 .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h |  24 ++
 .../drm/amd/display/dc/inc/hw/link_encoder.h  |   2 +
 drivers/gpu/drm/amd/display/dc/inc/resource.h |   1 +
 .../amd/display/dc/link/hwss/link_hwss_dio.c  |  19 +-
 .../drm/amd/display/dc/link/link_detection.c  | 123 +++++++-
 .../gpu/drm/amd/display/dc/link/link_dpms.c   |   9 +-
 .../drm/amd/display/dc/link/link_factory.c    |  31 ++
 .../dc/resource/dce100/dce100_resource.c      |  28 +-
 .../dc/resource/dce110/dce110_resource.c      |   2 +
 .../dc/resource/dce112/dce112_resource.c      |   2 +
 .../dc/resource/dce120/dce120_resource.c      |   1 +
 .../dc/resource/dce60/dce60_resource.c        |  26 +-
 .../dc/resource/dce80/dce80_resource.c        |  23 +-
 .../amd/display/include/bios_parser_types.h   |  11 +-
 .../display/include/grph_object_ctrl_defs.h   |   1 +
 .../drm/amd/display/include/signal_types.h    |   5 +
 34 files changed, 1027 insertions(+), 76 deletions(-)

-- 
2.50.1


^ permalink raw reply	[flat|nested] 61+ messages in thread

* [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
@ 2025-07-23 15:57 ` Timur Kristóf
  2025-07-29 18:03   ` Harry Wentland
  2025-08-06 14:56   ` Harry Wentland
  2025-07-23 15:57 ` [PATCH 02/20] drm/amd/display: Add analog bit to edid_caps Timur Kristóf
                   ` (19 subsequent siblings)
  20 siblings, 2 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:57 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

Previously, DC determined the DRM connector type based on the
signal type, which becomes problematic when a connector may
support different signal types, such as DVI-I.

With this patch, it is now determined according to the actual
connector type in DC, meaning it can now distinguish between
DVI-D and DVI-I connectors.

A subsequent commit will enable polling for these connectors.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++--------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 096b23ad4845..c347b232ae06 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8038,24 +8038,26 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
 	return 0;
 }
 
-static int to_drm_connector_type(enum signal_type st)
+static int to_drm_connector_type(uint32_t connector_id)
 {
-	switch (st) {
-	case SIGNAL_TYPE_HDMI_TYPE_A:
+	switch (connector_id) {
+	case CONNECTOR_ID_HDMI_TYPE_A:
 		return DRM_MODE_CONNECTOR_HDMIA;
-	case SIGNAL_TYPE_EDP:
+	case CONNECTOR_ID_EDP:
 		return DRM_MODE_CONNECTOR_eDP;
-	case SIGNAL_TYPE_LVDS:
+	case CONNECTOR_ID_LVDS:
 		return DRM_MODE_CONNECTOR_LVDS;
-	case SIGNAL_TYPE_RGB:
+	case CONNECTOR_ID_VGA:
 		return DRM_MODE_CONNECTOR_VGA;
-	case SIGNAL_TYPE_DISPLAY_PORT:
-	case SIGNAL_TYPE_DISPLAY_PORT_MST:
+	case CONNECTOR_ID_DISPLAY_PORT:
 		return DRM_MODE_CONNECTOR_DisplayPort;
-	case SIGNAL_TYPE_DVI_DUAL_LINK:
-	case SIGNAL_TYPE_DVI_SINGLE_LINK:
+	case CONNECTOR_ID_SINGLE_LINK_DVID:
+	case CONNECTOR_ID_DUAL_LINK_DVID:
 		return DRM_MODE_CONNECTOR_DVID;
-	case SIGNAL_TYPE_VIRTUAL:
+	case CONNECTOR_ID_SINGLE_LINK_DVII:
+	case CONNECTOR_ID_DUAL_LINK_DVII:
+		return DRM_MODE_CONNECTOR_DVII;
+	case CONNECTOR_ID_VIRTUAL:
 		return DRM_MODE_CONNECTOR_VIRTUAL;
 
 	default:
@@ -8440,6 +8442,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 			link->link_enc->features.dp_ycbcr420_supported ? true : false;
 		break;
 	case DRM_MODE_CONNECTOR_DVID:
+	case DRM_MODE_CONNECTOR_DVII:
+	case DRM_MODE_CONNECTOR_VGA:
 		aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
 		break;
 	default:
@@ -8631,7 +8635,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
 		goto out_free;
 	}
 
-	connector_type = to_drm_connector_type(link->connector_signal);
+	connector_type = to_drm_connector_type(link->link_id.id);
 
 	res = drm_connector_init_with_ddc(
 			dm->ddev,
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 02/20] drm/amd/display: Add analog bit to edid_caps
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
  2025-07-23 15:57 ` [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately Timur Kristóf
@ 2025-07-23 15:57 ` Timur Kristóf
  2025-07-23 15:57 ` [PATCH 03/20] drm/amd/display: Introduce MAX_LINK_ENCODERS Timur Kristóf
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:57 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

The new analog bit will be used with DVI-I connectors.

DVI-I connectors can connect to both digital and analog monitors
and this bit will help distinguish between those.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 1 +
 drivers/gpu/drm/amd/display/dc/dc_types.h                 | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 9e3e51a2dc49..95c00af04d77 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -129,6 +129,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
 	edid_caps->serial_number = edid_buf->serial;
 	edid_caps->manufacture_week = edid_buf->mfg_week;
 	edid_caps->manufacture_year = edid_buf->mfg_year;
+	edid_caps->analog = !(edid_buf->input & DRM_EDID_INPUT_DIGITAL);
 
 	drm_edid_get_monitor_name(edid_buf,
 				  edid_caps->display_name,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 375ca2f13b7a..10de0930adaa 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -185,6 +185,10 @@ struct dc_panel_patch {
 	unsigned int wait_after_dpcd_poweroff_ms;
 };
 
+/**
+ * struct dc_edid_caps - Capabilities read from EDID.
+ * @analog: Whether the monitor is analog. Used by DVI-I handling.
+ */
 struct dc_edid_caps {
 	/* sink identification */
 	uint16_t manufacturer_id;
@@ -212,6 +216,7 @@ struct dc_edid_caps {
 	bool edid_hdmi;
 	bool hdr_supported;
 	bool rr_capable;
+	bool analog;
 
 	struct dc_panel_patch panel_patch;
 };
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 03/20] drm/amd/display: Introduce MAX_LINK_ENCODERS
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
  2025-07-23 15:57 ` [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately Timur Kristóf
  2025-07-23 15:57 ` [PATCH 02/20] drm/amd/display: Add analog bit to edid_caps Timur Kristóf
@ 2025-07-23 15:57 ` Timur Kristóf
  2025-07-29 18:06   ` Harry Wentland
  2025-07-23 15:57 ` [PATCH 04/20] drm/amd/display: Hook up DAC to bios_parser_encoder_control Timur Kristóf
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:57 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

We are going to support analog encoders as well, not just digital,
so we need to make space for them in various arrays.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../drm/amd/display/dc/core/dc_link_enc_cfg.c |  4 ++--
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  8 +++----
 .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 24 +++++++++++++++++++
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
index 814f68d76257..d86482611b3f 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
@@ -522,10 +522,10 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
 struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc)
 {
 	struct link_encoder *link_enc = NULL;
-	enum engine_id encs_assigned[MAX_DIG_LINK_ENCODERS];
+	enum engine_id encs_assigned[MAX_LINK_ENCODERS];
 	int i;
 
-	for (i = 0; i < MAX_DIG_LINK_ENCODERS; i++)
+	for (i = 0; i < MAX_LINK_ENCODERS; i++)
 		encs_assigned[i] = ENGINE_ID_UNKNOWN;
 
 	/* Add assigned encoders to list. */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index f0d7185153b2..55daf348293e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -274,7 +274,7 @@ struct resource_pool {
 	/* An array for accessing the link encoder objects that have been created.
 	 * Index in array corresponds to engine ID - viz. 0: ENGINE_ID_DIGA
 	 */
-	struct link_encoder *link_encoders[MAX_DIG_LINK_ENCODERS];
+	struct link_encoder *link_encoders[MAX_LINK_ENCODERS];
 	/* Number of DIG link encoder objects created - i.e. number of valid
 	 * entries in link_encoders array.
 	 */
@@ -508,7 +508,7 @@ struct pipe_ctx {
 struct link_enc_cfg_context {
 	enum link_enc_cfg_mode mode;
 	struct link_enc_assignment link_enc_assignments[MAX_PIPES];
-	enum engine_id link_enc_avail[MAX_DIG_LINK_ENCODERS];
+	enum engine_id link_enc_avail[MAX_LINK_ENCODERS];
 	struct link_enc_assignment transient_assignments[MAX_PIPES];
 };
 
@@ -520,8 +520,8 @@ struct resource_context {
 	uint8_t dp_clock_source_ref_count;
 	bool is_dsc_acquired[MAX_PIPES];
 	struct link_enc_cfg_context link_enc_cfg_ctx;
-	unsigned int dio_link_enc_to_link_idx[MAX_DIG_LINK_ENCODERS];
-	int dio_link_enc_ref_cnts[MAX_DIG_LINK_ENCODERS];
+	unsigned int dio_link_enc_to_link_idx[MAX_LINK_ENCODERS];
+	int dio_link_enc_ref_cnts[MAX_LINK_ENCODERS];
 	bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS];
 	unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS];
 	int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS];
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index 41c76ba9ba56..dc9b9f22c75b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -45,7 +45,31 @@
 #define MAX_PIPES 6
 #define MAX_PHANTOM_PIPES (MAX_PIPES / 2)
 #define MAX_LINKS (MAX_PIPES * 2 +2)
+
+/**
+ * define MAX_DIG_LINK_ENCODERS - maximum number of digital encoders
+ *
+ * Digital encoders are ENGINE_ID_DIGA...G, there are at most 7,
+ * although not every GPU may have that many.
+ */
 #define MAX_DIG_LINK_ENCODERS 7
+
+/**
+ * define MAX_DIG_LINK_ENCODERS - maximum number of analog link encoders
+ *
+ * Analog encoders are ENGINE_ID_DACA/B, there are at most 2,
+ * although not every GPU may have that many. Modern GPUs typically
+ * don't have analog encoders.
+ */
+#define MAX_DAC_LINK_ENCODERS 2
+
+/**
+ * define MAX_LINK_ENCODERS - maximum number link encoders in total
+ *
+ * This includes both analog and digital encoders.
+ */
+#define MAX_LINK_ENCODERS (MAX_DIG_LINK_ENCODERS + MAX_DAC_LINK_ENCODERS)
+
 #define MAX_DWB_PIPES	1
 #define MAX_HPO_DP2_ENCODERS	4
 #define MAX_HPO_DP2_LINK_ENCODERS	4
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 04/20] drm/amd/display: Hook up DAC to bios_parser_encoder_control
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (2 preceding siblings ...)
  2025-07-23 15:57 ` [PATCH 03/20] drm/amd/display: Introduce MAX_LINK_ENCODERS Timur Kristóf
@ 2025-07-23 15:57 ` Timur Kristóf
  2025-07-23 15:57 ` [PATCH 05/20] drm/amd/display: Add SelectCRTC_Source to BIOS parser Timur Kristóf
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:57 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

The BIOS parser already supports calling the DAC1EncoderControl
function from the VBIOS, but it was not exposed anywhere.
This commit enables the codebase to use encoder_control()
when the encoder engine is one of the DACs.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../gpu/drm/amd/display/dc/bios/bios_parser.c    | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
index 67f08495b7e6..6914dd6944b7 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -745,6 +745,22 @@ static enum bp_result bios_parser_encoder_control(
 {
 	struct bios_parser *bp = BP_FROM_DCB(dcb);
 
+	if (cntl->engine_id == ENGINE_ID_DACA) {
+		if (!bp->cmd_tbl.dac1_encoder_control)
+			return BP_RESULT_FAILURE;
+
+		return bp->cmd_tbl.dac1_encoder_control(
+			bp, cntl->action == ENCODER_CONTROL_ENABLE,
+			cntl->pixel_clock, ATOM_DAC1_PS2);
+	} else if (cntl->engine_id == ENGINE_ID_DACB) {
+		if (!bp->cmd_tbl.dac2_encoder_control)
+			return BP_RESULT_FAILURE;
+
+		return bp->cmd_tbl.dac2_encoder_control(
+			bp, cntl->action == ENCODER_CONTROL_ENABLE,
+			cntl->pixel_clock, ATOM_DAC1_PS2);
+	}
+
 	if (!bp->cmd_tbl.dig_encoder_control)
 		return BP_RESULT_FAILURE;
 
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 05/20] drm/amd/display: Add SelectCRTC_Source to BIOS parser
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (3 preceding siblings ...)
  2025-07-23 15:57 ` [PATCH 04/20] drm/amd/display: Hook up DAC to bios_parser_encoder_control Timur Kristóf
@ 2025-07-23 15:57 ` Timur Kristóf
  2025-07-23 15:57 ` [PATCH 06/20] drm/amd/display: Get maximum pixel clock from VBIOS Timur Kristóf
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:57 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

The SelectCRTC_Source command will be used to change which CRTC
should be connected to which encoder.

To implement this, I used the legacy display code as reference:
amdgpu_atombios_encoder_set_crtc_source

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../gpu/drm/amd/display/dc/bios/bios_parser.c |  14 ++
 .../drm/amd/display/dc/bios/command_table.c   | 194 ++++++++++++++++++
 .../drm/amd/display/dc/bios/command_table.h   |   3 +
 .../gpu/drm/amd/display/dc/dc_bios_types.h    |   3 +
 .../amd/display/include/bios_parser_types.h   |   6 +-
 5 files changed, 215 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
index 6914dd6944b7..bfacfd2a5376 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -739,6 +739,18 @@ static enum bp_result bios_parser_transmitter_control(
 	return bp->cmd_tbl.transmitter_control(bp, cntl);
 }
 
+static enum bp_result bios_parser_select_crtc_source(
+	struct dc_bios *dcb,
+	struct bp_crtc_source_select *bp_params)
+{
+	struct bios_parser *bp = BP_FROM_DCB(dcb);
+
+	if (!bp->cmd_tbl.select_crtc_source)
+		return BP_RESULT_FAILURE;
+
+	return bp->cmd_tbl.select_crtc_source(bp, bp_params);
+}
+
 static enum bp_result bios_parser_encoder_control(
 	struct dc_bios *dcb,
 	struct bp_encoder_control *cntl)
@@ -2848,6 +2860,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
 	.is_device_id_supported = bios_parser_is_device_id_supported,
 
 	/* COMMANDS */
+	.select_crtc_source = bios_parser_select_crtc_source,
+
 	.encoder_control = bios_parser_encoder_control,
 
 	.transmitter_control = bios_parser_transmitter_control,
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
index 2bcae0643e61..8983220d2a4b 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
@@ -52,6 +52,7 @@ static void init_transmitter_control(struct bios_parser *bp);
 static void init_set_pixel_clock(struct bios_parser *bp);
 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
 static void init_adjust_display_pll(struct bios_parser *bp);
+static void init_select_crtc_source(struct bios_parser *bp);
 static void init_dac_encoder_control(struct bios_parser *bp);
 static void init_dac_output_control(struct bios_parser *bp);
 static void init_set_crtc_timing(struct bios_parser *bp);
@@ -69,6 +70,7 @@ void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
 	init_set_pixel_clock(bp);
 	init_enable_spread_spectrum_on_ppll(bp);
 	init_adjust_display_pll(bp);
+	init_select_crtc_source(bp);
 	init_dac_encoder_control(bp);
 	init_dac_output_control(bp);
 	init_set_crtc_timing(bp);
@@ -1609,6 +1611,198 @@ static enum bp_result adjust_display_pll_v3(
 	return result;
 }
 
+/*******************************************************************************
+ ********************************************************************************
+ **
+ **                  SELECT CRTC SOURCE
+ **
+ ********************************************************************************
+ *******************************************************************************/
+
+static enum bp_result select_crtc_source_v1(
+	struct bios_parser *bp,
+	struct bp_crtc_source_select *bp_params);
+static enum bp_result select_crtc_source_v2(
+	struct bios_parser *bp,
+	struct bp_crtc_source_select *bp_params);
+static enum bp_result select_crtc_source_v3(
+	struct bios_parser *bp,
+	struct bp_crtc_source_select *bp_params);
+
+static void init_select_crtc_source(struct bios_parser *bp)
+{
+	switch (BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source)) {
+	case 1:
+		bp->cmd_tbl.select_crtc_source = select_crtc_source_v1;
+		break;
+	case 2:
+		bp->cmd_tbl.select_crtc_source = select_crtc_source_v2;
+		break;
+	case 3:
+		bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
+		break;
+	default:
+		bp->cmd_tbl.select_crtc_source = NULL;
+		break;
+	}
+}
+
+static enum bp_result select_crtc_source_v1(
+	struct bios_parser *bp,
+	struct bp_crtc_source_select *bp_params)
+{
+	enum bp_result result = BP_RESULT_FAILURE;
+	SELECT_CRTC_SOURCE_PS_ALLOCATION params;
+
+	if (!bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &params.ucCRTC))
+		return BP_RESULT_BADINPUT;
+
+	switch (bp_params->engine_id) {
+	case ENGINE_ID_DACA:
+		params.ucDevice = ATOM_DEVICE_CRT1_INDEX;
+		break;
+	case ENGINE_ID_DACB:
+		params.ucDevice = ATOM_DEVICE_CRT2_INDEX;
+		break;
+	default:
+		return BP_RESULT_BADINPUT;
+	}
+
+	if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
+		result = BP_RESULT_OK;
+
+	return result;
+}
+
+static bool select_crtc_source_v2_encoder_id(
+	enum engine_id engine_id, uint8_t *out_encoder_id)
+{
+	uint8_t encoder_id = 0;
+
+	switch (engine_id) {
+	case ENGINE_ID_DIGA:
+		encoder_id = ASIC_INT_DIG1_ENCODER_ID;
+		break;
+	case ENGINE_ID_DIGB:
+		encoder_id = ASIC_INT_DIG2_ENCODER_ID;
+		break;
+	case ENGINE_ID_DIGC:
+		encoder_id = ASIC_INT_DIG3_ENCODER_ID;
+		break;
+	case ENGINE_ID_DIGD:
+		encoder_id = ASIC_INT_DIG4_ENCODER_ID;
+		break;
+	case ENGINE_ID_DIGE:
+		encoder_id = ASIC_INT_DIG5_ENCODER_ID;
+		break;
+	case ENGINE_ID_DIGF:
+		encoder_id = ASIC_INT_DIG6_ENCODER_ID;
+		break;
+	case ENGINE_ID_DIGG:
+		encoder_id = ASIC_INT_DIG7_ENCODER_ID;
+		break;
+	case ENGINE_ID_DACA:
+		encoder_id = ASIC_INT_DAC1_ENCODER_ID;
+		break;
+	case ENGINE_ID_DACB:
+		encoder_id = ASIC_INT_DAC2_ENCODER_ID;
+		break;
+	default:
+		return false;
+	}
+
+	*out_encoder_id = encoder_id;
+	return true;
+}
+
+static bool select_crtc_source_v2_encoder_mode(
+	enum signal_type signal_type, uint8_t *out_encoder_mode)
+{
+	uint8_t encoder_mode = 0;
+
+	switch (signal_type) {
+	case SIGNAL_TYPE_DVI_SINGLE_LINK:
+	case SIGNAL_TYPE_DVI_DUAL_LINK:
+		encoder_mode = ATOM_ENCODER_MODE_DVI;
+		break;
+	case SIGNAL_TYPE_HDMI_TYPE_A:
+		encoder_mode = ATOM_ENCODER_MODE_HDMI;
+		break;
+	case SIGNAL_TYPE_LVDS:
+		encoder_mode = ATOM_ENCODER_MODE_LVDS;
+		break;
+	case SIGNAL_TYPE_RGB:
+		encoder_mode = ATOM_ENCODER_MODE_CRT;
+		break;
+	case SIGNAL_TYPE_DISPLAY_PORT:
+		encoder_mode = ATOM_ENCODER_MODE_DP;
+		break;
+	case SIGNAL_TYPE_DISPLAY_PORT_MST:
+		encoder_mode = ATOM_ENCODER_MODE_DP_MST;
+		break;
+	case SIGNAL_TYPE_EDP:
+		encoder_mode = ATOM_ENCODER_MODE_DP;
+		break;
+	default:
+		return false;
+	}
+
+	*out_encoder_mode = encoder_mode;
+	return true;
+}
+
+static enum bp_result select_crtc_source_v2(
+	struct bios_parser *bp,
+	struct bp_crtc_source_select *bp_params)
+{
+	enum bp_result result = BP_RESULT_FAILURE;
+	SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
+
+	if (!bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &params.ucCRTC))
+		return BP_RESULT_BADINPUT;
+
+	if (!select_crtc_source_v2_encoder_id(
+		bp_params->engine_id,
+		&params.ucEncoderID))
+		return BP_RESULT_BADINPUT;
+	if (!select_crtc_source_v2_encoder_mode(
+		bp_params->sink_signal,
+		&params.ucEncodeMode))
+		return BP_RESULT_BADINPUT;
+
+	if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
+		result = BP_RESULT_OK;
+
+	return result;
+}
+
+static enum bp_result select_crtc_source_v3(
+	struct bios_parser *bp,
+	struct bp_crtc_source_select *bp_params)
+{
+	enum bp_result result = BP_RESULT_FAILURE;
+	SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
+
+	if (!bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &params.ucCRTC))
+		return BP_RESULT_BADINPUT;
+
+	if (!select_crtc_source_v2_encoder_id(
+		bp_params->engine_id,
+		&params.ucEncoderID))
+		return BP_RESULT_BADINPUT;
+	if (!select_crtc_source_v2_encoder_mode(
+		bp_params->sink_signal,
+		&params.ucEncodeMode))
+		return BP_RESULT_BADINPUT;
+
+	params.ucDstBpc = bp_params->bit_depth;
+
+	if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
+		result = BP_RESULT_OK;
+
+	return result;
+}
+
 /*******************************************************************************
  ********************************************************************************
  **
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.h b/drivers/gpu/drm/amd/display/dc/bios/command_table.h
index ad533775e724..8b04b903e93d 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.h
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.h
@@ -52,6 +52,9 @@ struct cmd_tbl {
 	enum bp_result (*adjust_display_pll)(
 		struct bios_parser *bp,
 		struct bp_adjust_pixel_clock_parameters *bp_params);
+	enum bp_result (*select_crtc_source)(
+		struct bios_parser *bp,
+		struct bp_crtc_source_select *bp_params);
 	enum bp_result (*dac1_encoder_control)(
 		struct bios_parser *bp,
 		bool enable,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
index 5fa5e2b63fb7..545ce1e15eae 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
@@ -91,6 +91,9 @@ struct dc_vbios_funcs {
 		struct device_id id);
 	/* COMMANDS */
 
+	enum bp_result (*select_crtc_source)(
+		struct dc_bios *bios,
+		struct bp_crtc_source_select *bp_params);
 	enum bp_result (*encoder_control)(
 		struct dc_bios *bios,
 		struct bp_encoder_control *cntl);
diff --git a/drivers/gpu/drm/amd/display/include/bios_parser_types.h b/drivers/gpu/drm/amd/display/include/bios_parser_types.h
index 812377d9e48f..d9e58a6a0d36 100644
--- a/drivers/gpu/drm/amd/display/include/bios_parser_types.h
+++ b/drivers/gpu/drm/amd/display/include/bios_parser_types.h
@@ -135,12 +135,8 @@ struct bp_external_encoder_control {
 struct bp_crtc_source_select {
 	enum engine_id engine_id;
 	enum controller_id controller_id;
-	/* from GPU Tx aka asic_signal */
-	enum signal_type signal;
-	/* sink_signal may differ from asicSignal if Translator encoder */
 	enum signal_type sink_signal;
-	enum display_output_bit_depth display_output_bit_depth;
-	bool enable_dp_audio;
+	uint8_t bit_depth;
 };
 
 struct bp_transmitter_control {
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 06/20] drm/amd/display: Get maximum pixel clock from VBIOS
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (4 preceding siblings ...)
  2025-07-23 15:57 ` [PATCH 05/20] drm/amd/display: Add SelectCRTC_Source to BIOS parser Timur Kristóf
@ 2025-07-23 15:57 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals Timur Kristóf
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:57 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

We will use this for validating the pixel clock when
an analog monitor is connected to VGA or DVI-I connectors.

Reference in the legacy code:
amdgpu_connector_vga_mode_valid

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/display/dc/bios/bios_parser.c           | 2 ++
 drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
index bfacfd2a5376..bd61ed6cafab 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -444,6 +444,7 @@ static enum bp_result get_firmware_info_v1_4(
 		le32_to_cpu(firmware_info->ulMinPixelClockPLL_Output) * 10;
 	info->pll_info.max_output_pxl_clk_pll_frequency =
 		le32_to_cpu(firmware_info->ulMaxPixelClockPLL_Output) * 10;
+	info->max_pixel_clock = le16_to_cpu(firmware_info->usMaxPixelClock) * 10;
 
 	if (firmware_info->usFirmwareCapability.sbfAccess.MemoryClockSS_Support)
 		/* Since there is no information on the SS, report conservative
@@ -500,6 +501,7 @@ static enum bp_result get_firmware_info_v2_1(
 	info->external_clock_source_frequency_for_dp =
 		le16_to_cpu(firmwareInfo->usUniphyDPModeExtClkFreq) * 10;
 	info->min_allowed_bl_level = firmwareInfo->ucMinAllowedBL_Level;
+	info->max_pixel_clock = le16_to_cpu(firmwareInfo->usMaxPixelClock) * 10;
 
 	/* There should be only one entry in the SS info table for Memory Clock
 	 */
diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
index cc467031651d..38a77fa9b4af 100644
--- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
+++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
@@ -169,6 +169,7 @@ struct dc_firmware_info {
 		uint32_t engine_clk_ss_percentage;
 	} feature;
 
+	uint32_t max_pixel_clock; /* in KHz */
 	uint32_t default_display_engine_pll_frequency; /* in KHz */
 	uint32_t external_clock_source_frequency_for_dp; /* in KHz */
 	uint32_t smu_gpu_pll_output_freq; /* in KHz */
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (5 preceding siblings ...)
  2025-07-23 15:57 ` [PATCH 06/20] drm/amd/display: Get maximum pixel clock from VBIOS Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-29 18:21   ` Harry Wentland
  2025-07-23 15:58 ` [PATCH 08/20] drm/amd/display: Don't try to enable/disable HPD when unavailable Timur Kristóf
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

Features like stereo sync and audio are not supported by RGB
signals, so don't try to use them.

Also add a dc_is_rgb_signal similar to other dc_is_*_signal.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c | 3 ++-
 drivers/gpu/drm/amd/display/dc/link/link_dpms.c          | 6 ++++--
 drivers/gpu/drm/amd/display/include/signal_types.h       | 5 +++++
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
index b68bcc9fca0a..f3470716734d 100644
--- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
+++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
@@ -115,7 +115,8 @@ void setup_dio_stream_attribute(struct pipe_ctx *pipe_ctx)
 	struct dc_stream_state *stream = pipe_ctx->stream;
 	struct dc_link *link = stream->link;
 
-	if (!dc_is_virtual_signal(stream->signal))
+	if (!dc_is_virtual_signal(stream->signal) &&
+		!dc_is_rgb_signal(stream->signal))
 		stream_encoder->funcs->setup_stereo_sync(
 				stream_encoder,
 				pipe_ctx->stream_res.tg->inst,
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
index 8c8682f743d6..d6b7347c6c11 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
@@ -2369,7 +2369,8 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
 			set_avmute(pipe_ctx, true);
 	}
 
-	dc->hwss.disable_audio_stream(pipe_ctx);
+	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
+		dc->hwss.disable_audio_stream(pipe_ctx);
 
 	update_psp_stream_config(pipe_ctx, true);
 	dc->hwss.blank_stream(pipe_ctx);
@@ -2656,7 +2657,8 @@ void link_set_dpms_on(
 		enable_stream_features(pipe_ctx);
 	update_psp_stream_config(pipe_ctx, false);
 
-	dc->hwss.enable_audio_stream(pipe_ctx);
+	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
+		dc->hwss.enable_audio_stream(pipe_ctx);
 
 	if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
 		set_avmute(pipe_ctx, false);
diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h b/drivers/gpu/drm/amd/display/include/signal_types.h
index a10d6b988aab..825a08fcb125 100644
--- a/drivers/gpu/drm/amd/display/include/signal_types.h
+++ b/drivers/gpu/drm/amd/display/include/signal_types.h
@@ -118,6 +118,11 @@ static inline bool dc_is_dvi_signal(enum signal_type signal)
 	}
 }
 
+static inline bool dc_is_rgb_signal(enum signal_type signal)
+{
+	return (signal == SIGNAL_TYPE_RGB);
+}
+
 static inline bool dc_is_tmds_signal(enum signal_type signal)
 {
 	switch (signal) {
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 08/20] drm/amd/display: Don't try to enable/disable HPD when unavailable
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (6 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 09/20] drm/amd/display: Add concept of analog encoders Timur Kristóf
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

VGA connectors don't have HPD (hotplug detection), so don't
touch any HPD related registers for VGA.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index c7d13e743e6c..1bb8a9bc673b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -758,6 +758,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us
 	int max_param_num = 11;
 	enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
 	bool disable_hpd = false;
+	bool supports_hpd = link->irq_source_hpd != DC_IRQ_SOURCE_INVALID;
 	bool valid_test_pattern = false;
 	uint8_t param_nums = 0;
 	/* init with default 80bit custom pattern */
@@ -849,7 +850,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us
 	 * because it might have been disabled after a test pattern was set.
 	 * AUX depends on HPD * sequence dependent, do not move!
 	 */
-	if (!disable_hpd)
+	if (supports_hpd && !disable_hpd)
 		dc_link_enable_hpd(link);
 
 	prefer_link_settings.lane_count = link->verified_link_cap.lane_count;
@@ -887,7 +888,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us
 	 * Need disable interrupt to avoid SW driver disable DP output. This is
 	 * done after the test pattern is set.
 	 */
-	if (valid_test_pattern && disable_hpd)
+	if (valid_test_pattern && supports_hpd && disable_hpd)
 		dc_link_disable_hpd(link);
 
 	kfree(wr_buf);
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 09/20] drm/amd/display: Add concept of analog encoders
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (7 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 08/20] drm/amd/display: Don't try to enable/disable HPD when unavailable Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders Timur Kristóf
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

Add a num_analog_stream_encoders field to indicate how many
analog stream encoders are present. When analog stream encoders
are present, create them.

Additionally, add an analog_engine field to link encoders and
search for supported analog encoders in the BIOS for each link.
When connecting an RGB signal, search for analog stream encoders.

The actual DCE analog stream encoder support is going to be
added in a subsequent commit.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  8 ++++++
 .../drm/amd/display/dc/inc/hw/link_encoder.h  |  2 ++
 drivers/gpu/drm/amd/display/dc/inc/resource.h |  1 +
 .../drm/amd/display/dc/link/link_factory.c    | 28 +++++++++++++++++++
 .../dc/resource/dce100/dce100_resource.c      |  7 +++--
 5 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 4d6181e7c612..9561d0bd255a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -441,6 +441,14 @@ bool resource_construct(
 				DC_ERR("DC: failed to create stream_encoder!\n");
 			pool->stream_enc_count++;
 		}
+
+		for (i = 0; i < caps->num_analog_stream_encoder; i++) {
+			pool->stream_enc[caps->num_stream_encoder + i] =
+				create_funcs->create_stream_encoder(ENGINE_ID_DACA + i, ctx);
+			if (pool->stream_enc[caps->num_stream_encoder + i] == NULL)
+				DC_ERR("DC: failed to create analog stream_encoder %d!\n", i);
+			pool->stream_enc_count++;
+		}
 	}
 
 	pool->hpo_dp_stream_enc_count = 0;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 08c16ba52a51..df512920a9fa 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -47,6 +47,7 @@ struct encoder_init_data {
 	enum hpd_source_id hpd_source;
 	/* TODO: in DAL2, here was pointer to EventManagerInterface */
 	struct graphics_object_id encoder;
+	enum engine_id analog_engine;
 	struct dc_context *ctx;
 	enum transmitter transmitter;
 };
@@ -83,6 +84,7 @@ struct link_encoder {
 	struct graphics_object_id connector;
 	uint32_t output_signals;
 	enum engine_id preferred_engine;
+	enum engine_id analog_engine;
 	struct encoder_feature_support features;
 	enum transmitter transmitter;
 	enum hpd_source_id hpd_source;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index a890f581f4e8..9a10fbc93e5f 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -48,6 +48,7 @@ struct resource_caps {
 	int num_video_plane;
 	int num_audio;
 	int num_stream_encoder;
+	int num_analog_stream_encoder;
 	int num_pll;
 	int num_dwb;
 	int num_ddc;
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
index de1143dbbd25..71c10a1261b9 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
@@ -449,6 +449,32 @@ static enum channel_id get_ddc_line(struct dc_link *link)
 	return channel;
 }
 
+static enum engine_id find_analog_engine(struct dc_link *link)
+{
+	struct dc_bios *bp = link->ctx->dc_bios;
+	struct graphics_object_id encoder = {0};
+	enum bp_result bp_result = BP_RESULT_OK;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		bp_result = bp->funcs->get_src_obj(bp, link->link_id, i, &encoder);
+
+		if (bp_result != BP_RESULT_OK)
+			return ENGINE_ID_UNKNOWN;
+
+		switch (encoder.id) {
+		case ENCODER_ID_INTERNAL_DAC1:
+		case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
+			return ENGINE_ID_DACA;
+		case ENCODER_ID_INTERNAL_DAC2:
+		case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
+			return ENGINE_ID_DACB;
+		}
+	}
+
+	return ENGINE_ID_UNKNOWN;
+}
+
 static bool construct_phy(struct dc_link *link,
 			      const struct link_init_data *init_params)
 {
@@ -461,6 +487,7 @@ static bool construct_phy(struct dc_link *link,
 	const struct dc_vbios_funcs *bp_funcs = bios->funcs;
 	struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 };
 
+
 	DC_LOGGER_INIT(dc_ctx->logger);
 
 	link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
@@ -614,6 +641,7 @@ static bool construct_phy(struct dc_link *link,
 	enc_init_data.connector = link->link_id;
 	enc_init_data.channel = get_ddc_line(link);
 	enc_init_data.hpd_source = get_hpd_line(link);
+	enc_init_data.analog_engine = find_analog_engine(link);
 
 	link->hpd_src = enc_init_data.hpd_source;
 
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
index 3a51be63f020..72efb13c9027 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
@@ -935,6 +935,10 @@ struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link(
 	int i;
 	int j = -1;
 	struct dc_link *link = stream->link;
+	enum engine_id preferred_engine = link->link_enc->preferred_engine;
+
+	if (dc_is_rgb_signal(stream->signal))
+		preferred_engine = link->link_enc->analog_engine;
 
 	for (i = 0; i < pool->stream_enc_count; i++) {
 		if (!res_ctx->is_stream_enc_acquired[i] &&
@@ -943,8 +947,7 @@ struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link(
 			 * in daisy chain use case
 			 */
 			j = i;
-			if (pool->stream_enc[i]->id ==
-					link->link_enc->preferred_engine)
+			if (pool->stream_enc[i]->id == preferred_engine)
 				return pool->stream_enc[i];
 		}
 	}
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (8 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 09/20] drm/amd/display: Add concept of analog encoders Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-08-01 18:05   ` Alexandre Demers
  2025-08-01 18:06   ` Alexandre Demers
  2025-07-23 15:58 ` [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders Timur Kristóf
                   ` (10 subsequent siblings)
  20 siblings, 2 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

Add stream encoders for DCE6-10 only, because there are definitely
graphics cards with analog connectors out there with these DCE
versions. I am not aware of newer ones.

Considering that all stream encoder functions currently have to do
with digital streams, there is nothing for an analog stream
encoder to do, making them basically a no-op.
That being said, we still need some kind of stream encoder to
represent an analog stream, and it is beneficial to split them from
digital stream encoders in the code to make sure they don't
accidentally write any DIG* registers.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../drm/amd/display/dc/dce/dce_stream_encoder.c    | 14 ++++++++++++++
 .../drm/amd/display/dc/dce/dce_stream_encoder.h    |  5 +++++
 .../display/dc/resource/dce100/dce100_resource.c   |  6 ++++++
 .../amd/display/dc/resource/dce60/dce60_resource.c |  8 ++++++++
 .../amd/display/dc/resource/dce80/dce80_resource.c |  8 ++++++++
 5 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
index 1130d7619b26..f8996ee2856b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
@@ -1567,3 +1567,17 @@ void dce110_stream_encoder_construct(
 	enc110->se_shift = se_shift;
 	enc110->se_mask = se_mask;
 }
+
+static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {0};
+
+void dce110_analog_stream_encoder_construct(
+	struct dce110_stream_encoder *enc110,
+	struct dc_context *ctx,
+	struct dc_bios *bp,
+	enum engine_id eng_id)
+{
+	enc110->base.funcs = &dce110_an_str_enc_funcs;
+	enc110->base.ctx = ctx;
+	enc110->base.id = eng_id;
+	enc110->base.bp = bp;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h
index cc5020a8e1e1..068de1392121 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h
@@ -708,6 +708,11 @@ void dce110_stream_encoder_construct(
 	const struct dce_stream_encoder_shift *se_shift,
 	const struct dce_stream_encoder_mask *se_mask);
 
+void dce110_analog_stream_encoder_construct(
+	struct dce110_stream_encoder *enc110,
+	struct dc_context *ctx,
+	struct dc_bios *bp,
+	enum engine_id eng_id);
 
 void dce110_se_audio_mute_control(
 	struct stream_encoder *enc, bool mute);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
index 72efb13c9027..9e70e920eb69 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
@@ -374,6 +374,7 @@ static const struct bios_registers bios_regs = {
 static const struct resource_caps res_cap = {
 	.num_timing_generator = 6,
 	.num_audio = 6,
+	.num_analog_stream_encoder = 1,
 	.num_stream_encoder = 6,
 	.num_pll = 3,
 	.num_ddc = 6,
@@ -483,6 +484,11 @@ static struct stream_encoder *dce100_stream_encoder_create(
 	if (!enc110)
 		return NULL;
 
+	if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) {
+		dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id);
+		return &enc110->base;
+	}
+
 	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 					&stream_enc_regs[eng_id], &se_shift, &se_mask);
 	return &enc110->base;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
index 58b59d52dc9d..29ccfbddb492 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
@@ -372,6 +372,7 @@ static const struct bios_registers bios_regs = {
 static const struct resource_caps res_cap = {
 		.num_timing_generator = 6,
 		.num_audio = 6,
+		.num_analog_stream_encoder = 1,
 		.num_stream_encoder = 6,
 		.num_pll = 2,
 		.num_ddc = 6,
@@ -381,6 +382,7 @@ static const struct resource_caps res_cap_61 = {
 		.num_timing_generator = 4,
 		.num_audio = 6,
 		.num_stream_encoder = 6,
+		.num_analog_stream_encoder = 1,
 		.num_pll = 3,
 		.num_ddc = 6,
 };
@@ -388,6 +390,7 @@ static const struct resource_caps res_cap_61 = {
 static const struct resource_caps res_cap_64 = {
 		.num_timing_generator = 2,
 		.num_audio = 2,
+		.num_analog_stream_encoder = 1,
 		.num_stream_encoder = 2,
 		.num_pll = 2,
 		.num_ddc = 2,
@@ -598,6 +601,11 @@ static struct stream_encoder *dce60_stream_encoder_create(
 	if (!enc110)
 		return NULL;
 
+	if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) {
+		dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id);
+		return &enc110->base;
+	}
+
 	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 					&stream_enc_regs[eng_id],
 					&se_shift, &se_mask);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
index 3e8b0ac11d90..f90e51696bda 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
@@ -374,6 +374,7 @@ static const struct bios_registers bios_regs = {
 static const struct resource_caps res_cap = {
 		.num_timing_generator = 6,
 		.num_audio = 6,
+		.num_analog_stream_encoder = 1,
 		.num_stream_encoder = 6,
 		.num_pll = 3,
 		.num_ddc = 6,
@@ -382,6 +383,7 @@ static const struct resource_caps res_cap = {
 static const struct resource_caps res_cap_81 = {
 		.num_timing_generator = 4,
 		.num_audio = 7,
+		.num_analog_stream_encoder = 1,
 		.num_stream_encoder = 7,
 		.num_pll = 3,
 		.num_ddc = 6,
@@ -390,6 +392,7 @@ static const struct resource_caps res_cap_81 = {
 static const struct resource_caps res_cap_83 = {
 		.num_timing_generator = 2,
 		.num_audio = 6,
+		.num_analog_stream_encoder = 1,
 		.num_stream_encoder = 6,
 		.num_pll = 2,
 		.num_ddc = 2,
@@ -604,6 +607,11 @@ static struct stream_encoder *dce80_stream_encoder_create(
 	if (!enc110)
 		return NULL;
 
+	if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) {
+		dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id);
+		return &enc110->base;
+	}
+
 	dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
 					&stream_enc_regs[eng_id],
 					&se_shift, &se_mask);
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (9 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-08-01 19:30   ` Alexandre Demers
  2025-07-23 15:58 ` [PATCH 12/20] drm/amd/display: Support DAC in dce110_hwseq Timur Kristóf
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

We support two kinds of analog connections:

1. VGA, which only supports analog signals:
For VGA, we need to create a link encoder that only works with the
DAC without perturbing any digital transmitter functionality.
This is achieved by the new dce110_analog_link_encoder_construct.

2. DVI-I, which allows both digital and analog signals:
The DC code base only allows 1 encoder per connector, and the
preferred engine type is still going to be digital. So, for DVI-I
to work, we need to make sure the pre-existing link encoder can
also work with analog signals.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../drm/amd/display/dc/dce/dce_link_encoder.c | 100 ++++++++++++++++++
 .../drm/amd/display/dc/dce/dce_link_encoder.h |  21 ++--
 .../dc/resource/dce100/dce100_resource.c      |  13 ++-
 .../dc/resource/dce60/dce60_resource.c        |  16 ++-
 .../dc/resource/dce80/dce80_resource.c        |  13 ++-
 5 files changed, 152 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index 4a9d07c31bc5..0d5069773f57 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -804,6 +804,24 @@ bool dce110_link_encoder_validate_dp_output(
 	return true;
 }
 
+static bool dce110_link_encoder_validate_rgb_output(
+	const struct dce110_link_encoder *enc110,
+	const struct dc_crtc_timing *crtc_timing)
+{
+	uint32_t max_pixel_clock_khz = 400000;
+
+	if (enc110->base.ctx->dc_bios->fw_info_valid &&
+	    enc110->base.ctx->dc_bios->fw_info.max_pixel_clock) {
+		max_pixel_clock_khz =
+			enc110->base.ctx->dc_bios->fw_info.max_pixel_clock;
+	}
+
+	if (crtc_timing->pix_clk_100hz > max_pixel_clock_khz * 10)
+		return false;
+
+	return true;
+}
+
 void dce110_link_encoder_construct(
 	struct dce110_link_encoder *enc110,
 	const struct encoder_init_data *init_data,
@@ -824,6 +842,7 @@ void dce110_link_encoder_construct(
 	enc110->base.connector = init_data->connector;
 
 	enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
+	enc110->base.analog_engine = init_data->analog_engine;
 
 	enc110->base.features = *enc_features;
 
@@ -847,6 +866,11 @@ void dce110_link_encoder_construct(
 		SIGNAL_TYPE_EDP |
 		SIGNAL_TYPE_HDMI_TYPE_A;
 
+	if ((enc110->base.connector.id == CONNECTOR_ID_DUAL_LINK_DVII ||
+	     enc110->base.connector.id == CONNECTOR_ID_SINGLE_LINK_DVII) &&
+		enc110->base.analog_engine != ENGINE_ID_UNKNOWN)
+		enc110->base.output_signals |= SIGNAL_TYPE_RGB;
+
 	/* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
 	 * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
 	 * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
@@ -939,6 +963,10 @@ bool dce110_link_encoder_validate_output_with_stream(
 		is_valid = dce110_link_encoder_validate_dp_output(
 					enc110, &stream->timing);
 	break;
+	case SIGNAL_TYPE_RGB:
+		is_valid = dce110_link_encoder_validate_rgb_output(
+					enc110, &stream->timing);
+	break;
 	case SIGNAL_TYPE_EDP:
 	case SIGNAL_TYPE_LVDS:
 		is_valid = stream->timing.pixel_encoding == PIXEL_ENCODING_RGB;
@@ -1034,6 +1062,8 @@ void dce110_link_encoder_setup(
 		/* DP MST */
 		REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 5);
 		break;
+	case SIGNAL_TYPE_RGB:
+		break;
 	default:
 		ASSERT_CRITICAL(false);
 		/* invalid mode ! */
@@ -1282,6 +1312,23 @@ void dce110_link_encoder_disable_output(
 	struct bp_transmitter_control cntl = { 0 };
 	enum bp_result result;
 
+	switch (enc->analog_engine) {
+	case ENGINE_ID_DACA:
+		REG_UPDATE(DAC_ENABLE, DAC_ENABLE, 0);
+		break;
+	case ENGINE_ID_DACB:
+		/* DACB doesn't seem to be present on DCE6+,
+		 * although there are references to it in the register file.
+		 */
+		DC_LOG_ERROR("%s DACB is unsupported\n", __func__);
+		break;
+	default:
+		break;
+	}
+
+	if (enc->preferred_engine == enc->analog_engine)
+		return;
+
 	if (!dce110_is_dig_enabled(enc)) {
 		/* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */
 		return;
@@ -1726,6 +1773,7 @@ void dce60_link_encoder_construct(
 	enc110->base.connector = init_data->connector;
 
 	enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
+	enc110->base.analog_engine = init_data->analog_engine;
 
 	enc110->base.features = *enc_features;
 
@@ -1749,6 +1797,11 @@ void dce60_link_encoder_construct(
 		SIGNAL_TYPE_EDP |
 		SIGNAL_TYPE_HDMI_TYPE_A;
 
+	if ((enc110->base.connector.id == CONNECTOR_ID_DUAL_LINK_DVII ||
+	     enc110->base.connector.id == CONNECTOR_ID_SINGLE_LINK_DVII) &&
+		enc110->base.analog_engine != ENGINE_ID_UNKNOWN)
+		enc110->base.output_signals |= SIGNAL_TYPE_RGB;
+
 	/* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
 	 * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
 	 * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
@@ -1814,3 +1867,50 @@ void dce60_link_encoder_construct(
 	}
 }
 #endif
+
+static void dce110_analog_link_encoder_hw_init(
+	struct link_encoder *enc)
+{
+}
+
+static void dce110_analog_link_encoder_setup(
+	struct link_encoder *enc,
+	enum signal_type signal)
+{
+}
+
+static void dce110_analog_link_encoder_get_max_link_cap(
+	struct link_encoder *enc,
+	struct dc_link_settings *link_settings)
+{
+	memset(link_settings, 0, sizeof(struct dc_link_settings));
+}
+
+static const struct link_encoder_funcs dce110_an_lnk_enc_funcs = {
+	.validate_output_with_stream =
+		dce110_link_encoder_validate_output_with_stream,
+	.hw_init = dce110_analog_link_encoder_hw_init,
+	.setup = dce110_analog_link_encoder_setup,
+	.disable_output = dce110_link_encoder_disable_output,
+	.destroy = dce110_link_encoder_destroy,
+	.get_max_link_cap = dce110_analog_link_encoder_get_max_link_cap,
+};
+
+void dce110_analog_link_encoder_construct(
+	struct dce110_link_encoder *enc110,
+	const struct encoder_init_data *init_data,
+	const struct dce110_link_enc_registers *link_regs)
+{
+	enc110->base.funcs = &dce110_an_lnk_enc_funcs;
+	enc110->base.ctx = init_data->ctx;
+	enc110->base.id = init_data->encoder;
+
+	enc110->base.hpd_source = init_data->hpd_source;
+	enc110->base.connector = init_data->connector;
+	enc110->base.preferred_engine = init_data->analog_engine;
+	enc110->base.analog_engine = init_data->analog_engine;
+	enc110->base.transmitter = init_data->transmitter;
+	enc110->base.output_signals = SIGNAL_TYPE_RGB;
+
+	enc110->link_regs = link_regs;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
index 261c70e01e33..1eda1a1a539c 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
@@ -101,18 +101,21 @@
 	SRI(DP_SEC_CNTL, DP, id), \
 	SRI(DP_VID_STREAM_CNTL, DP, id), \
 	SRI(DP_DPHY_FAST_TRAINING, DP, id), \
-	SRI(DP_SEC_CNTL1, DP, id)
+	SRI(DP_SEC_CNTL1, DP, id), \
+	SR(DAC_ENABLE)
 #endif
 
 #define LE_DCE80_REG_LIST(id)\
 	SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
-	LE_COMMON_REG_LIST_BASE(id)
+	LE_COMMON_REG_LIST_BASE(id), \
+	SR(DAC_ENABLE)
 
 #define LE_DCE100_REG_LIST(id)\
 	LE_COMMON_REG_LIST_BASE(id), \
 	SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
 	SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
-	SR(DCI_MEM_PWR_STATUS)
+	SR(DCI_MEM_PWR_STATUS), \
+	SR(DAC_ENABLE)
 
 #define LE_DCE110_REG_LIST(id)\
 	LE_COMMON_REG_LIST_BASE(id), \
@@ -181,6 +184,9 @@ struct dce110_link_enc_registers {
 	uint32_t DP_DPHY_BS_SR_SWAP_CNTL;
 	uint32_t DP_DPHY_HBR2_PATTERN_CONTROL;
 	uint32_t DP_SEC_CNTL1;
+
+	/* DAC registers */
+	uint32_t DAC_ENABLE;
 };
 
 struct dce110_link_encoder {
@@ -199,6 +205,11 @@ void dce110_link_encoder_construct(
 	const struct dce110_link_enc_aux_registers *aux_regs,
 	const struct dce110_link_enc_hpd_registers *hpd_regs);
 
+void dce110_analog_link_encoder_construct(
+	struct dce110_link_encoder *enc110,
+	const struct encoder_init_data *init_data,
+	const struct dce110_link_enc_registers *link_regs);
+
 #if defined(CONFIG_DRM_AMD_DC_SI)
 void dce60_link_encoder_construct(
 	struct dce110_link_encoder *enc110,
@@ -215,10 +226,6 @@ bool dce110_link_encoder_validate_dvi_output(
 	enum signal_type signal,
 	const struct dc_crtc_timing *crtc_timing);
 
-bool dce110_link_encoder_validate_rgb_output(
-	const struct dce110_link_encoder *enc110,
-	const struct dc_crtc_timing *crtc_timing);
-
 bool dce110_link_encoder_validate_dp_output(
 	const struct dce110_link_encoder *enc110,
 	const struct dc_crtc_timing *crtc_timing);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
index 9e70e920eb69..6a4c1b47f80d 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
@@ -224,6 +224,7 @@ static const struct dce110_link_enc_registers link_enc_regs[] = {
 	link_regs(4),
 	link_regs(5),
 	link_regs(6),
+	{ .DAC_ENABLE = mmDAC_ENABLE },
 };
 
 #define stream_enc_regs(id)\
@@ -629,7 +630,17 @@ static struct link_encoder *dce100_link_encoder_create(
 		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 	int link_regs_id;
 
-	if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
+	if (!enc110)
+		return NULL;
+
+	if (enc_init_data->connector.id == CONNECTOR_ID_VGA) {
+		dce110_analog_link_encoder_construct(enc110,
+						enc_init_data,
+						&link_enc_regs[ENGINE_ID_DACA]);
+		return &enc110->base;
+	}
+
+	if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
 		return NULL;
 
 	link_regs_id =
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
index 29ccfbddb492..98775e5ef0bf 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
@@ -239,7 +239,9 @@ static const struct dce110_link_enc_registers link_enc_regs[] = {
 	link_regs(2),
 	link_regs(3),
 	link_regs(4),
-	link_regs(5)
+	link_regs(5),
+	{0},
+	{ .DAC_ENABLE = mmDAC_ENABLE },
 };
 
 #define stream_enc_regs(id)\
@@ -725,7 +727,17 @@ static struct link_encoder *dce60_link_encoder_create(
 		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 	int link_regs_id;
 
-	if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
+	if (!enc110)
+		return NULL;
+
+	if (enc_init_data->connector.id == CONNECTOR_ID_VGA) {
+		dce110_analog_link_encoder_construct(enc110,
+						enc_init_data,
+						&link_enc_regs[ENGINE_ID_DACA]);
+		return &enc110->base;
+	}
+
+	if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
 		return NULL;
 
 	link_regs_id =
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
index f90e51696bda..7fde2b8719c7 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
@@ -240,6 +240,7 @@ static const struct dce110_link_enc_registers link_enc_regs[] = {
 	link_regs(4),
 	link_regs(5),
 	link_regs(6),
+	{ .DAC_ENABLE = mmDAC_ENABLE },
 };
 
 #define stream_enc_regs(id)\
@@ -731,7 +732,17 @@ static struct link_encoder *dce80_link_encoder_create(
 		kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
 	int link_regs_id;
 
-	if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
+	if (!enc110)
+		return NULL;
+
+	if (enc_init_data->connector.id == CONNECTOR_ID_VGA) {
+		dce110_analog_link_encoder_construct(enc110,
+						enc_init_data,
+						&link_enc_regs[ENGINE_ID_DACA]);
+		return &enc110->base;
+	}
+
+	if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
 		return NULL;
 
 	link_regs_id =
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 12/20] drm/amd/display: Support DAC in dce110_hwseq
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (10 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 13/20] drm/amd/display: Add analog link detection Timur Kristóf
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

The dce110_hwseq is used by all DCE hardware,
so add the DAC support here.

When enabling/disabling a stream for a RGB signal,
this will call the VBIOS to enable/disable the DAC.
Additionally, when applying the controller context,
call SelectCRTC_Source from VBIOS in order to
direct the CRTC output to the DAC.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 75 ++++++++++++++++++-
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 4ea13d0bf815..cc1f899f37e8 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -659,6 +659,20 @@ void dce110_update_info_frame(struct pipe_ctx *pipe_ctx)
 	}
 }
 
+static void
+dce110_dac_encoder_control(struct pipe_ctx *pipe_ctx, bool enable)
+{
+	struct dc_link *link = pipe_ctx->stream->link;
+	struct dc_bios *bios = link->ctx->dc_bios;
+	struct bp_encoder_control encoder_control = {0};
+
+	encoder_control.action = enable ? ENCODER_CONTROL_ENABLE : ENCODER_CONTROL_DISABLE;
+	encoder_control.engine_id = link->link_enc->analog_engine;
+	encoder_control.pixel_clock = pipe_ctx->stream->timing.pix_clk_100hz / 10;
+
+	bios->funcs->encoder_control(bios, &encoder_control);
+}
+
 void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
 {
 	enum dc_lane_count lane_count =
@@ -688,6 +702,9 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
 		early_control = lane_count;
 
 	tg->funcs->set_early_control(tg, early_control);
+
+	if (dc_is_rgb_signal(pipe_ctx->stream->signal))
+		dce110_dac_encoder_control(pipe_ctx, true);
 }
 
 static enum bp_result link_transmitter_control(
@@ -1175,7 +1192,8 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 		pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
 			pipe_ctx->stream_res.stream_enc);
 
-	dc->hwss.disable_audio_stream(pipe_ctx);
+	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
+		dc->hwss.disable_audio_stream(pipe_ctx);
 
 	link_hwss->reset_stream_encoder(pipe_ctx);
 
@@ -1195,6 +1213,9 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 		dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
 					       link_enc->transmitter - TRANSMITTER_UNIPHY_A);
 	}
+
+	if (dc_is_rgb_signal(pipe_ctx->stream->signal))
+		dce110_dac_encoder_control(pipe_ctx, false);
 }
 
 void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
@@ -1580,6 +1601,51 @@ static enum dc_status dce110_enable_stream_timing(
 	return DC_OK;
 }
 
+static void
+dce110_select_crtc_source(struct pipe_ctx *pipe_ctx)
+{
+	struct dc_link *link = pipe_ctx->stream->link;
+	struct dc_bios *bios = link->ctx->dc_bios;
+	struct bp_crtc_source_select crtc_source_select = {0};
+	enum engine_id engine_id = link->link_enc->preferred_engine;
+	uint8_t bit_depth;
+
+	if (dc_is_rgb_signal(pipe_ctx->stream->signal))
+		engine_id = link->link_enc->analog_engine;
+
+	switch (pipe_ctx->stream->timing.display_color_depth) {
+	case COLOR_DEPTH_UNDEFINED:
+		bit_depth = 0;
+		break;
+	case COLOR_DEPTH_666:
+		bit_depth = 6;
+		break;
+	default:
+	case COLOR_DEPTH_888:
+		bit_depth = 8;
+		break;
+	case COLOR_DEPTH_101010:
+		bit_depth = 10;
+		break;
+	case COLOR_DEPTH_121212:
+		bit_depth = 12;
+		break;
+	case COLOR_DEPTH_141414:
+		bit_depth = 14;
+		break;
+	case COLOR_DEPTH_161616:
+		bit_depth = 16;
+		break;
+	}
+
+	crtc_source_select.controller_id = CONTROLLER_ID_D0 + pipe_ctx->stream_res.tg->inst;
+	crtc_source_select.bit_depth = bit_depth;
+	crtc_source_select.engine_id = engine_id;
+	crtc_source_select.sink_signal = pipe_ctx->stream->signal;
+
+	bios->funcs->select_crtc_source(bios, &crtc_source_select);
+}
+
 enum dc_status dce110_apply_single_controller_ctx_to_hw(
 		struct pipe_ctx *pipe_ctx,
 		struct dc_state *context,
@@ -1599,6 +1665,10 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
 		hws->funcs.disable_stream_gating(dc, pipe_ctx);
 	}
 
+	if (pipe_ctx->stream->signal == SIGNAL_TYPE_RGB) {
+		dce110_select_crtc_source(pipe_ctx);
+	}
+
 	if (pipe_ctx->stream_res.audio != NULL) {
 		struct audio_output audio_output = {0};
 
@@ -1678,7 +1748,8 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
 		pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
 				pipe_ctx->stream_res.tg, event_triggers, 2);
 
-	if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
+	if (!dc_is_virtual_signal(pipe_ctx->stream->signal) &&
+		!dc_is_rgb_signal(pipe_ctx->stream->signal))
 		pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
 			pipe_ctx->stream_res.stream_enc,
 			pipe_ctx->stream_res.tg->inst);
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (11 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 12/20] drm/amd/display: Support DAC in dce110_hwseq Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-08-07 19:12   ` Harry Wentland
  2025-07-23 15:58 ` [PATCH 14/20] drm/amd/display: Poll analog connectors Timur Kristóf
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

Analog displays typically have a DDC connection which can be
used by the GPU to read EDID. This commit adds the capability
to probe analog displays using DDC, reading the EDID header and
deciding whether the analog link is connected based on the data
that was read.

As a reference, I used the following functions:
amdgpu_connector_vga_detect
amdgpu_display_ddc_probe

DAC load detection will be implemented in a separate commit.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
 .../drm/amd/display/dc/link/link_detection.c  | 80 ++++++++++++++++++-
 .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
 .../drm/amd/display/dc/link/link_factory.c    |  3 +
 4 files changed, 95 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
index f3470716734d..b9ebb992dc98 100644
--- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
+++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
@@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
 		return;
 	}
 
-	link_enc->funcs->connect_dig_be_to_fe(link_enc,
-			pipe_ctx->stream_res.stream_enc->id, true);
+	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
+		link_enc->funcs->connect_dig_be_to_fe(link_enc,
+				pipe_ctx->stream_res.stream_enc->id, true);
 	if (dc_is_dp_signal(pipe_ctx->stream->signal))
 		pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(pipe_ctx->stream->link,
 				DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
@@ -98,10 +99,13 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
 	if (stream_enc->funcs->enable_stream)
 		stream_enc->funcs->enable_stream(stream_enc,
 				pipe_ctx->stream->signal, false);
-	link_enc->funcs->connect_dig_be_to_fe(
-			link_enc,
-			pipe_ctx->stream_res.stream_enc->id,
-			false);
+
+	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
+		link_enc->funcs->connect_dig_be_to_fe(
+				link_enc,
+				pipe_ctx->stream_res.stream_enc->id,
+				false);
+
 	if (dc_is_dp_signal(pipe_ctx->stream->signal))
 		pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(
 				pipe_ctx->stream->link,
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index 827b630daf49..fcabc83464af 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -942,6 +942,12 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 			break;
 		}
 
+		case SIGNAL_TYPE_RGB: {
+			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
+			sink_caps.signal = SIGNAL_TYPE_RGB;
+			break;
+		}
+
 		case SIGNAL_TYPE_LVDS: {
 			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
 			sink_caps.signal = SIGNAL_TYPE_LVDS;
@@ -1133,9 +1139,17 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 				sink = prev_sink;
 				prev_sink = NULL;
 			}
-			query_hdcp_capability(sink->sink_signal, link);
+
+			if (!sink->edid_caps.analog)
+				query_hdcp_capability(sink->sink_signal, link);
 		}
 
+		/* DVI-I connector connected to analog display. */
+		if ((link->link_enc->connector.id == CONNECTOR_ID_DUAL_LINK_DVII ||
+		     link->link_enc->connector.id == CONNECTOR_ID_SINGLE_LINK_DVII) &&
+			sink->edid_caps.analog)
+			sink->sink_signal = SIGNAL_TYPE_RGB;
+
 		/* HDMI-DVI Dongle */
 		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
 		    !sink->edid_caps.edid_hdmi)
@@ -1228,6 +1242,64 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 	return true;
 }
 
+/**
+ * Evaluates whether an EDID header is acceptable,
+ * for the purpose of determining a connection with a display.
+ */
+static bool link_detect_evaluate_edid_header(uint8_t edid_header[8])
+{
+	int edid_header_score = 0;
+	int i;
+
+	for (i = 0; i < 8; ++i)
+		edid_header_score += edid_header[i] == ((i == 0 || i == 7) ? 0x00 : 0xff);
+
+	return edid_header_score >= 6;
+}
+
+/**
+ * Tries to detect a connected display by probing the DDC
+ * and reading the EDID header.
+ * The probing is considered successful if we receive a
+ * reply from the DDC over I2C and the EDID header matches.
+ */
+static bool link_detect_ddc_probe(struct dc_link *link)
+{
+	if (!link->ddc)
+		return false;
+
+	uint8_t edid_header[8] = {0};
+	bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header, sizeof(edid_header));
+
+	if (!ddc_probed)
+		return false;
+
+	if (!link_detect_evaluate_edid_header(edid_header))
+		return false;
+
+	return true;
+}
+
+/**
+ * Determines if there is an analog sink connected.
+ */
+static bool link_detect_analog(struct dc_link *link, enum dc_connection_type *type)
+{
+	/* Don't care about connectors that don't support an analog signal. */
+	if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
+		link->link_enc->connector.id != CONNECTOR_ID_SINGLE_LINK_DVII &&
+		link->link_enc->connector.id != CONNECTOR_ID_DUAL_LINK_DVII)
+		return false;
+
+	if (link_detect_ddc_probe(link)) {
+		*type = dc_connection_single;
+		return true;
+	}
+
+	*type = dc_connection_none;
+	return true;
+}
+
 /*
  * link_detect_connection_type() - Determine if there is a sink connected
  *
@@ -1238,6 +1310,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type)
 {
 	uint32_t is_hpd_high = 0;
+	bool supports_hpd = link->irq_source_hpd != DC_IRQ_SOURCE_INVALID;
 
 	if (link->connector_signal == SIGNAL_TYPE_LVDS) {
 		*type = dc_connection_single;
@@ -1261,6 +1334,8 @@ bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *
 		return true;
 	}
 
+	if (!supports_hpd)
+		return link_detect_analog(link, type);
 
 	if (!query_hpd_status(link, &is_hpd_high))
 		goto hpd_gpio_failure;
@@ -1269,6 +1344,9 @@ bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *
 		*type = dc_connection_single;
 		/* TODO: need to do the actual detection */
 	} else {
+		if (link_detect_analog(link, type))
+			return true;
+
 		*type = dc_connection_none;
 		if (link->connector_signal == SIGNAL_TYPE_EDP) {
 			/* eDP is not connected, power down it */
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
index d6b7347c6c11..ac25d89a4148 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
@@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
 		enable_link_lvds(pipe_ctx);
 		status = DC_OK;
 		break;
+	case SIGNAL_TYPE_RGB:
+		status = DC_OK;
+		break;
 	case SIGNAL_TYPE_VIRTUAL:
 		status = enable_link_virtual(pipe_ctx);
 		break;
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
index 71c10a1261b9..c9725fd316f6 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
@@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link *link,
 	case CONNECTOR_ID_DUAL_LINK_DVII:
 		link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
 		break;
+	case CONNECTOR_ID_VGA:
+		link->connector_signal = SIGNAL_TYPE_RGB;
+		break;
 	case CONNECTOR_ID_DISPLAY_PORT:
 	case CONNECTOR_ID_MXM:
 	case CONNECTOR_ID_USBC:
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 14/20] drm/amd/display: Poll analog connectors
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (12 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 13/20] drm/amd/display: Add analog link detection Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 15/20] drm/amd/display: Add DCE BIOS_SCRATCH_0 register Timur Kristóf
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

VGA connectors don't support any hotplug detection, so the kernel
needs to periodically poll them to see if a display is connected.

DVI-I connectors have hotplug detection for digital signals, and
some analog DVI cables pull up that pin to work with that.
However, in general not all DVI cables do this so we can't rely on
this feature, therefore we need to poll DVI-I connectors as well.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 60 ++++++++++++++++++-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  8 +++
 2 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c347b232ae06..13823469fa7c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3736,7 +3736,9 @@ void amdgpu_dm_update_connector_after_detect(
 	drm_dbg_kms(dev, "DCHPD: connector_id=%d: Old sink=%p New sink=%p\n",
 		    aconnector->connector_id, aconnector->dc_sink, sink);
 
-	guard(mutex)(&dev->mode_config.mutex);
+	/* When polling, DRM has already locked the mutex for us. */
+	if (!drm_kms_helper_is_poll_worker())
+		mutex_lock(&dev->mode_config.mutex);
 
 	/*
 	 * 1. Update status of the drm connector
@@ -3799,6 +3801,10 @@ void amdgpu_dm_update_connector_after_detect(
 	}
 
 	update_subconnector_property(aconnector);
+
+	/* When polling, the mutex will be unlocked for us by DRM. */
+	if (!drm_kms_helper_is_poll_worker())
+		mutex_unlock(&dev->mode_config.mutex);
 }
 
 static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector)
@@ -7061,10 +7067,48 @@ create_stream_for_sink(struct drm_connector *connector,
 	return stream;
 }
 
+static enum drm_connector_status
+amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force)
+{
+	struct drm_connector *connector = &aconnector->base;
+	struct drm_device *dev = connector->dev;
+	struct amdgpu_device *adev = drm_to_adev(dev);
+	struct dc_link *link = aconnector->dc_link;
+	enum dc_connection_type conn_type = dc_connection_none;
+	enum drm_connector_status status = connector_status_disconnected;
+
+	mutex_lock(&aconnector->hpd_lock);
+
+	if (dc_link_detect_connection_type(aconnector->dc_link, &conn_type) &&
+	    conn_type != dc_connection_none) {
+		mutex_lock(&adev->dm.dc_lock);
+
+		if (dc_link_detect(link, DETECT_REASON_HPD))
+			status = connector_status_connected;
+
+		mutex_unlock(&adev->dm.dc_lock);
+	}
+
+	if (status == connector_status_disconnected) {
+		if (link->local_sink)
+			dc_sink_release(link->local_sink);
+
+		link->local_sink = NULL;
+		link->dpcd_sink_count = 0;
+		link->type = dc_connection_none;
+	}
+
+	amdgpu_dm_update_connector_after_detect(aconnector);
+
+	mutex_unlock(&aconnector->hpd_lock);
+	return status;
+}
+
 static enum drm_connector_status
 amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
 {
 	bool connected;
+	bool analog_connector;
 	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 
 	/*
@@ -7083,6 +7127,15 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
 
 	update_subconnector_property(aconnector);
 
+	analog_connector =
+		aconnector->dc_link->link_id.id == CONNECTOR_ID_DUAL_LINK_DVII ||
+		aconnector->dc_link->link_id.id == CONNECTOR_ID_SINGLE_LINK_DVII ||
+		aconnector->dc_link->link_id.id == CONNECTOR_ID_VGA;
+
+	if (analog_connector && drm_kms_helper_is_poll_worker() &&
+		(!connected || aconnector->dc_sink->edid_caps.analog))
+		return amdgpu_dm_connector_poll(aconnector, force);
+
 	return (connected ? connector_status_connected :
 			connector_status_disconnected);
 }
@@ -8442,9 +8495,12 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 			link->link_enc->features.dp_ycbcr420_supported ? true : false;
 		break;
 	case DRM_MODE_CONNECTOR_DVID:
+		aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
+		break;
 	case DRM_MODE_CONNECTOR_DVII:
 	case DRM_MODE_CONNECTOR_VGA:
-		aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
+		aconnector->base.polled =
+			DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
 		break;
 	default:
 		break;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
index b61e210f6246..327a3965fda1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
@@ -892,6 +892,7 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
 	struct drm_connector_list_iter iter;
 	int irq_type;
 	int i;
+	bool need_polling = false;
 
 	/* First, clear all hpd and hpdrx interrupts */
 	for (i = DC_IRQ_SOURCE_HPD1; i <= DC_IRQ_SOURCE_HPD6RX; i++) {
@@ -905,6 +906,8 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
 		struct amdgpu_dm_connector *amdgpu_dm_connector;
 		const struct dc_link *dc_link;
 
+		need_polling |= connector->polled != DRM_CONNECTOR_POLL_HPD;
+
 		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
 			continue;
 
@@ -946,6 +949,11 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
 		}
 	}
 	drm_connector_list_iter_end(&iter);
+
+	if (need_polling) {
+		drm_kms_helper_poll_init(dev);
+		drm_kms_helper_poll_enable(dev);
+	}
 }
 
 /**
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 15/20] drm/amd/display: Add DCE BIOS_SCRATCH_0 register
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (13 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 14/20] drm/amd/display: Poll analog connectors Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 16/20] drm/amd/display: Make get_support_mask_for_device_id reusable Timur Kristóf
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

The BIOS uses this register to write the results of the
DAC_LoadDetection command, so we'll need to read this
in order to make DAC load detection work.

As a reference, I used the mmBIOS_SCRATCH_0 definition from
the amdgpu legacy display code.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/display/dc/dc_bios_types.h                  | 1 +
 .../gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c    | 2 ++
 .../gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c    | 2 ++
 .../gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c    | 2 ++
 .../gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c    | 1 +
 drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c  | 2 ++
 drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c  | 2 ++
 7 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
index 545ce1e15eae..50c8906b74c5 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
@@ -168,6 +168,7 @@ struct dc_vbios_funcs {
 };
 
 struct bios_registers {
+	uint32_t BIOS_SCRATCH_0;
 	uint32_t BIOS_SCRATCH_3;
 	uint32_t BIOS_SCRATCH_6;
 };
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
index 6a4c1b47f80d..3b6f330d27b4 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
@@ -77,6 +77,7 @@
 #endif
 
 #ifndef mmBIOS_SCRATCH_2
+	#define mmBIOS_SCRATCH_0 0x05C9
 	#define mmBIOS_SCRATCH_2 0x05CB
 	#define mmBIOS_SCRATCH_3 0x05CC
 	#define mmBIOS_SCRATCH_6 0x05CF
@@ -368,6 +369,7 @@ static const struct dce_abm_mask abm_mask = {
 #define DCFE_MEM_PWR_CTRL_REG_BASE 0x1b03
 
 static const struct bios_registers bios_regs = {
+	.BIOS_SCRATCH_0 = mmBIOS_SCRATCH_0,
 	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 };
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
index cccde5a6f3cd..42b0068b1c05 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
@@ -82,6 +82,7 @@
 #endif
 
 #ifndef mmBIOS_SCRATCH_2
+	#define mmBIOS_SCRATCH_0 0x05C9
 	#define mmBIOS_SCRATCH_2 0x05CB
 	#define mmBIOS_SCRATCH_3 0x05CC
 	#define mmBIOS_SCRATCH_6 0x05CF
@@ -377,6 +378,7 @@ static const struct dce110_clk_src_mask cs_mask = {
 };
 
 static const struct bios_registers bios_regs = {
+	.BIOS_SCRATCH_0 = mmBIOS_SCRATCH_0,
 	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 };
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
index 164ba796f64c..62babc9dfca0 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
@@ -76,6 +76,7 @@
 #endif
 
 #ifndef mmBIOS_SCRATCH_2
+	#define mmBIOS_SCRATCH_0 0x05C9
 	#define mmBIOS_SCRATCH_2 0x05CB
 	#define mmBIOS_SCRATCH_3 0x05CC
 	#define mmBIOS_SCRATCH_6 0x05CF
@@ -385,6 +386,7 @@ static const struct dce110_clk_src_mask cs_mask = {
 };
 
 static const struct bios_registers bios_regs = {
+	.BIOS_SCRATCH_0 = mmBIOS_SCRATCH_0,
 	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 };
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c
index eb1e158d3436..4998f45ace11 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c
@@ -491,6 +491,7 @@ static struct dce_i2c_hw *dce120_i2c_hw_create(
 	return dce_i2c_hw;
 }
 static const struct bios_registers bios_regs = {
+	.BIOS_SCRATCH_0 = mmBIOS_SCRATCH_0 + NBIO_BASE(mmBIOS_SCRATCH_0_BASE_IDX),
 	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3 + NBIO_BASE(mmBIOS_SCRATCH_3_BASE_IDX),
 	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6 + NBIO_BASE(mmBIOS_SCRATCH_6_BASE_IDX)
 };
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
index 98775e5ef0bf..3e1032d5cae3 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
@@ -79,6 +79,7 @@
 
 
 #ifndef mmBIOS_SCRATCH_2
+	#define mmBIOS_SCRATCH_0 0x05C9
 	#define mmBIOS_SCRATCH_2 0x05CB
 	#define mmBIOS_SCRATCH_3 0x05CC
 	#define mmBIOS_SCRATCH_6 0x05CF
@@ -367,6 +368,7 @@ static const struct dce110_clk_src_mask cs_mask = {
 };
 
 static const struct bios_registers bios_regs = {
+	.BIOS_SCRATCH_0 = mmBIOS_SCRATCH_0,
 	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 };
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
index 7fde2b8719c7..1462adf7df70 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
@@ -77,6 +77,7 @@
 
 
 #ifndef mmBIOS_SCRATCH_2
+	#define mmBIOS_SCRATCH_0 0x05C9
 	#define mmBIOS_SCRATCH_2 0x05CB
 	#define mmBIOS_SCRATCH_3 0x05CC
 	#define mmBIOS_SCRATCH_6 0x05CF
@@ -368,6 +369,7 @@ static const struct dce110_clk_src_mask cs_mask = {
 };
 
 static const struct bios_registers bios_regs = {
+	.BIOS_SCRATCH_0 = mmBIOS_SCRATCH_0,
 	.BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
 	.BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
 };
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 16/20] drm/amd/display: Make get_support_mask_for_device_id reusable
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (14 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 15/20] drm/amd/display: Add DCE BIOS_SCRATCH_0 register Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 17/20] drm/amd/display: Add DAC_LoadDetection to BIOS parser Timur Kristóf
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

This will be reused by DAC load detection.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/display/dc/bios/bios_parser.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
index bd61ed6cafab..44f71757508f 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -67,7 +67,9 @@ static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp,
 	ATOM_OBJECT *object);
 static struct device_id device_type_from_device_id(uint16_t device_id);
 static uint32_t signal_to_ss_id(enum as_signal_type signal);
-static uint32_t get_support_mask_for_device_id(struct device_id device_id);
+static uint32_t get_support_mask_for_device_id(
+	enum dal_device_type device_type,
+	uint32_t enum_id);
 static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record(
 	struct bios_parser *bp,
 	ATOM_OBJECT *object);
@@ -891,7 +893,7 @@ static bool bios_parser_is_device_id_supported(
 {
 	struct bios_parser *bp = BP_FROM_DCB(dcb);
 
-	uint32_t mask = get_support_mask_for_device_id(id);
+	uint32_t mask = get_support_mask_for_device_id(id.device_type, id.enum_id);
 
 	return (le16_to_cpu(bp->object_info_tbl.v1_1->usDeviceSupport) & mask) != 0;
 }
@@ -2182,11 +2184,10 @@ static uint32_t signal_to_ss_id(enum as_signal_type signal)
 	return clk_id_ss;
 }
 
-static uint32_t get_support_mask_for_device_id(struct device_id device_id)
+static uint32_t get_support_mask_for_device_id(
+	enum dal_device_type device_type,
+	uint32_t enum_id)
 {
-	enum dal_device_type device_type = device_id.device_type;
-	uint32_t enum_id = device_id.enum_id;
-
 	switch (device_type) {
 	case DEVICE_TYPE_LCD:
 		switch (enum_id) {
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 17/20] drm/amd/display: Add DAC_LoadDetection to BIOS parser
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (15 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 16/20] drm/amd/display: Make get_support_mask_for_device_id reusable Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 18/20] drm/amd/display: Use DAC load detection on analog connectors Timur Kristóf
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

DAC_LoadDetection can be used to determine whether something
is connected to an analog connector, primarily when the connected
display doesn't have an EDID.

As a reference, I used the following function:
amdgpu_atombios_encoder_dac_load_detect

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../gpu/drm/amd/display/dc/bios/bios_parser.c | 50 ++++++++++
 .../drm/amd/display/dc/bios/command_table.c   | 92 +++++++++++++++++++
 .../drm/amd/display/dc/bios/command_table.h   |  3 +
 .../gpu/drm/amd/display/dc/dc_bios_types.h    |  5 +
 .../amd/display/include/bios_parser_types.h   |  5 +
 5 files changed, 155 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
index 44f71757508f..58a7f6012936 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -783,6 +783,54 @@ static enum bp_result bios_parser_encoder_control(
 	return bp->cmd_tbl.dig_encoder_control(bp, cntl);
 }
 
+static enum bp_result bios_parser_dac_load_detection(
+	struct dc_bios *dcb,
+	enum engine_id engine_id,
+	enum dal_device_type device_type,
+	uint32_t enum_id)
+{
+	struct bios_parser *bp = BP_FROM_DCB(dcb);
+	struct dc_context *ctx = dcb->ctx;
+	struct bp_load_detection_parameters bp_params = {0};
+	enum bp_result bp_result;
+	uint32_t bios_0_scratch;
+
+	bp_params.engine_id = engine_id;
+	bp_params.device_id = get_support_mask_for_device_id(device_type, enum_id);
+
+	if (engine_id != ENGINE_ID_DACA &&
+	    engine_id != ENGINE_ID_DACB)
+		return BP_RESULT_UNSUPPORTED;
+
+	if (!bp->cmd_tbl.dac_load_detection)
+		return BP_RESULT_UNSUPPORTED;
+
+	/* BIOS will write the detected devices to BIOS_SCRATCH_0, clear the register */
+	dm_write_reg(ctx, bp->base.regs->BIOS_SCRATCH_0, 0);
+
+	bp_result = bp->cmd_tbl.dac_load_detection(bp, &bp_params);
+
+	if (bp_result != BP_RESULT_OK)
+		return bp_result;
+
+	bios_0_scratch = dm_read_reg(ctx, bp->base.regs->BIOS_SCRATCH_0);
+
+	switch (bp_params.device_id) {
+	case ATOM_DEVICE_CRT1_SUPPORT:
+		if (bios_0_scratch & ATOM_S0_CRT1_MASK)
+			return BP_RESULT_OK;
+		break;
+	case ATOM_DEVICE_CRT2_SUPPORT:
+		if (bios_0_scratch & ATOM_S0_CRT2_MASK)
+			return BP_RESULT_OK;
+		break;
+	default:
+		break;
+	}
+
+	return BP_RESULT_FAILURE;
+}
+
 static enum bp_result bios_parser_adjust_pixel_clock(
 	struct dc_bios *dcb,
 	struct bp_adjust_pixel_clock_parameters *bp_params)
@@ -2867,6 +2915,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
 
 	.encoder_control = bios_parser_encoder_control,
 
+	.dac_load_detection = bios_parser_dac_load_detection,
+
 	.transmitter_control = bios_parser_transmitter_control,
 
 	.enable_crtc = bios_parser_enable_crtc,
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
index 8983220d2a4b..7899e952b68a 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
@@ -54,6 +54,7 @@ static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
 static void init_adjust_display_pll(struct bios_parser *bp);
 static void init_select_crtc_source(struct bios_parser *bp);
 static void init_dac_encoder_control(struct bios_parser *bp);
+static void init_dac_load_detection(struct bios_parser *bp);
 static void init_dac_output_control(struct bios_parser *bp);
 static void init_set_crtc_timing(struct bios_parser *bp);
 static void init_enable_crtc(struct bios_parser *bp);
@@ -72,6 +73,7 @@ void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
 	init_adjust_display_pll(bp);
 	init_select_crtc_source(bp);
 	init_dac_encoder_control(bp);
+	init_dac_load_detection(bp);
 	init_dac_output_control(bp);
 	init_set_crtc_timing(bp);
 	init_enable_crtc(bp);
@@ -1902,6 +1904,96 @@ static enum bp_result dac2_encoder_control_v1(
 	return result;
 }
 
+/*******************************************************************************
+ ********************************************************************************
+ **
+ **                  DAC LOAD DETECTION
+ **
+ ********************************************************************************
+ *******************************************************************************/
+
+static enum bp_result dac_load_detection_v1(
+	struct bios_parser *bp,
+	struct bp_load_detection_parameters *bp_params);
+
+static enum bp_result dac_load_detection_v3(
+	struct bios_parser *bp,
+	struct bp_load_detection_parameters *bp_params);
+
+static void init_dac_load_detection(struct bios_parser *bp)
+{
+	switch (BIOS_CMD_TABLE_PARA_REVISION(DAC_LoadDetection)) {
+	case 1:
+	case 2:
+		bp->cmd_tbl.dac_load_detection = dac_load_detection_v1;
+		break;
+	case 3:
+	default:
+		bp->cmd_tbl.dac_load_detection = dac_load_detection_v3;
+		break;
+	}
+}
+
+static void dac_load_detect_prepare_params(
+	struct _DAC_LOAD_DETECTION_PS_ALLOCATION *params,
+	enum engine_id engine_id,
+	uint16_t device_id,
+	uint8_t misc)
+{
+	uint8_t dac_type = ENGINE_ID_DACA;
+
+	if (engine_id == ENGINE_ID_DACB)
+		dac_type = ATOM_DAC_B;
+
+	params->sDacload.usDeviceID = cpu_to_le16(device_id);
+	params->sDacload.ucDacType = dac_type;
+	params->sDacload.ucMisc = misc;
+}
+
+static enum bp_result dac_load_detection_v1(
+	struct bios_parser *bp,
+	struct bp_load_detection_parameters *bp_params)
+{
+	enum bp_result result = BP_RESULT_FAILURE;
+	DAC_LOAD_DETECTION_PS_ALLOCATION params;
+
+	dac_load_detect_prepare_params(
+		&params,
+		bp_params->engine_id,
+		bp_params->device_id,
+		0);
+
+	if (EXEC_BIOS_CMD_TABLE(DAC_LoadDetection, params))
+		result = BP_RESULT_OK;
+
+	return result;
+}
+
+static enum bp_result dac_load_detection_v3(
+	struct bios_parser *bp,
+	struct bp_load_detection_parameters *bp_params)
+{
+	enum bp_result result = BP_RESULT_FAILURE;
+	DAC_LOAD_DETECTION_PS_ALLOCATION params;
+
+	uint8_t misc = 0;
+
+	if (bp_params->device_id == ATOM_DEVICE_CV_SUPPORT ||
+	    bp_params->device_id == ATOM_DEVICE_TV1_SUPPORT)
+		misc = DAC_LOAD_MISC_YPrPb;
+
+	dac_load_detect_prepare_params(
+		&params,
+		bp_params->engine_id,
+		bp_params->device_id,
+		misc);
+
+	if (EXEC_BIOS_CMD_TABLE(DAC_LoadDetection, params))
+		result = BP_RESULT_OK;
+
+	return result;
+}
+
 /*******************************************************************************
  ********************************************************************************
  **
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.h b/drivers/gpu/drm/amd/display/dc/bios/command_table.h
index 8b04b903e93d..e89b1ba0048b 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.h
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.h
@@ -71,6 +71,9 @@ struct cmd_tbl {
 	enum bp_result (*dac2_output_control)(
 		struct bios_parser *bp,
 		bool enable);
+	enum bp_result (*dac_load_detection)(
+		struct bios_parser *bp,
+		struct bp_load_detection_parameters *bp_params);
 	enum bp_result (*set_crtc_timing)(
 		struct bios_parser *bp,
 		struct bp_hw_crtc_timing_parameters *bp_params);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
index 50c8906b74c5..40d7a7d83c40 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
@@ -97,6 +97,11 @@ struct dc_vbios_funcs {
 	enum bp_result (*encoder_control)(
 		struct dc_bios *bios,
 		struct bp_encoder_control *cntl);
+	enum bp_result (*dac_load_detection)(
+		struct dc_bios *bios,
+		enum engine_id engine_id,
+		enum dal_device_type device_type,
+		uint32_t enum_id);
 	enum bp_result (*transmitter_control)(
 		struct dc_bios *bios,
 		struct bp_transmitter_control *cntl);
diff --git a/drivers/gpu/drm/amd/display/include/bios_parser_types.h b/drivers/gpu/drm/amd/display/include/bios_parser_types.h
index d9e58a6a0d36..973b6bdbac63 100644
--- a/drivers/gpu/drm/amd/display/include/bios_parser_types.h
+++ b/drivers/gpu/drm/amd/display/include/bios_parser_types.h
@@ -162,6 +162,11 @@ struct bp_transmitter_control {
 	bool single_pll_mode;
 };
 
+struct bp_load_detection_parameters {
+	enum engine_id engine_id;
+	uint16_t device_id;
+};
+
 struct bp_hw_crtc_timing_parameters {
 	enum controller_id controller_id;
 	/* horizontal part */
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 18/20] drm/amd/display: Use DAC load detection on analog connectors
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (16 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 17/20] drm/amd/display: Add DAC_LoadDetection to BIOS parser Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 19/20] drm/amd/display: Add common modes to analog displays without EDID Timur Kristóf
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

This feature is useful for analog connections without EDID:
- Really old monitors with a VGA connector
- Cheap DVI/VGA adapters that don't connect DDC pins

When a connection is established through DAC load detection,
the driver is supposed to fill in the supported modes for the
display, which we already do in amdgpu_dm_connector_get_modes.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 ++++++
 .../drm/amd/display/dc/link/link_detection.c  | 43 +++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 13823469fa7c..49ee516dc83d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7077,6 +7077,18 @@ amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force)
 	enum dc_connection_type conn_type = dc_connection_none;
 	enum drm_connector_status status = connector_status_disconnected;
 
+	/* When the EDID is missing on an analog connector, that means
+	 * we determined the connection using DAC load detection.
+	 * In this case do NOT poll the connector do detect disconnect
+	 * because that would run DAC load detection again which can cause
+	 * visible visual glitches.
+	 *
+	 * Only allow to poll such a connector again when forcing.
+	 */
+	if (!force && link->local_sink && link->local_sink->edid_caps.analog &&
+		!aconnector->drm_edid)
+		return connector->status;
+
 	mutex_lock(&aconnector->hpd_lock);
 
 	if (dc_link_detect_connection_type(aconnector->dc_link, &conn_type) &&
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index fcabc83464af..6dd96e2797f4 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1073,6 +1073,20 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 			break;
 		case EDID_NO_RESPONSE:
 			DC_LOG_ERROR("No EDID read.\n");
+
+			/* Analog connectors without EDID.
+			 * This can be an old monitor that actually doesn't have EDID,
+			 * or could be a cheap DVI/VGA adapter that doesn't connect DDC,
+			 * and therefore we can't read the EDID.
+			 */
+			if (link->link_enc->connector.id == CONNECTOR_ID_VGA ||
+				link->link_enc->connector.id == CONNECTOR_ID_DUAL_LINK_DVII ||
+				link->link_enc->connector.id == CONNECTOR_ID_SINGLE_LINK_DVII) {
+				DC_LOG_INFO("%s detected analog display without EDID\n", __func__);
+				sink->edid_caps.analog = true;
+				break;
+			}
+
 			/*
 			 * Abort detection for non-DP connectors if we have
 			 * no EDID
@@ -1280,6 +1294,30 @@ static bool link_detect_ddc_probe(struct dc_link *link)
 	return true;
 }
 
+static bool link_detect_dac_load_detect(struct dc_link *link)
+{
+	struct dc_bios *bios = link->ctx->dc_bios;
+	struct link_encoder *link_enc = link->link_enc;
+	enum engine_id engine_id = link_enc->preferred_engine;
+	enum dal_device_type device_type = DEVICE_TYPE_CRT;
+	enum bp_result bp_result;
+	uint32_t enum_id;
+
+	switch (engine_id) {
+	case ENGINE_ID_DACB:
+		enum_id = 2;
+		break;
+	case ENGINE_ID_DACA:
+	default:
+		engine_id = ENGINE_ID_DACA;
+		enum_id = 1;
+		break;
+	}
+
+	bp_result = bios->funcs->dac_load_detection(bios, engine_id, device_type, enum_id);
+	return bp_result == BP_RESULT_OK;
+}
+
 /**
  * Determines if there is an analog sink connected.
  */
@@ -1296,6 +1334,11 @@ static bool link_detect_analog(struct dc_link *link, enum dc_connection_type *ty
 		return true;
 	}
 
+	if (link_detect_dac_load_detect(link)) {
+		*type = dc_connection_single;
+		return true;
+	}
+
 	*type = dc_connection_none;
 	return true;
 }
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 19/20] drm/amd/display: Add common modes to analog displays without EDID
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (17 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 18/20] drm/amd/display: Use DAC load detection on analog connectors Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-23 15:58 ` [PATCH 20/20] drm/amdgpu: Use DC by default for Bonaire Timur Kristóf
  2025-07-30 16:29 ` [PATCH 00/20] Analog connector support in DC Harry Wentland
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

When the EDID of an analog display is not available, we can't
know the possible modes supported by the display. However, we
still need to offer the user to select from a variety of common
modes. It will be up to the user to select the best one, though.

This is how it works on other operating systems as well as the
legacy display code path in amdgpu.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 46 +++++++++++--------
 1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 49ee516dc83d..23333880f4e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8172,7 +8172,7 @@ static void amdgpu_dm_get_native_mode(struct drm_connector *connector)
 
 static struct drm_display_mode *
 amdgpu_dm_create_common_mode(struct drm_encoder *encoder,
-			     char *name,
+			     const char *name,
 			     int hdisplay, int vdisplay)
 {
 	struct drm_device *dev = encoder->dev;
@@ -8194,6 +8194,24 @@ amdgpu_dm_create_common_mode(struct drm_encoder *encoder,
 
 }
 
+static const struct amdgpu_dm_mode_size {
+	char name[DRM_DISPLAY_MODE_LEN];
+	int w;
+	int h;
+} common_modes[] = {
+	{  "640x480",  640,  480},
+	{  "800x600",  800,  600},
+	{ "1024x768", 1024,  768},
+	{ "1280x720", 1280,  720},
+	{ "1280x800", 1280,  800},
+	{"1280x1024", 1280, 1024},
+	{ "1440x900", 1440,  900},
+	{"1680x1050", 1680, 1050},
+	{"1600x1200", 1600, 1200},
+	{"1920x1080", 1920, 1080},
+	{"1920x1200", 1920, 1200}
+};
+
 static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder,
 						 struct drm_connector *connector)
 {
@@ -8204,23 +8222,6 @@ static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder,
 				to_amdgpu_dm_connector(connector);
 	int i;
 	int n;
-	struct mode_size {
-		char name[DRM_DISPLAY_MODE_LEN];
-		int w;
-		int h;
-	} common_modes[] = {
-		{  "640x480",  640,  480},
-		{  "800x600",  800,  600},
-		{ "1024x768", 1024,  768},
-		{ "1280x720", 1280,  720},
-		{ "1280x800", 1280,  800},
-		{"1280x1024", 1280, 1024},
-		{ "1440x900", 1440,  900},
-		{"1680x1050", 1680, 1050},
-		{"1600x1200", 1600, 1200},
-		{"1920x1080", 1920, 1080},
-		{"1920x1200", 1920, 1200}
-	};
 
 	n = ARRAY_SIZE(common_modes);
 
@@ -8440,6 +8441,15 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
 		if (dc->link_srv->dp_get_encoding_format(verified_link_cap) == DP_128b_132b_ENCODING)
 			amdgpu_dm_connector->num_modes +=
 				drm_add_modes_noedid(connector, 1920, 1080);
+
+		if (amdgpu_dm_connector->dc_sink->edid_caps.analog) {
+			/* Analog monitor connected by DAC load detection.
+			 * Add common modes. It will be up to the user to select one that works.
+			 */
+			for (int i = 0; i < ARRAY_SIZE(common_modes); i++)
+				amdgpu_dm_connector->num_modes += drm_add_modes_noedid(
+					connector, common_modes[i].w, common_modes[i].h);
+		}
 	} else {
 		amdgpu_dm_connector_ddc_get_modes(connector, drm_edid);
 		if (encoder && (connector->connector_type != DRM_MODE_CONNECTOR_eDP) &&
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 20/20] drm/amdgpu: Use DC by default for Bonaire
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (18 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 19/20] drm/amd/display: Add common modes to analog displays without EDID Timur Kristóf
@ 2025-07-23 15:58 ` Timur Kristóf
  2025-07-30 16:29 ` [PATCH 00/20] Analog connector support in DC Harry Wentland
  20 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-23 15:58 UTC (permalink / raw)
  To: amd-gfx; +Cc: Timur Kristóf

Now that DC supports analog connectors, there is nothing stopping
us from using it by default on Bonaire.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 3757634613c3..e0798dcb9551 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -4125,7 +4125,6 @@ bool amdgpu_device_asic_has_dc_support(struct pci_dev *pdev,
 #else
 		return false;
 #endif
-	case CHIP_BONAIRE:
 	case CHIP_KAVERI:
 	case CHIP_KABINI:
 	case CHIP_MULLINS:
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-07-23 15:57 ` [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately Timur Kristóf
@ 2025-07-29 18:03   ` Harry Wentland
  2025-07-30  7:40     ` Timur Kristóf
  2025-08-06 14:56   ` Harry Wentland
  1 sibling, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-07-29 18:03 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-07-23 11:57, Timur Kristóf wrote:
> Previously, DC determined the DRM connector type based on the
> signal type, which becomes problematic when a connector may
> support different signal types, such as DVI-I.
> 
> With this patch, it is now determined according to the actual
> connector type in DC, meaning it can now distinguish between
> DVI-D and DVI-I connectors.
> 
> A subsequent commit will enable polling for these connectors.
> 
> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++--------
>  1 file changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 096b23ad4845..c347b232ae06 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -8038,24 +8038,26 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
>  	return 0;
>  }
>  
> -static int to_drm_connector_type(enum signal_type st)
> +static int to_drm_connector_type(uint32_t connector_id)
>  {
> -	switch (st) {
> -	case SIGNAL_TYPE_HDMI_TYPE_A:
> +	switch (connector_id) {
> +	case CONNECTOR_ID_HDMI_TYPE_A:
>  		return DRM_MODE_CONNECTOR_HDMIA;
> -	case SIGNAL_TYPE_EDP:
> +	case CONNECTOR_ID_EDP:
>  		return DRM_MODE_CONNECTOR_eDP;
> -	case SIGNAL_TYPE_LVDS:
> +	case CONNECTOR_ID_LVDS:
>  		return DRM_MODE_CONNECTOR_LVDS;
> -	case SIGNAL_TYPE_RGB:
> +	case CONNECTOR_ID_VGA:
>  		return DRM_MODE_CONNECTOR_VGA;
> -	case SIGNAL_TYPE_DISPLAY_PORT:
> -	case SIGNAL_TYPE_DISPLAY_PORT_MST:
> +	case CONNECTOR_ID_DISPLAY_PORT:
>  		return DRM_MODE_CONNECTOR_DisplayPort;
> -	case SIGNAL_TYPE_DVI_DUAL_LINK:
> -	case SIGNAL_TYPE_DVI_SINGLE_LINK:
> +	case CONNECTOR_ID_SINGLE_LINK_DVID:
> +	case CONNECTOR_ID_DUAL_LINK_DVID:
>  		return DRM_MODE_CONNECTOR_DVID;
> -	case SIGNAL_TYPE_VIRTUAL:
> +	case CONNECTOR_ID_SINGLE_LINK_DVII:
> +	case CONNECTOR_ID_DUAL_LINK_DVII:
> +		return DRM_MODE_CONNECTOR_DVII;
> +	case CONNECTOR_ID_VIRTUAL:
>  		return DRM_MODE_CONNECTOR_VIRTUAL;
>  
>  	default:
> @@ -8440,6 +8442,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
>  			link->link_enc->features.dp_ycbcr420_supported ? true : false;
>  		break;
>  	case DRM_MODE_CONNECTOR_DVID:
> +	case DRM_MODE_CONNECTOR_DVII:
> +	case DRM_MODE_CONNECTOR_VGA:

This seems unrelated and would do better in a separate patch.

Harry

>  		aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
>  		break;
>  	default:
> @@ -8631,7 +8635,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
>  		goto out_free;
>  	}
>  
> -	connector_type = to_drm_connector_type(link->connector_signal);
> +	connector_type = to_drm_connector_type(link->link_id.id);
>  
>  	res = drm_connector_init_with_ddc(
>  			dm->ddev,


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 03/20] drm/amd/display: Introduce MAX_LINK_ENCODERS
  2025-07-23 15:57 ` [PATCH 03/20] drm/amd/display: Introduce MAX_LINK_ENCODERS Timur Kristóf
@ 2025-07-29 18:06   ` Harry Wentland
  2025-07-30  7:40     ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-07-29 18:06 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-07-23 11:57, Timur Kristóf wrote:
> We are going to support analog encoders as well, not just digital,
> so we need to make space for them in various arrays.
> 
> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
>  .../drm/amd/display/dc/core/dc_link_enc_cfg.c |  4 ++--
>  .../gpu/drm/amd/display/dc/inc/core_types.h   |  8 +++----
>  .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 24 +++++++++++++++++++
>  3 files changed, 30 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> index 814f68d76257..d86482611b3f 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> @@ -522,10 +522,10 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link(
>  struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc)
>  {
>  	struct link_encoder *link_enc = NULL;
> -	enum engine_id encs_assigned[MAX_DIG_LINK_ENCODERS];
> +	enum engine_id encs_assigned[MAX_LINK_ENCODERS];
>  	int i;
>  
> -	for (i = 0; i < MAX_DIG_LINK_ENCODERS; i++)
> +	for (i = 0; i < MAX_LINK_ENCODERS; i++)
>  		encs_assigned[i] = ENGINE_ID_UNKNOWN;
>  
>  	/* Add assigned encoders to list. */
> diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> index f0d7185153b2..55daf348293e 100644
> --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> @@ -274,7 +274,7 @@ struct resource_pool {
>  	/* An array for accessing the link encoder objects that have been created.
>  	 * Index in array corresponds to engine ID - viz. 0: ENGINE_ID_DIGA
>  	 */
> -	struct link_encoder *link_encoders[MAX_DIG_LINK_ENCODERS];
> +	struct link_encoder *link_encoders[MAX_LINK_ENCODERS];
>  	/* Number of DIG link encoder objects created - i.e. number of valid
>  	 * entries in link_encoders array.
>  	 */
> @@ -508,7 +508,7 @@ struct pipe_ctx {
>  struct link_enc_cfg_context {
>  	enum link_enc_cfg_mode mode;
>  	struct link_enc_assignment link_enc_assignments[MAX_PIPES];
> -	enum engine_id link_enc_avail[MAX_DIG_LINK_ENCODERS];
> +	enum engine_id link_enc_avail[MAX_LINK_ENCODERS];
>  	struct link_enc_assignment transient_assignments[MAX_PIPES];
>  };
>  
> @@ -520,8 +520,8 @@ struct resource_context {
>  	uint8_t dp_clock_source_ref_count;
>  	bool is_dsc_acquired[MAX_PIPES];
>  	struct link_enc_cfg_context link_enc_cfg_ctx;
> -	unsigned int dio_link_enc_to_link_idx[MAX_DIG_LINK_ENCODERS];
> -	int dio_link_enc_ref_cnts[MAX_DIG_LINK_ENCODERS];
> +	unsigned int dio_link_enc_to_link_idx[MAX_LINK_ENCODERS];
> +	int dio_link_enc_ref_cnts[MAX_LINK_ENCODERS];
>  	bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS];
>  	unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS];
>  	int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS];
> diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
> index 41c76ba9ba56..dc9b9f22c75b 100644
> --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
> +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
> @@ -45,7 +45,31 @@
>  #define MAX_PIPES 6
>  #define MAX_PHANTOM_PIPES (MAX_PIPES / 2)
>  #define MAX_LINKS (MAX_PIPES * 2 +2)
> +
> +/**
> + * define MAX_DIG_LINK_ENCODERS - maximum number of digital encoders
> + *
> + * Digital encoders are ENGINE_ID_DIGA...G, there are at most 7,
> + * although not every GPU may have that many.
> + */
>  #define MAX_DIG_LINK_ENCODERS 7
> +
> +/**
> + * define MAX_DIG_LINK_ENCODERS - maximum number of analog link encoders

_DAC_, not _DIG_

Harry

> + *
> + * Analog encoders are ENGINE_ID_DACA/B, there are at most 2,
> + * although not every GPU may have that many. Modern GPUs typically
> + * don't have analog encoders.
> + */
> +#define MAX_DAC_LINK_ENCODERS 2
> +
> +/**
> + * define MAX_LINK_ENCODERS - maximum number link encoders in total
> + *
> + * This includes both analog and digital encoders.
> + */
> +#define MAX_LINK_ENCODERS (MAX_DIG_LINK_ENCODERS + MAX_DAC_LINK_ENCODERS)
> +
>  #define MAX_DWB_PIPES	1
>  #define MAX_HPO_DP2_ENCODERS	4
>  #define MAX_HPO_DP2_LINK_ENCODERS	4


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-07-23 15:58 ` [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals Timur Kristóf
@ 2025-07-29 18:21   ` Harry Wentland
  2025-07-30  8:19     ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-07-29 18:21 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-07-23 11:58, Timur Kristóf wrote:
> Features like stereo sync and audio are not supported by RGB
> signals, so don't try to use them.
> 

Where does it say that?

Harry

> Also add a dc_is_rgb_signal similar to other dc_is_*_signal.
> 
> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
>  drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c | 3 ++-
>  drivers/gpu/drm/amd/display/dc/link/link_dpms.c          | 6 ++++--
>  drivers/gpu/drm/amd/display/include/signal_types.h       | 5 +++++
>  3 files changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> index b68bcc9fca0a..f3470716734d 100644
> --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> @@ -115,7 +115,8 @@ void setup_dio_stream_attribute(struct pipe_ctx *pipe_ctx)
>  	struct dc_stream_state *stream = pipe_ctx->stream;
>  	struct dc_link *link = stream->link;
>  
> -	if (!dc_is_virtual_signal(stream->signal))
> +	if (!dc_is_virtual_signal(stream->signal) &&
> +		!dc_is_rgb_signal(stream->signal))
>  		stream_encoder->funcs->setup_stereo_sync(
>  				stream_encoder,
>  				pipe_ctx->stream_res.tg->inst,
> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> index 8c8682f743d6..d6b7347c6c11 100644
> --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> @@ -2369,7 +2369,8 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
>  			set_avmute(pipe_ctx, true);
>  	}
>  
> -	dc->hwss.disable_audio_stream(pipe_ctx);
> +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> +		dc->hwss.disable_audio_stream(pipe_ctx);
>  
>  	update_psp_stream_config(pipe_ctx, true);
>  	dc->hwss.blank_stream(pipe_ctx);
> @@ -2656,7 +2657,8 @@ void link_set_dpms_on(
>  		enable_stream_features(pipe_ctx);
>  	update_psp_stream_config(pipe_ctx, false);
>  
> -	dc->hwss.enable_audio_stream(pipe_ctx);
> +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> +		dc->hwss.enable_audio_stream(pipe_ctx);
>  
>  	if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
>  		set_avmute(pipe_ctx, false);
> diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h b/drivers/gpu/drm/amd/display/include/signal_types.h
> index a10d6b988aab..825a08fcb125 100644
> --- a/drivers/gpu/drm/amd/display/include/signal_types.h
> +++ b/drivers/gpu/drm/amd/display/include/signal_types.h
> @@ -118,6 +118,11 @@ static inline bool dc_is_dvi_signal(enum signal_type signal)
>  	}
>  }
>  
> +static inline bool dc_is_rgb_signal(enum signal_type signal)
> +{
> +	return (signal == SIGNAL_TYPE_RGB);
> +}
> +
>  static inline bool dc_is_tmds_signal(enum signal_type signal)
>  {
>  	switch (signal) {


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-07-29 18:03   ` Harry Wentland
@ 2025-07-30  7:40     ` Timur Kristóf
  2025-07-30 14:30       ` Harry Wentland
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-07-30  7:40 UTC (permalink / raw)
  To: Harry Wentland, amd-gfx

On Tue, 2025-07-29 at 14:03 -0400, Harry Wentland wrote:
> 
> 
> On 2025-07-23 11:57, Timur Kristóf wrote:
> > Previously, DC determined the DRM connector type based on the
> > signal type, which becomes problematic when a connector may
> > support different signal types, such as DVI-I.
> > 
> > With this patch, it is now determined according to the actual
> > connector type in DC, meaning it can now distinguish between
> > DVI-D and DVI-I connectors.
> > 
> > A subsequent commit will enable polling for these connectors.
> > 
> > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > ---
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++----
> > ----
> >  1 file changed, 16 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > index 096b23ad4845..c347b232ae06 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -8038,24 +8038,26 @@ static int
> > dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
> >  	return 0;
> >  }
> >  
> > -static int to_drm_connector_type(enum signal_type st)
> > +static int to_drm_connector_type(uint32_t connector_id)
> >  {
> > -	switch (st) {
> > -	case SIGNAL_TYPE_HDMI_TYPE_A:
> > +	switch (connector_id) {
> > +	case CONNECTOR_ID_HDMI_TYPE_A:
> >  		return DRM_MODE_CONNECTOR_HDMIA;
> > -	case SIGNAL_TYPE_EDP:
> > +	case CONNECTOR_ID_EDP:
> >  		return DRM_MODE_CONNECTOR_eDP;
> > -	case SIGNAL_TYPE_LVDS:
> > +	case CONNECTOR_ID_LVDS:
> >  		return DRM_MODE_CONNECTOR_LVDS;
> > -	case SIGNAL_TYPE_RGB:
> > +	case CONNECTOR_ID_VGA:
> >  		return DRM_MODE_CONNECTOR_VGA;
> > -	case SIGNAL_TYPE_DISPLAY_PORT:
> > -	case SIGNAL_TYPE_DISPLAY_PORT_MST:
> > +	case CONNECTOR_ID_DISPLAY_PORT:
> >  		return DRM_MODE_CONNECTOR_DisplayPort;
> > -	case SIGNAL_TYPE_DVI_DUAL_LINK:
> > -	case SIGNAL_TYPE_DVI_SINGLE_LINK:
> > +	case CONNECTOR_ID_SINGLE_LINK_DVID:
> > +	case CONNECTOR_ID_DUAL_LINK_DVID:
> >  		return DRM_MODE_CONNECTOR_DVID;
> > -	case SIGNAL_TYPE_VIRTUAL:
> > +	case CONNECTOR_ID_SINGLE_LINK_DVII:
> > +	case CONNECTOR_ID_DUAL_LINK_DVII:
> > +		return DRM_MODE_CONNECTOR_DVII;
> > +	case CONNECTOR_ID_VIRTUAL:
> >  		return DRM_MODE_CONNECTOR_VIRTUAL;
> >  
> >  	default:
> > @@ -8440,6 +8442,8 @@ void amdgpu_dm_connector_init_helper(struct
> > amdgpu_display_manager *dm,
> >  			link->link_enc-
> > >features.dp_ycbcr420_supported ? true : false;
> >  		break;
> >  	case DRM_MODE_CONNECTOR_DVID:
> > +	case DRM_MODE_CONNECTOR_DVII:
> > +	case DRM_MODE_CONNECTOR_VGA:
> 
> This seems unrelated and would do better in a separate patch.
> 
> Harry

Keep in mind that currently DC recognizes DVI-I as DVI-D, but after
this patch they will be recognized correctly as DVI-I. So without this
part, the patch will regress the hotplug capability of those ports.

That said, sure, I can move this part to a separate commit before this
one, if you prefer.

Timur

> 
> >  		aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
> >  		break;
> >  	default:
> > @@ -8631,7 +8635,7 @@ static int amdgpu_dm_connector_init(struct
> > amdgpu_display_manager *dm,
> >  		goto out_free;
> >  	}
> >  
> > -	connector_type = to_drm_connector_type(link-
> > >connector_signal);
> > +	connector_type = to_drm_connector_type(link->link_id.id);
> >  
> >  	res = drm_connector_init_with_ddc(
> >  			dm->ddev,

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 03/20] drm/amd/display: Introduce MAX_LINK_ENCODERS
  2025-07-29 18:06   ` Harry Wentland
@ 2025-07-30  7:40     ` Timur Kristóf
  0 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-30  7:40 UTC (permalink / raw)
  To: Harry Wentland, amd-gfx

On Tue, 2025-07-29 at 14:06 -0400, Harry Wentland wrote:
> 
> 
> On 2025-07-23 11:57, Timur Kristóf wrote:
> > We are going to support analog encoders as well, not just digital,
> > so we need to make space for them in various arrays.
> > 
> > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > ---
> >  .../drm/amd/display/dc/core/dc_link_enc_cfg.c |  4 ++--
> >  .../gpu/drm/amd/display/dc/inc/core_types.h   |  8 +++----
> >  .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 24
> > +++++++++++++++++++
> >  3 files changed, 30 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> > b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> > index 814f68d76257..d86482611b3f 100644
> > --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> > +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> > @@ -522,10 +522,10 @@ struct link_encoder
> > *link_enc_cfg_get_link_enc_used_by_link(
> >  struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct
> > dc *dc)
> >  {
> >  	struct link_encoder *link_enc = NULL;
> > -	enum engine_id encs_assigned[MAX_DIG_LINK_ENCODERS];
> > +	enum engine_id encs_assigned[MAX_LINK_ENCODERS];
> >  	int i;
> >  
> > -	for (i = 0; i < MAX_DIG_LINK_ENCODERS; i++)
> > +	for (i = 0; i < MAX_LINK_ENCODERS; i++)
> >  		encs_assigned[i] = ENGINE_ID_UNKNOWN;
> >  
> >  	/* Add assigned encoders to list. */
> > diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> > b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> > index f0d7185153b2..55daf348293e 100644
> > --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> > +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
> > @@ -274,7 +274,7 @@ struct resource_pool {
> >  	/* An array for accessing the link encoder objects that
> > have been created.
> >  	 * Index in array corresponds to engine ID - viz. 0:
> > ENGINE_ID_DIGA
> >  	 */
> > -	struct link_encoder *link_encoders[MAX_DIG_LINK_ENCODERS];
> > +	struct link_encoder *link_encoders[MAX_LINK_ENCODERS];
> >  	/* Number of DIG link encoder objects created - i.e.
> > number of valid
> >  	 * entries in link_encoders array.
> >  	 */
> > @@ -508,7 +508,7 @@ struct pipe_ctx {
> >  struct link_enc_cfg_context {
> >  	enum link_enc_cfg_mode mode;
> >  	struct link_enc_assignment
> > link_enc_assignments[MAX_PIPES];
> > -	enum engine_id link_enc_avail[MAX_DIG_LINK_ENCODERS];
> > +	enum engine_id link_enc_avail[MAX_LINK_ENCODERS];
> >  	struct link_enc_assignment
> > transient_assignments[MAX_PIPES];
> >  };
> >  
> > @@ -520,8 +520,8 @@ struct resource_context {
> >  	uint8_t dp_clock_source_ref_count;
> >  	bool is_dsc_acquired[MAX_PIPES];
> >  	struct link_enc_cfg_context link_enc_cfg_ctx;
> > -	unsigned int
> > dio_link_enc_to_link_idx[MAX_DIG_LINK_ENCODERS];
> > -	int dio_link_enc_ref_cnts[MAX_DIG_LINK_ENCODERS];
> > +	unsigned int dio_link_enc_to_link_idx[MAX_LINK_ENCODERS];
> > +	int dio_link_enc_ref_cnts[MAX_LINK_ENCODERS];
> >  	bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS];
> >  	unsigned int
> > hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS];
> >  	int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS];
> > diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
> > b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
> > index 41c76ba9ba56..dc9b9f22c75b 100644
> > --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
> > +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
> > @@ -45,7 +45,31 @@
> >  #define MAX_PIPES 6
> >  #define MAX_PHANTOM_PIPES (MAX_PIPES / 2)
> >  #define MAX_LINKS (MAX_PIPES * 2 +2)
> > +
> > +/**
> > + * define MAX_DIG_LINK_ENCODERS - maximum number of digital
> > encoders
> > + *
> > + * Digital encoders are ENGINE_ID_DIGA...G, there are at most 7,
> > + * although not every GPU may have that many.
> > + */
> >  #define MAX_DIG_LINK_ENCODERS 7
> > +
> > +/**
> > + * define MAX_DIG_LINK_ENCODERS - maximum number of analog link
> > encoders
> 
> _DAC_, not _DIG_
> 
> Harry

That's a typo, will fix.

Timur.

> 
> > + *
> > + * Analog encoders are ENGINE_ID_DACA/B, there are at most 2,
> > + * although not every GPU may have that many. Modern GPUs
> > typically
> > + * don't have analog encoders.
> > + */
> > +#define MAX_DAC_LINK_ENCODERS 2
> > +
> > +/**
> > + * define MAX_LINK_ENCODERS - maximum number link encoders in
> > total
> > + *
> > + * This includes both analog and digital encoders.
> > + */
> > +#define MAX_LINK_ENCODERS (MAX_DIG_LINK_ENCODERS +
> > MAX_DAC_LINK_ENCODERS)
> > +
> >  #define MAX_DWB_PIPES	1
> >  #define MAX_HPO_DP2_ENCODERS	4
> >  #define MAX_HPO_DP2_LINK_ENCODERS	4

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-07-29 18:21   ` Harry Wentland
@ 2025-07-30  8:19     ` Timur Kristóf
  2025-07-30 14:34       ` Harry Wentland
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-07-30  8:19 UTC (permalink / raw)
  To: Harry Wentland, amd-gfx

On Tue, 2025-07-29 at 14:21 -0400, Harry Wentland wrote:
> 
> 
> On 2025-07-23 11:58, Timur Kristóf wrote:
> > Features like stereo sync and audio are not supported by RGB
> > signals, so don't try to use them.
> > 
> 
> Where does it say that?
> 
> Harry

1. Audio

VGA ports (and the analog part of DVI-I ports) simply cannot carry
audio. So there is no hardware to control any audio, therefore there is
nothing for this code to enable, which is why I added those ifs to not
even try to enable audio on analog video signals.

As a side note, DVI-D ports (and the digital part of DVI-I ports) may
have a non-standard extension to carry digital audio signals, but that
is not revelant to supporting analog displays.

2. Stereo sync

With regards to stereo sync, I didn't find any reference to this in the
legacy display code, so I assumed either it is unsupported or the VBIOS
already sets it up correctly. At least, considering that the legacy
code didn't bother setting it up, we don't lose any functionality if we
leave it out of DC as well.

That being said, upon some further digging in the DCE register files, I
found a register called DAC_STEREOSYNC_SELECT so maybe I could
investigate using that. Maybe it would be better to work with the
registers directly instead of the VBIOS? Would it be okay to
investigate that further in a future patch series once this one is
merged?

Thanks,
Timur



> 
> > Also add a dc_is_rgb_signal similar to other dc_is_*_signal.
> > 
> > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > ---
> >  drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c | 3 ++-
> >  drivers/gpu/drm/amd/display/dc/link/link_dpms.c          | 6 ++++-
> > -
> >  drivers/gpu/drm/amd/display/include/signal_types.h       | 5 +++++
> >  3 files changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git
> > a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > index b68bcc9fca0a..f3470716734d 100644
> > --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > @@ -115,7 +115,8 @@ void setup_dio_stream_attribute(struct pipe_ctx
> > *pipe_ctx)
> >  	struct dc_stream_state *stream = pipe_ctx->stream;
> >  	struct dc_link *link = stream->link;
> >  
> > -	if (!dc_is_virtual_signal(stream->signal))
> > +	if (!dc_is_virtual_signal(stream->signal) &&
> > +		!dc_is_rgb_signal(stream->signal))
> >  		stream_encoder->funcs->setup_stereo_sync(
> >  				stream_encoder,
> >  				pipe_ctx->stream_res.tg->inst,
> > diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > index 8c8682f743d6..d6b7347c6c11 100644
> > --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > @@ -2369,7 +2369,8 @@ void link_set_dpms_off(struct pipe_ctx
> > *pipe_ctx)
> >  			set_avmute(pipe_ctx, true);
> >  	}
> >  
> > -	dc->hwss.disable_audio_stream(pipe_ctx);
> > +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > +		dc->hwss.disable_audio_stream(pipe_ctx);
> >  
> >  	update_psp_stream_config(pipe_ctx, true);
> >  	dc->hwss.blank_stream(pipe_ctx);
> > @@ -2656,7 +2657,8 @@ void link_set_dpms_on(
> >  		enable_stream_features(pipe_ctx);
> >  	update_psp_stream_config(pipe_ctx, false);
> >  
> > -	dc->hwss.enable_audio_stream(pipe_ctx);
> > +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > +		dc->hwss.enable_audio_stream(pipe_ctx);
> >  
> >  	if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
> >  		set_avmute(pipe_ctx, false);
> > diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h
> > b/drivers/gpu/drm/amd/display/include/signal_types.h
> > index a10d6b988aab..825a08fcb125 100644
> > --- a/drivers/gpu/drm/amd/display/include/signal_types.h
> > +++ b/drivers/gpu/drm/amd/display/include/signal_types.h
> > @@ -118,6 +118,11 @@ static inline bool dc_is_dvi_signal(enum
> > signal_type signal)
> >  	}
> >  }
> >  
> > +static inline bool dc_is_rgb_signal(enum signal_type signal)
> > +{
> > +	return (signal == SIGNAL_TYPE_RGB);
> > +}
> > +
> >  static inline bool dc_is_tmds_signal(enum signal_type signal)
> >  {
> >  	switch (signal) {

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-07-30  7:40     ` Timur Kristóf
@ 2025-07-30 14:30       ` Harry Wentland
  2025-07-30 17:03         ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-07-30 14:30 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-07-30 03:40, Timur Kristóf wrote:
> On Tue, 2025-07-29 at 14:03 -0400, Harry Wentland wrote:
>>
>>
>> On 2025-07-23 11:57, Timur Kristóf wrote:
>>> Previously, DC determined the DRM connector type based on the
>>> signal type, which becomes problematic when a connector may
>>> support different signal types, such as DVI-I.
>>>
>>> With this patch, it is now determined according to the actual
>>> connector type in DC, meaning it can now distinguish between
>>> DVI-D and DVI-I connectors.
>>>
>>> A subsequent commit will enable polling for these connectors.
>>>
>>> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
>>> ---
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++----
>>> ----
>>>  1 file changed, 16 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> index 096b23ad4845..c347b232ae06 100644
>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> @@ -8038,24 +8038,26 @@ static int
>>> dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
>>>  	return 0;
>>>  }
>>>  
>>> -static int to_drm_connector_type(enum signal_type st)
>>> +static int to_drm_connector_type(uint32_t connector_id)
>>>  {
>>> -	switch (st) {
>>> -	case SIGNAL_TYPE_HDMI_TYPE_A:
>>> +	switch (connector_id) {
>>> +	case CONNECTOR_ID_HDMI_TYPE_A:
>>>  		return DRM_MODE_CONNECTOR_HDMIA;
>>> -	case SIGNAL_TYPE_EDP:
>>> +	case CONNECTOR_ID_EDP:
>>>  		return DRM_MODE_CONNECTOR_eDP;
>>> -	case SIGNAL_TYPE_LVDS:
>>> +	case CONNECTOR_ID_LVDS:
>>>  		return DRM_MODE_CONNECTOR_LVDS;
>>> -	case SIGNAL_TYPE_RGB:
>>> +	case CONNECTOR_ID_VGA:
>>>  		return DRM_MODE_CONNECTOR_VGA;
>>> -	case SIGNAL_TYPE_DISPLAY_PORT:
>>> -	case SIGNAL_TYPE_DISPLAY_PORT_MST:
>>> +	case CONNECTOR_ID_DISPLAY_PORT:
>>>  		return DRM_MODE_CONNECTOR_DisplayPort;
>>> -	case SIGNAL_TYPE_DVI_DUAL_LINK:
>>> -	case SIGNAL_TYPE_DVI_SINGLE_LINK:
>>> +	case CONNECTOR_ID_SINGLE_LINK_DVID:
>>> +	case CONNECTOR_ID_DUAL_LINK_DVID:
>>>  		return DRM_MODE_CONNECTOR_DVID;
>>> -	case SIGNAL_TYPE_VIRTUAL:
>>> +	case CONNECTOR_ID_SINGLE_LINK_DVII:
>>> +	case CONNECTOR_ID_DUAL_LINK_DVII:
>>> +		return DRM_MODE_CONNECTOR_DVII;
>>> +	case CONNECTOR_ID_VIRTUAL:
>>>  		return DRM_MODE_CONNECTOR_VIRTUAL;
>>>  
>>>  	default:
>>> @@ -8440,6 +8442,8 @@ void amdgpu_dm_connector_init_helper(struct
>>> amdgpu_display_manager *dm,
>>>  			link->link_enc-
>>>> features.dp_ycbcr420_supported ? true : false;
>>>  		break;
>>>  	case DRM_MODE_CONNECTOR_DVID:
>>> +	case DRM_MODE_CONNECTOR_DVII:
>>> +	case DRM_MODE_CONNECTOR_VGA:
>>
>> This seems unrelated and would do better in a separate patch.
>>
>> Harry
> 
> Keep in mind that currently DC recognizes DVI-I as DVI-D, but after
> this patch they will be recognized correctly as DVI-I. So without this
> part, the patch will regress the hotplug capability of those ports.
> 

How will it regress when your patch series introduces analog support?
Without that there shouldn't be DVII or VGA connectors.

Harry

> That said, sure, I can move this part to a separate commit before this
> one, if you prefer.
> 
> Timur
> 
>>
>>>  		aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
>>>  		break;
>>>  	default:
>>> @@ -8631,7 +8635,7 @@ static int amdgpu_dm_connector_init(struct
>>> amdgpu_display_manager *dm,
>>>  		goto out_free;
>>>  	}
>>>  
>>> -	connector_type = to_drm_connector_type(link-
>>>> connector_signal);
>>> +	connector_type = to_drm_connector_type(link->link_id.id);
>>>  
>>>  	res = drm_connector_init_with_ddc(
>>>  			dm->ddev,


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-07-30  8:19     ` Timur Kristóf
@ 2025-07-30 14:34       ` Harry Wentland
  2025-07-30 17:08         ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-07-30 14:34 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-07-30 04:19, Timur Kristóf wrote:
> On Tue, 2025-07-29 at 14:21 -0400, Harry Wentland wrote:
>>
>>
>> On 2025-07-23 11:58, Timur Kristóf wrote:
>>> Features like stereo sync and audio are not supported by RGB
>>> signals, so don't try to use them.
>>>
>>
>> Where does it say that?
>>
>> Harry
> 
> 1. Audio
> 
> VGA ports (and the analog part of DVI-I ports) simply cannot carry
> audio. So there is no hardware to control any audio, therefore there is
> nothing for this code to enable, which is why I added those ifs to not
> even try to enable audio on analog video signals.
> 

My bad, I was thinking RGB as opposed to YCbCr. Forgot that we use
RGB signal to refer to VGA.

> As a side note, DVI-D ports (and the digital part of DVI-I ports) may
> have a non-standard extension to carry digital audio signals, but that
> is not revelant to supporting analog displays.
> 
> 2. Stereo sync
> 
> With regards to stereo sync, I didn't find any reference to this in the
> legacy display code, so I assumed either it is unsupported or the VBIOS
> already sets it up correctly. At least, considering that the legacy
> code didn't bother setting it up, we don't lose any functionality if we
> leave it out of DC as well.
> 
> That being said, upon some further digging in the DCE register files, I
> found a register called DAC_STEREOSYNC_SELECT so maybe I could
> investigate using that. Maybe it would be better to work with the
> registers directly instead of the VBIOS? Would it be okay to
> investigate that further in a future patch series once this one is
> merged?
> 

I don't think DC supports stereo sync currently. I'm not sure there is
much value in pursuing that.

>>> diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h
>>> b/drivers/gpu/drm/amd/display/include/signal_types.h
>>> index a10d6b988aab..825a08fcb125 100644
>>> --- a/drivers/gpu/drm/amd/display/include/signal_types.h
>>> +++ b/drivers/gpu/drm/amd/display/include/signal_types.h
>>> @@ -118,6 +118,11 @@ static inline bool dc_is_dvi_signal(enum
>>> signal_type signal)
>>>  	}
>>>  }
>>>  
>>> +static inline bool dc_is_rgb_signal(enum signal_type signal)

To avoid confusion with people that haven't worked on analog
signals in years (or ever) it might be better to name this
dc_is_analog_signal.

Harry

>>> +{
>>> +	return (signal == SIGNAL_TYPE_RGB);
>>> +}
>>> +
>>>  static inline bool dc_is_tmds_signal(enum signal_type signal)
>>>  {
>>>  	switch (signal) {


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 00/20] Analog connector support in DC
  2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
                   ` (19 preceding siblings ...)
  2025-07-23 15:58 ` [PATCH 20/20] drm/amdgpu: Use DC by default for Bonaire Timur Kristóf
@ 2025-07-30 16:29 ` Harry Wentland
  2025-07-30 17:15   ` Timur Kristóf
  20 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-07-30 16:29 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-07-23 11:57, Timur Kristóf wrote:
> This series adds support for analog connectors to DC for DCE6-10.
> There are two reasons to add this support:
> 
> 1. GPUs that already use DC by default and have analog connectors.
> Some Tonga and Hawaii graphics cards in fact have DVI-I connectors,
> and the analog part doesn't work by default. This functionality
> regressed when switching from the amdgpu legacy display code to DC.
> 
> 2. GPUs that don't use amdgpu by default yet.
> Currently, SI (GFX6) and CIK (GFX7) don't use amdgpu by default
> yet, and missing analog connector support is cited as one of the
> main reasons why not.
> 
> With this analog support added to DC, we could already fully switch
> CIK discrete GPUs to use DC and switch them to the amdgpu driver.
> For GFX7 APUs and SI, further fixes are needed before enabling DC.
> 
> Before starting this work, I asked Harry and Alex about how best
> to do it and we agreed that we'd like to use the VBIOS to set up
> the DAC. So I used the amdgpu legacy display code as a reference.
> The first few commits add some minor changes to DC to prepare for
> supporting analog stream and link encoders, then analog link
> detection is added along with polling, and finally DAC load
> detection support, which is useful for old displays and adapters.
> 

The series looks good to me.

Patches 2-20 are
Reviewed-by: Harry Wentland <harry.wentland@amd.com>

Patch 1 is probably good, just waiting for feedback on my comments.

Though I would like to send this through our weekly testing cycle
before we merge to ensure it doesn't regress DCN in some non-obvious
ways.

Harry

> Please let me know what you think.
> 
> Timur Kristóf (20):
>   drm/amd/display: Determine DRM connector type more accurately
>   drm/amd/display: Add analog bit to edid_caps
>   drm/amd/display: Introduce MAX_LINK_ENCODERS
>   drm/amd/display: Hook up DAC to bios_parser_encoder_control
>   drm/amd/display: Add SelectCRTC_Source to BIOS parser
>   drm/amd/display: Get maximum pixel clock from VBIOS
>   drm/amd/display: Don't use stereo sync and audio on RGB signals
>   drm/amd/display: Don't try to enable/disable HPD when unavailable
>   drm/amd/display: Add concept of analog encoders
>   drm/amd/display: Implement DCE analog stream encoders
>   drm/amd/display: Implement DCE analog link encoders
>   drm/amd/display: Support DAC in dce110_hwseq
>   drm/amd/display: Add analog link detection
>   drm/amd/display: Poll analog connectors
>   drm/amd/display: Add DCE BIOS_SCRATCH_0 register
>   drm/amd/display: Make get_support_mask_for_device_id reusable
>   drm/amd/display: Add DAC_LoadDetection to BIOS parser
>   drm/amd/display: Use DAC load detection on analog connectors
>   drm/amd/display: Add common modes to analog displays without EDID
>   drm/amdgpu: Use DC by default for Bonaire
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |   1 -
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 144 +++++++--
>  .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |   5 +-
>  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |   1 +
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |   8 +
>  .../gpu/drm/amd/display/dc/bios/bios_parser.c |  95 +++++-
>  .../drm/amd/display/dc/bios/command_table.c   | 286 ++++++++++++++++++
>  .../drm/amd/display/dc/bios/command_table.h   |   6 +
>  .../drm/amd/display/dc/core/dc_link_enc_cfg.c |   4 +-
>  .../gpu/drm/amd/display/dc/core/dc_resource.c |   8 +
>  .../gpu/drm/amd/display/dc/dc_bios_types.h    |   9 +
>  drivers/gpu/drm/amd/display/dc/dc_types.h     |   5 +
>  .../drm/amd/display/dc/dce/dce_link_encoder.c | 100 ++++++
>  .../drm/amd/display/dc/dce/dce_link_encoder.h |  21 +-
>  .../amd/display/dc/dce/dce_stream_encoder.c   |  14 +
>  .../amd/display/dc/dce/dce_stream_encoder.h   |   5 +
>  .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  75 ++++-
>  .../gpu/drm/amd/display/dc/inc/core_types.h   |   8 +-
>  .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h |  24 ++
>  .../drm/amd/display/dc/inc/hw/link_encoder.h  |   2 +
>  drivers/gpu/drm/amd/display/dc/inc/resource.h |   1 +
>  .../amd/display/dc/link/hwss/link_hwss_dio.c  |  19 +-
>  .../drm/amd/display/dc/link/link_detection.c  | 123 +++++++-
>  .../gpu/drm/amd/display/dc/link/link_dpms.c   |   9 +-
>  .../drm/amd/display/dc/link/link_factory.c    |  31 ++
>  .../dc/resource/dce100/dce100_resource.c      |  28 +-
>  .../dc/resource/dce110/dce110_resource.c      |   2 +
>  .../dc/resource/dce112/dce112_resource.c      |   2 +
>  .../dc/resource/dce120/dce120_resource.c      |   1 +
>  .../dc/resource/dce60/dce60_resource.c        |  26 +-
>  .../dc/resource/dce80/dce80_resource.c        |  23 +-
>  .../amd/display/include/bios_parser_types.h   |  11 +-
>  .../display/include/grph_object_ctrl_defs.h   |   1 +
>  .../drm/amd/display/include/signal_types.h    |   5 +
>  34 files changed, 1027 insertions(+), 76 deletions(-)
> 


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-07-30 14:30       ` Harry Wentland
@ 2025-07-30 17:03         ` Timur Kristóf
  2025-07-30 17:29           ` Harry Wentland
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-07-30 17:03 UTC (permalink / raw)
  To: Harry Wentland, amd-gfx

On Wed, 2025-07-30 at 10:30 -0400, Harry Wentland wrote:
> 
> 
> On 2025-07-30 03:40, Timur Kristóf wrote:
> > On Tue, 2025-07-29 at 14:03 -0400, Harry Wentland wrote:
> > > 
> > > 
> > > On 2025-07-23 11:57, Timur Kristóf wrote:
> > > > Previously, DC determined the DRM connector type based on the
> > > > signal type, which becomes problematic when a connector may
> > > > support different signal types, such as DVI-I.
> > > > 
> > > > With this patch, it is now determined according to the actual
> > > > connector type in DC, meaning it can now distinguish between
> > > > DVI-D and DVI-I connectors.
> > > > 
> > > > A subsequent commit will enable polling for these connectors.
> > > > 
> > > > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > > > ---
> > > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28
> > > > +++++++++++----
> > > > ----
> > > >  1 file changed, 16 insertions(+), 12 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > index 096b23ad4845..c347b232ae06 100644
> > > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > @@ -8038,24 +8038,26 @@ static int
> > > > dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state
> > > > *state,
> > > >  	return 0;
> > > >  }
> > > >  
> > > > -static int to_drm_connector_type(enum signal_type st)
> > > > +static int to_drm_connector_type(uint32_t connector_id)
> > > >  {
> > > > -	switch (st) {
> > > > -	case SIGNAL_TYPE_HDMI_TYPE_A:
> > > > +	switch (connector_id) {
> > > > +	case CONNECTOR_ID_HDMI_TYPE_A:
> > > >  		return DRM_MODE_CONNECTOR_HDMIA;
> > > > -	case SIGNAL_TYPE_EDP:
> > > > +	case CONNECTOR_ID_EDP:
> > > >  		return DRM_MODE_CONNECTOR_eDP;
> > > > -	case SIGNAL_TYPE_LVDS:
> > > > +	case CONNECTOR_ID_LVDS:
> > > >  		return DRM_MODE_CONNECTOR_LVDS;
> > > > -	case SIGNAL_TYPE_RGB:
> > > > +	case CONNECTOR_ID_VGA:
> > > >  		return DRM_MODE_CONNECTOR_VGA;
> > > > -	case SIGNAL_TYPE_DISPLAY_PORT:
> > > > -	case SIGNAL_TYPE_DISPLAY_PORT_MST:
> > > > +	case CONNECTOR_ID_DISPLAY_PORT:
> > > >  		return DRM_MODE_CONNECTOR_DisplayPort;
> > > > -	case SIGNAL_TYPE_DVI_DUAL_LINK:
> > > > -	case SIGNAL_TYPE_DVI_SINGLE_LINK:
> > > > +	case CONNECTOR_ID_SINGLE_LINK_DVID:
> > > > +	case CONNECTOR_ID_DUAL_LINK_DVID:
> > > >  		return DRM_MODE_CONNECTOR_DVID;
> > > > -	case SIGNAL_TYPE_VIRTUAL:
> > > > +	case CONNECTOR_ID_SINGLE_LINK_DVII:
> > > > +	case CONNECTOR_ID_DUAL_LINK_DVII:
> > > > +		return DRM_MODE_CONNECTOR_DVII;
> > > > +	case CONNECTOR_ID_VIRTUAL:
> > > >  		return DRM_MODE_CONNECTOR_VIRTUAL;
> > > >  
> > > >  	default:
> > > > @@ -8440,6 +8442,8 @@ void
> > > > amdgpu_dm_connector_init_helper(struct
> > > > amdgpu_display_manager *dm,
> > > >  			link->link_enc-
> > > > > features.dp_ycbcr420_supported ? true : false;
> > > >  		break;
> > > >  	case DRM_MODE_CONNECTOR_DVID:
> > > > +	case DRM_MODE_CONNECTOR_DVII:
> > > > +	case DRM_MODE_CONNECTOR_VGA:
> > > 
> > > This seems unrelated and would do better in a separate patch.
> > > 
> > > Harry
> > 
> > Keep in mind that currently DC recognizes DVI-I as DVI-D, but after
> > this patch they will be recognized correctly as DVI-I. So without
> > this
> > part, the patch will regress the hotplug capability of those ports.
> > 
> 
> How will it regress when your patch series introduces analog support?
> Without that there shouldn't be DVII or VGA connectors.
> 
> Harry

DVI-I can carry either an analog or a digital signal.

Before this patch, the DVI-I ports were recognized by DRM as
DRM_MODE_CONNECTOR_DVID and their digital part was already working.
That means you can plug in a digital DVI cable in a DVI-I port and it
will work today.

After this patch they will be recognized as DRM_MODE_CONNECTOR_DVII
instead, so in order to keep the same behaviour as before and avoid
regressing the digital part, we need to set DRM_CONNECTOR_POLL_HPD, and
in order to do that we need to add DRM_MODE_CONNECTOR_DVII to this
switch statement.

That being said, I can move this hunk to a separate patch before this
one. That way there is going to be no regression and this patch stays
simpler.

Does that sound ok to you?

Timur

> 
> > That said, sure, I can move this part to a separate commit before
> > this
> > one, if you prefer.
> > 
> > Timur
> > 
> > > 
> > > >  		aconnector->base.polled =
> > > > DRM_CONNECTOR_POLL_HPD;
> > > >  		break;
> > > >  	default:
> > > > @@ -8631,7 +8635,7 @@ static int
> > > > amdgpu_dm_connector_init(struct
> > > > amdgpu_display_manager *dm,
> > > >  		goto out_free;
> > > >  	}
> > > >  
> > > > -	connector_type = to_drm_connector_type(link-
> > > > > connector_signal);
> > > > +	connector_type = to_drm_connector_type(link-
> > > > >link_id.id);
> > > >  
> > > >  	res = drm_connector_init_with_ddc(
> > > >  			dm->ddev,

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-07-30 14:34       ` Harry Wentland
@ 2025-07-30 17:08         ` Timur Kristóf
  2025-07-31 15:37           ` Harry Wentland
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-07-30 17:08 UTC (permalink / raw)
  To: Harry Wentland, amd-gfx

On Wed, 2025-07-30 at 10:34 -0400, Harry Wentland wrote:
> 
> 
> On 2025-07-30 04:19, Timur Kristóf wrote:
> > On Tue, 2025-07-29 at 14:21 -0400, Harry Wentland wrote:
> > > 
> > > 
> > > On 2025-07-23 11:58, Timur Kristóf wrote:
> > > > Features like stereo sync and audio are not supported by RGB
> > > > signals, so don't try to use them.
> > > > 
> > > 
> > > Where does it say that?
> > > 
> > > Harry
> > 
> > 1. Audio
> > 
> > VGA ports (and the analog part of DVI-I ports) simply cannot carry
> > audio. So there is no hardware to control any audio, therefore
> > there is
> > nothing for this code to enable, which is why I added those ifs to
> > not
> > even try to enable audio on analog video signals.
> > 
> 
> My bad, I was thinking RGB as opposed to YCbCr. Forgot that we use
> RGB signal to refer to VGA.

Sorry for the confusion.

> 
> > As a side note, DVI-D ports (and the digital part of DVI-I ports)
> > may
> > have a non-standard extension to carry digital audio signals, but
> > that
> > is not revelant to supporting analog displays.
> > 
> > 2. Stereo sync
> > 
> > With regards to stereo sync, I didn't find any reference to this in
> > the
> > legacy display code, so I assumed either it is unsupported or the
> > VBIOS
> > already sets it up correctly. At least, considering that the legacy
> > code didn't bother setting it up, we don't lose any functionality
> > if we
> > leave it out of DC as well.
> > 
> > That being said, upon some further digging in the DCE register
> > files, I
> > found a register called DAC_STEREOSYNC_SELECT so maybe I could
> > investigate using that. Maybe it would be better to work with the
> > registers directly instead of the VBIOS? Would it be okay to
> > investigate that further in a future patch series once this one is
> > merged?
> > 
> 
> I don't think DC supports stereo sync currently. I'm not sure there
> is
> much value in pursuing that.

If stereo sync is not supported, what does setup_stereo_sync() do?

> 
> > > > diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > b/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > index a10d6b988aab..825a08fcb125 100644
> > > > --- a/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > +++ b/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > @@ -118,6 +118,11 @@ static inline bool dc_is_dvi_signal(enum
> > > > signal_type signal)
> > > >  	}
> > > >  }
> > > >  
> > > > +static inline bool dc_is_rgb_signal(enum signal_type signal)
> 
> To avoid confusion with people that haven't worked on analog
> signals in years (or ever) it might be better to name this
> dc_is_analog_signal.
> 
> Harry

Sounds good, I'll rename it in the next version of the series.
To further ease the confusion, what do you think about renaming
SIGNAL_TYPE_RGB to SIGNAL_TYPE_ANALOG?

Thanks,
Timur


> 
> > > > +{
> > > > +	return (signal == SIGNAL_TYPE_RGB);
> > > > +}
> > > > +
> > > >  static inline bool dc_is_tmds_signal(enum signal_type signal)
> > > >  {
> > > >  	switch (signal) {

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 00/20] Analog connector support in DC
  2025-07-30 16:29 ` [PATCH 00/20] Analog connector support in DC Harry Wentland
@ 2025-07-30 17:15   ` Timur Kristóf
  0 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-30 17:15 UTC (permalink / raw)
  To: Harry Wentland, amd-gfx

On Wed, 2025-07-30 at 12:29 -0400, Harry Wentland wrote:
> 
> 
> The series looks good to me.
> 
> Patches 2-20 are
> Reviewed-by: Harry Wentland <harry.wentland@amd.com>
> 
> Patch 1 is probably good, just waiting for feedback on my comments.
> 
> Though I would like to send this through our weekly testing cycle
> before we merge to ensure it doesn't regress DCN in some non-obvious
> ways.
> 
> Harry

Thank you for the quick review, Harry!

I will send a second version of this series addressing your comments.

(Also it was reported to me that the series causes a crash on Kaveri.
While TRAVIS and NUTMEG are not supported yet for Kaveri, I would still
like to fix the crash.)

Cheers,
Timur

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-07-30 17:03         ` Timur Kristóf
@ 2025-07-30 17:29           ` Harry Wentland
  2025-07-30 18:19             ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-07-30 17:29 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-07-30 13:03, Timur Kristóf wrote:
> On Wed, 2025-07-30 at 10:30 -0400, Harry Wentland wrote:
>>
>>
>> On 2025-07-30 03:40, Timur Kristóf wrote:
>>> On Tue, 2025-07-29 at 14:03 -0400, Harry Wentland wrote:
>>>>
>>>>
>>>> On 2025-07-23 11:57, Timur Kristóf wrote:
>>>>> Previously, DC determined the DRM connector type based on the
>>>>> signal type, which becomes problematic when a connector may
>>>>> support different signal types, such as DVI-I.
>>>>>
>>>>> With this patch, it is now determined according to the actual
>>>>> connector type in DC, meaning it can now distinguish between
>>>>> DVI-D and DVI-I connectors.
>>>>>
>>>>> A subsequent commit will enable polling for these connectors.
>>>>>
>>>>> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
>>>>> ---
>>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28
>>>>> +++++++++++----
>>>>> ----
>>>>>  1 file changed, 16 insertions(+), 12 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>>> index 096b23ad4845..c347b232ae06 100644
>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>>> @@ -8038,24 +8038,26 @@ static int
>>>>> dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state
>>>>> *state,
>>>>>  	return 0;
>>>>>  }
>>>>>  
>>>>> -static int to_drm_connector_type(enum signal_type st)
>>>>> +static int to_drm_connector_type(uint32_t connector_id)
>>>>>  {
>>>>> -	switch (st) {
>>>>> -	case SIGNAL_TYPE_HDMI_TYPE_A:
>>>>> +	switch (connector_id) {
>>>>> +	case CONNECTOR_ID_HDMI_TYPE_A:
>>>>>  		return DRM_MODE_CONNECTOR_HDMIA;
>>>>> -	case SIGNAL_TYPE_EDP:
>>>>> +	case CONNECTOR_ID_EDP:
>>>>>  		return DRM_MODE_CONNECTOR_eDP;
>>>>> -	case SIGNAL_TYPE_LVDS:
>>>>> +	case CONNECTOR_ID_LVDS:
>>>>>  		return DRM_MODE_CONNECTOR_LVDS;
>>>>> -	case SIGNAL_TYPE_RGB:
>>>>> +	case CONNECTOR_ID_VGA:
>>>>>  		return DRM_MODE_CONNECTOR_VGA;
>>>>> -	case SIGNAL_TYPE_DISPLAY_PORT:
>>>>> -	case SIGNAL_TYPE_DISPLAY_PORT_MST:
>>>>> +	case CONNECTOR_ID_DISPLAY_PORT:
>>>>>  		return DRM_MODE_CONNECTOR_DisplayPort;
>>>>> -	case SIGNAL_TYPE_DVI_DUAL_LINK:
>>>>> -	case SIGNAL_TYPE_DVI_SINGLE_LINK:
>>>>> +	case CONNECTOR_ID_SINGLE_LINK_DVID:
>>>>> +	case CONNECTOR_ID_DUAL_LINK_DVID:
>>>>>  		return DRM_MODE_CONNECTOR_DVID;
>>>>> -	case SIGNAL_TYPE_VIRTUAL:
>>>>> +	case CONNECTOR_ID_SINGLE_LINK_DVII:
>>>>> +	case CONNECTOR_ID_DUAL_LINK_DVII:
>>>>> +		return DRM_MODE_CONNECTOR_DVII;
>>>>> +	case CONNECTOR_ID_VIRTUAL:
>>>>>  		return DRM_MODE_CONNECTOR_VIRTUAL;
>>>>>  
>>>>>  	default:
>>>>> @@ -8440,6 +8442,8 @@ void
>>>>> amdgpu_dm_connector_init_helper(struct
>>>>> amdgpu_display_manager *dm,
>>>>>  			link->link_enc-
>>>>>> features.dp_ycbcr420_supported ? true : false;
>>>>>  		break;
>>>>>  	case DRM_MODE_CONNECTOR_DVID:
>>>>> +	case DRM_MODE_CONNECTOR_DVII:
>>>>> +	case DRM_MODE_CONNECTOR_VGA:
>>>>
>>>> This seems unrelated and would do better in a separate patch.
>>>>
>>>> Harry
>>>
>>> Keep in mind that currently DC recognizes DVI-I as DVI-D, but after
>>> this patch they will be recognized correctly as DVI-I. So without
>>> this
>>> part, the patch will regress the hotplug capability of those ports.
>>>
>>
>> How will it regress when your patch series introduces analog support?
>> Without that there shouldn't be DVII or VGA connectors.
>>
>> Harry
> 
> DVI-I can carry either an analog or a digital signal.
> 
> Before this patch, the DVI-I ports were recognized by DRM as
> DRM_MODE_CONNECTOR_DVID and their digital part was already working.
> That means you can plug in a digital DVI cable in a DVI-I port and it
> will work today.
> 
> After this patch they will be recognized as DRM_MODE_CONNECTOR_DVII
> instead, so in order to keep the same behaviour as before and avoid
> regressing the digital part, we need to set DRM_CONNECTOR_POLL_HPD, and
> in order to do that we need to add DRM_MODE_CONNECTOR_DVII to this
> switch statement.
> 

Thanks for the explanation. In that case the changes are all related
and it's probably easier to keep them together.

Reviewed-by: Harry Wentland <harry.wentland@amd.com>

Harry

> That being said, I can move this hunk to a separate patch before this
> one. That way there is going to be no regression and this patch stays
> simpler.
> 
> Does that sound ok to you?
> 
> Timur
> 
>>
>>> That said, sure, I can move this part to a separate commit before
>>> this
>>> one, if you prefer.
>>>
>>> Timur
>>>
>>>>
>>>>>  		aconnector->base.polled =
>>>>> DRM_CONNECTOR_POLL_HPD;
>>>>>  		break;
>>>>>  	default:
>>>>> @@ -8631,7 +8635,7 @@ static int
>>>>> amdgpu_dm_connector_init(struct
>>>>> amdgpu_display_manager *dm,
>>>>>  		goto out_free;
>>>>>  	}
>>>>>  
>>>>> -	connector_type = to_drm_connector_type(link-
>>>>>> connector_signal);
>>>>> +	connector_type = to_drm_connector_type(link-
>>>>>> link_id.id);
>>>>>  
>>>>>  	res = drm_connector_init_with_ddc(
>>>>>  			dm->ddev,


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-07-30 17:29           ` Harry Wentland
@ 2025-07-30 18:19             ` Timur Kristóf
  0 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-07-30 18:19 UTC (permalink / raw)
  To: Harry Wentland, amd-gfx

On Wed, 2025-07-30 at 13:29 -0400, Harry Wentland wrote:
> 
> 
> On 2025-07-30 13:03, Timur Kristóf wrote:
> > On Wed, 2025-07-30 at 10:30 -0400, Harry Wentland wrote:
> > > 
> > > 
> > > On 2025-07-30 03:40, Timur Kristóf wrote:
> > > > On Tue, 2025-07-29 at 14:03 -0400, Harry Wentland wrote:
> > > > > 
> > > > > 
> > > > > On 2025-07-23 11:57, Timur Kristóf wrote:
> > > > > > Previously, DC determined the DRM connector type based on
> > > > > > the
> > > > > > signal type, which becomes problematic when a connector may
> > > > > > support different signal types, such as DVI-I.
> > > > > > 
> > > > > > With this patch, it is now determined according to the
> > > > > > actual
> > > > > > connector type in DC, meaning it can now distinguish
> > > > > > between
> > > > > > DVI-D and DVI-I connectors.
> > > > > > 
> > > > > > A subsequent commit will enable polling for these
> > > > > > connectors.
> > > > > > 
> > > > > > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > > > > > ---
> > > > > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28
> > > > > > +++++++++++----
> > > > > > ----
> > > > > >  1 file changed, 16 insertions(+), 12 deletions(-)
> > > > > > 
> > > > > > diff --git
> > > > > > a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > > > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > > > index 096b23ad4845..c347b232ae06 100644
> > > > > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > > > @@ -8038,24 +8038,26 @@ static int
> > > > > > dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state
> > > > > > *state,
> > > > > >  	return 0;
> > > > > >  }
> > > > > >  
> > > > > > -static int to_drm_connector_type(enum signal_type st)
> > > > > > +static int to_drm_connector_type(uint32_t connector_id)
> > > > > >  {
> > > > > > -	switch (st) {
> > > > > > -	case SIGNAL_TYPE_HDMI_TYPE_A:
> > > > > > +	switch (connector_id) {
> > > > > > +	case CONNECTOR_ID_HDMI_TYPE_A:
> > > > > >  		return DRM_MODE_CONNECTOR_HDMIA;
> > > > > > -	case SIGNAL_TYPE_EDP:
> > > > > > +	case CONNECTOR_ID_EDP:
> > > > > >  		return DRM_MODE_CONNECTOR_eDP;
> > > > > > -	case SIGNAL_TYPE_LVDS:
> > > > > > +	case CONNECTOR_ID_LVDS:
> > > > > >  		return DRM_MODE_CONNECTOR_LVDS;
> > > > > > -	case SIGNAL_TYPE_RGB:
> > > > > > +	case CONNECTOR_ID_VGA:
> > > > > >  		return DRM_MODE_CONNECTOR_VGA;
> > > > > > -	case SIGNAL_TYPE_DISPLAY_PORT:
> > > > > > -	case SIGNAL_TYPE_DISPLAY_PORT_MST:
> > > > > > +	case CONNECTOR_ID_DISPLAY_PORT:
> > > > > >  		return DRM_MODE_CONNECTOR_DisplayPort;
> > > > > > -	case SIGNAL_TYPE_DVI_DUAL_LINK:
> > > > > > -	case SIGNAL_TYPE_DVI_SINGLE_LINK:
> > > > > > +	case CONNECTOR_ID_SINGLE_LINK_DVID:
> > > > > > +	case CONNECTOR_ID_DUAL_LINK_DVID:
> > > > > >  		return DRM_MODE_CONNECTOR_DVID;
> > > > > > -	case SIGNAL_TYPE_VIRTUAL:
> > > > > > +	case CONNECTOR_ID_SINGLE_LINK_DVII:
> > > > > > +	case CONNECTOR_ID_DUAL_LINK_DVII:
> > > > > > +		return DRM_MODE_CONNECTOR_DVII;
> > > > > > +	case CONNECTOR_ID_VIRTUAL:
> > > > > >  		return DRM_MODE_CONNECTOR_VIRTUAL;
> > > > > >  
> > > > > >  	default:
> > > > > > @@ -8440,6 +8442,8 @@ void
> > > > > > amdgpu_dm_connector_init_helper(struct
> > > > > > amdgpu_display_manager *dm,
> > > > > >  			link->link_enc-
> > > > > > > features.dp_ycbcr420_supported ? true : false;
> > > > > >  		break;
> > > > > >  	case DRM_MODE_CONNECTOR_DVID:
> > > > > > +	case DRM_MODE_CONNECTOR_DVII:
> > > > > > +	case DRM_MODE_CONNECTOR_VGA:
> > > > > 
> > > > > This seems unrelated and would do better in a separate patch.
> > > > > 
> > > > > Harry
> > > > 
> > > > Keep in mind that currently DC recognizes DVI-I as DVI-D, but
> > > > after
> > > > this patch they will be recognized correctly as DVI-I. So
> > > > without
> > > > this
> > > > part, the patch will regress the hotplug capability of those
> > > > ports.
> > > > 
> > > 
> > > How will it regress when your patch series introduces analog
> > > support?
> > > Without that there shouldn't be DVII or VGA connectors.
> > > 
> > > Harry
> > 
> > DVI-I can carry either an analog or a digital signal.
> > 
> > Before this patch, the DVI-I ports were recognized by DRM as
> > DRM_MODE_CONNECTOR_DVID and their digital part was already working.
> > That means you can plug in a digital DVI cable in a DVI-I port and
> > it
> > will work today.
> > 
> > After this patch they will be recognized as DRM_MODE_CONNECTOR_DVII
> > instead, so in order to keep the same behaviour as before and avoid
> > regressing the digital part, we need to set DRM_CONNECTOR_POLL_HPD,
> > and
> > in order to do that we need to add DRM_MODE_CONNECTOR_DVII to this
> > switch statement.
> > 
> 
> Thanks for the explanation. In that case the changes are all related
> and it's probably easier to keep them together.
> 
> Reviewed-by: Harry Wentland <harry.wentland@amd.com>
> 
> Harry

Thank you.

In the next version of the series I'll edit the commit message to make
it clearer why this is necessary.

> 
> > That being said, I can move this hunk to a separate patch before
> > this
> > one. That way there is going to be no regression and this patch
> > stays
> > simpler.
> > 
> > Does that sound ok to you?
> > 
> > Timur
> > 
> > > 
> > > > That said, sure, I can move this part to a separate commit
> > > > before
> > > > this
> > > > one, if you prefer.
> > > > 
> > > > Timur
> > > > 
> > > > > 
> > > > > >  		aconnector->base.polled =
> > > > > > DRM_CONNECTOR_POLL_HPD;
> > > > > >  		break;
> > > > > >  	default:
> > > > > > @@ -8631,7 +8635,7 @@ static int
> > > > > > amdgpu_dm_connector_init(struct
> > > > > > amdgpu_display_manager *dm,
> > > > > >  		goto out_free;
> > > > > >  	}
> > > > > >  
> > > > > > -	connector_type = to_drm_connector_type(link-
> > > > > > > connector_signal);
> > > > > > +	connector_type = to_drm_connector_type(link-
> > > > > > > link_id.id);
> > > > > >  
> > > > > >  	res = drm_connector_init_with_ddc(
> > > > > >  			dm->ddev,

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-07-30 17:08         ` Timur Kristóf
@ 2025-07-31 15:37           ` Harry Wentland
  2025-08-01  7:19             ` Alexandre Demers
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-07-31 15:37 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-07-30 13:08, Timur Kristóf wrote:
> On Wed, 2025-07-30 at 10:34 -0400, Harry Wentland wrote:
>>
>>
>> On 2025-07-30 04:19, Timur Kristóf wrote:
>>> On Tue, 2025-07-29 at 14:21 -0400, Harry Wentland wrote:
>>>>
>>>>
>>>> On 2025-07-23 11:58, Timur Kristóf wrote:
>>>>> Features like stereo sync and audio are not supported by RGB
>>>>> signals, so don't try to use them.
>>>>>
>>>>
>>>> Where does it say that?
>>>>
>>>> Harry
>>>
>>> 1. Audio
>>>
>>> VGA ports (and the analog part of DVI-I ports) simply cannot carry
>>> audio. So there is no hardware to control any audio, therefore
>>> there is
>>> nothing for this code to enable, which is why I added those ifs to
>>> not
>>> even try to enable audio on analog video signals.
>>>
>>
>> My bad, I was thinking RGB as opposed to YCbCr. Forgot that we use
>> RGB signal to refer to VGA.
> 
> Sorry for the confusion.
> 
>>
>>> As a side note, DVI-D ports (and the digital part of DVI-I ports)
>>> may
>>> have a non-standard extension to carry digital audio signals, but
>>> that
>>> is not revelant to supporting analog displays.
>>>
>>> 2. Stereo sync
>>>
>>> With regards to stereo sync, I didn't find any reference to this in
>>> the
>>> legacy display code, so I assumed either it is unsupported or the
>>> VBIOS
>>> already sets it up correctly. At least, considering that the legacy
>>> code didn't bother setting it up, we don't lose any functionality
>>> if we
>>> leave it out of DC as well.
>>>
>>> That being said, upon some further digging in the DCE register
>>> files, I
>>> found a register called DAC_STEREOSYNC_SELECT so maybe I could
>>> investigate using that. Maybe it would be better to work with the
>>> registers directly instead of the VBIOS? Would it be okay to
>>> investigate that further in a future patch series once this one is
>>> merged?
>>>
>>
>> I don't think DC supports stereo sync currently. I'm not sure there
>> is
>> much value in pursuing that.
> 
> If stereo sync is not supported, what does setup_stereo_sync() do?
> 

My bad. Not sure then. But no objection if you want to explore it.

Harry

>>
>>>>> diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>> b/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>> index a10d6b988aab..825a08fcb125 100644
>>>>> --- a/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>> +++ b/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>> @@ -118,6 +118,11 @@ static inline bool dc_is_dvi_signal(enum
>>>>> signal_type signal)
>>>>>  	}
>>>>>  }
>>>>>  
>>>>> +static inline bool dc_is_rgb_signal(enum signal_type signal)
>>
>> To avoid confusion with people that haven't worked on analog
>> signals in years (or ever) it might be better to name this
>> dc_is_analog_signal.
>>
>> Harry
> 
> Sounds good, I'll rename it in the next version of the series.
> To further ease the confusion, what do you think about renaming
> SIGNAL_TYPE_RGB to SIGNAL_TYPE_ANALOG?
> 
> Thanks,
> Timur
> 
> 
>>
>>>>> +{
>>>>> +	return (signal == SIGNAL_TYPE_RGB);
>>>>> +}
>>>>> +
>>>>>  static inline bool dc_is_tmds_signal(enum signal_type signal)
>>>>>  {
>>>>>  	switch (signal) {


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-07-31 15:37           ` Harry Wentland
@ 2025-08-01  7:19             ` Alexandre Demers
  2025-08-01  8:39               ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Alexandre Demers @ 2025-08-01  7:19 UTC (permalink / raw)
  To: amd-gfx

>On 2025-07-30 13:08, Timur Kristóf wrote:
>> On Wed, 2025-07-30 at 10:34 -0400, Harry Wentland wrote:
>>>
>>>
>>> On 2025-07-30 04:19, Timur Kristóf wrote:
>>>> On Tue, 2025-07-29 at 14:21 -0400, Harry Wentland wrote:
>>>>>
>>>>>
>>>>> On 2025-07-23 11:58, Timur Kristóf wrote:
>>>>>> Features like stereo sync and audio are not supported by RGB
>>>>>> signals, so don't try to use them.
>>>>>>
>>>>>
>>>>> Where does it say that?
>>>>>
>>>>> Harry
>>>>
>>>> 1. Audio
>>>>
>>>> VGA ports (and the analog part of DVI-I ports) simply cannot carry
>>>> audio. So there is no hardware to control any audio, therefore
>>>> there is
>>>> nothing for this code to enable, which is why I added those ifs to
>>>> not
>>>> even try to enable audio on analog video signals.
>>>>
>>>
>>> My bad, I was thinking RGB as opposed to YCbCr. Forgot that we use
>>> RGB signal to refer to VGA.
>> 
>> Sorry for the confusion.
>> 
>>>
>>>> As a side note, DVI-D ports (and the digital part of DVI-I ports)
>>>> may
>>>> have a non-standard extension to carry digital audio signals, but
>>>> that
>>>> is not revelant to supporting analog displays.
>>>>
>>>> 2. Stereo sync
>>>>
>>>> With regards to stereo sync, I didn't find any reference to this in
>>>> the
>>>> legacy display code, so I assumed either it is unsupported or the
>>>> VBIOS
>>>> already sets it up correctly. At least, considering that the legacy
>>>> code didn't bother setting it up, we don't lose any functionality
>>>> if we
>>>> leave it out of DC as well.
>>>>
>>>> That being said, upon some further digging in the DCE register
>>>> files, I
>>>> found a register called DAC_STEREOSYNC_SELECT so maybe I could
>>>> investigate using that. Maybe it would be better to work with the
>>>> registers directly instead of the VBIOS? Would it be okay to
>>>> investigate that further in a future patch series once this one is
>>>> merged?
>>>>
>>>
>>> I don't think DC supports stereo sync currently. I'm not sure there
>>> is
>>> much value in pursuing that.
>> 
>> If stereo sync is not supported, what does setup_stereo_sync() do?
>> 
> 
> My bad. Not sure then. But no objection if you want to explore it.
> 
> Harry
> >>>
>>>>>> diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>>> b/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>>> index a10d6b988aab..825a08fcb125 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>>> +++ b/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>>> @@ -118,6 +118,11 @@ static inline bool dc_is_dvi_signal(enum
>>>>>> signal_type signal)
>>>>>>  	}
>>>>>>  }
>>>>>>  
>>>>>> +static inline bool dc_is_rgb_signal(enum signal_type signal)
>>>
>>> To avoid confusion with people that haven't worked on analog
>>> signals in years (or ever) it might be better to name this
>>> dc_is_analog_signal.
>>>
>>> Harry
>> 
>> Sounds good, I'll rename it in the next version of the series.
>> To further ease the confusion, what do you think about renaming
>> SIGNAL_TYPE_RGB to SIGNAL_TYPE_ANALOG?
I think Harry hasn't answered your proposition. I must say that the 
first time I looked for VGA in the legacy code, I stumbled upon the RGB 
usage. But then, it began to make sense (I'm not completely sure if 
signals and connector types are used properly everywhere), because we 
are mostly translating DRM signal types to supported connector 
types.That being said, while both dc_is_rgb_signal() and 
dc_is_analog_signal() could be used here, we are specifically querying 
the signal type and this signal type is RGB. Because of this, I would be 
in favor of keeping dc_is_rgb_signal() unless there is another analog 
type that could be queried and not rename SIGNAL_TYPE_RGB to 
SIGNAL_TYPE_ANALOG in any case. Cheers, Alexandre >>
>> Thanks,
>> Timur
>> 
>> 
>>>
>>>>>> +{
>>>>>> +	return (signal == SIGNAL_TYPE_RGB);
>>>>>> +}
>>>>>> +
>>>>>>  static inline bool dc_is_tmds_signal(enum signal_type signal)
>>>>>>  {
>>>>>>  	switch (signal) {



^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-08-01  7:19             ` Alexandre Demers
@ 2025-08-01  8:39               ` Timur Kristóf
  2025-08-01 14:55                 ` Harry Wentland
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-08-01  8:39 UTC (permalink / raw)
  To: alexandre.f.demers, amd-gfx

On Fri, 2025-08-01 at 03:19 -0400, Alexandre Demers wrote:
> > On 2025-07-30 13:08, Timur Kristóf wrote:
> > > On Wed, 2025-07-30 at 10:34 -0400, Harry Wentland wrote:
> > > > 
> > > > 
> > > > On 2025-07-30 04:19, Timur Kristóf wrote:
> > > > > On Tue, 2025-07-29 at 14:21 -0400, Harry Wentland wrote:
> > > > > > 
> > > > > > 
> > > > > > On 2025-07-23 11:58, Timur Kristóf wrote:
> > > > > > > Features like stereo sync and audio are not supported by
> > > > > > > RGB
> > > > > > > signals, so don't try to use them.
> > > > > > > 
> > > > > > 
> > > > > > Where does it say that?
> > > > > > 
> > > > > > Harry
> > > > > 
> > > > > 1. Audio
> > > > > 
> > > > > VGA ports (and the analog part of DVI-I ports) simply cannot
> > > > > carry
> > > > > audio. So there is no hardware to control any audio,
> > > > > therefore
> > > > > there is
> > > > > nothing for this code to enable, which is why I added those
> > > > > ifs to
> > > > > not
> > > > > even try to enable audio on analog video signals.
> > > > > 
> > > > 
> > > > My bad, I was thinking RGB as opposed to YCbCr. Forgot that we
> > > > use
> > > > RGB signal to refer to VGA.
> > > 
> > > Sorry for the confusion.
> > > 
> > > > 
> > > > > As a side note, DVI-D ports (and the digital part of DVI-I
> > > > > ports)
> > > > > may
> > > > > have a non-standard extension to carry digital audio signals,
> > > > > but
> > > > > that
> > > > > is not revelant to supporting analog displays.
> > > > > 
> > > > > 2. Stereo sync
> > > > > 
> > > > > With regards to stereo sync, I didn't find any reference to
> > > > > this in
> > > > > the
> > > > > legacy display code, so I assumed either it is unsupported or
> > > > > the
> > > > > VBIOS
> > > > > already sets it up correctly. At least, considering that the
> > > > > legacy
> > > > > code didn't bother setting it up, we don't lose any
> > > > > functionality
> > > > > if we
> > > > > leave it out of DC as well.
> > > > > 
> > > > > That being said, upon some further digging in the DCE
> > > > > register
> > > > > files, I
> > > > > found a register called DAC_STEREOSYNC_SELECT so maybe I
> > > > > could
> > > > > investigate using that. Maybe it would be better to work with
> > > > > the
> > > > > registers directly instead of the VBIOS? Would it be okay to
> > > > > investigate that further in a future patch series once this
> > > > > one is
> > > > > merged?
> > > > > 
> > > > 
> > > > I don't think DC supports stereo sync currently. I'm not sure
> > > > there
> > > > is
> > > > much value in pursuing that.
> > > 
> > > If stereo sync is not supported, what does setup_stereo_sync()
> > > do?
> > > 
> > 
> > My bad. Not sure then. But no objection if you want to explore it.
> > 
> > Harry
> > > > > 
> > > > > > > diff --git
> > > > > > > a/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > > > > b/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > > > > index a10d6b988aab..825a08fcb125 100644
> > > > > > > --- a/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > > > > +++ b/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > > > > @@ -118,6 +118,11 @@ static inline bool
> > > > > > > dc_is_dvi_signal(enum
> > > > > > > signal_type signal)
> > > > > > >  	}
> > > > > > >  }
> > > > > > >  
> > > > > > > +static inline bool dc_is_rgb_signal(enum signal_type
> > > > > > > signal)
> > > > 
> > > > To avoid confusion with people that haven't worked on analog
> > > > signals in years (or ever) it might be better to name this
> > > > dc_is_analog_signal.
> > > > 
> > > > Harry
> > > 
> > > Sounds good, I'll rename it in the next version of the series.
> > > To further ease the confusion, what do you think about renaming
> > > SIGNAL_TYPE_RGB to SIGNAL_TYPE_ANALOG?
> I think Harry hasn't answered your proposition. I must say that the 
> first time I looked for VGA in the legacy code, I stumbled upon the
> RGB 
> usage. But then, it began to make sense (I'm not completely sure if 
> signals and connector types are used properly everywhere), because we
> are mostly translating DRM signal types to supported connector 
> types.That being said, while both dc_is_rgb_signal() and 
> dc_is_analog_signal() could be used here, we are specifically
> querying 
> the signal type and this signal type is RGB. Because of this, I would
> be 
> in favor of keeping dc_is_rgb_signal() unless there is another analog
> type that could be queried and not rename SIGNAL_TYPE_RGB to 
> SIGNAL_TYPE_ANALOG in any case. Cheers, Alexandre

Hi Alexandre,

I think the confusion comes from "RGB" being a very overloaded term in
this space, so I am in favour of clarifying the name. I am open to
suggestion as to what is the best clarification. If you want to keep
the "RGB" part then I propose:

SIGNAL_TYPE_RGB -> SIGNAL_TYPE_ANALOG_RGB

Which should make it very clear what it is.

Otherwise, I would like to apply Harry's suggestion to name the new
helper function dc_is_analog_singal. Considering we don't support other
types of analog signals, I don't think there is any confusion with
that.

Let me know what you think.

Timur



> > > Thanks,
> > > Timur
> > > 
> > > 
> > > > 
> > > > > > > +{
> > > > > > > +	return (signal == SIGNAL_TYPE_RGB);
> > > > > > > +}
> > > > > > > +
> > > > > > >  static inline bool dc_is_tmds_signal(enum signal_type
> > > > > > > signal)
> > > > > > >  {
> > > > > > >  	switch (signal) {
> 

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-08-01  8:39               ` Timur Kristóf
@ 2025-08-01 14:55                 ` Harry Wentland
  2025-08-01 15:09                   ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-08-01 14:55 UTC (permalink / raw)
  To: Timur Kristóf, alexandre.f.demers, amd-gfx



On 2025-08-01 04:39, Timur Kristóf wrote:
> On Fri, 2025-08-01 at 03:19 -0400, Alexandre Demers wrote:
>>> On 2025-07-30 13:08, Timur Kristóf wrote:
>>>> On Wed, 2025-07-30 at 10:34 -0400, Harry Wentland wrote:
>>>>>
>>>>>
>>>>> On 2025-07-30 04:19, Timur Kristóf wrote:
>>>>>> On Tue, 2025-07-29 at 14:21 -0400, Harry Wentland wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 2025-07-23 11:58, Timur Kristóf wrote:
>>>>>>>> Features like stereo sync and audio are not supported by
>>>>>>>> RGB
>>>>>>>> signals, so don't try to use them.
>>>>>>>>
>>>>>>>
>>>>>>> Where does it say that?
>>>>>>>
>>>>>>> Harry
>>>>>>
>>>>>> 1. Audio
>>>>>>
>>>>>> VGA ports (and the analog part of DVI-I ports) simply cannot
>>>>>> carry
>>>>>> audio. So there is no hardware to control any audio,
>>>>>> therefore
>>>>>> there is
>>>>>> nothing for this code to enable, which is why I added those
>>>>>> ifs to
>>>>>> not
>>>>>> even try to enable audio on analog video signals.
>>>>>>
>>>>>
>>>>> My bad, I was thinking RGB as opposed to YCbCr. Forgot that we
>>>>> use
>>>>> RGB signal to refer to VGA.
>>>>
>>>> Sorry for the confusion.
>>>>
>>>>>
>>>>>> As a side note, DVI-D ports (and the digital part of DVI-I
>>>>>> ports)
>>>>>> may
>>>>>> have a non-standard extension to carry digital audio signals,
>>>>>> but
>>>>>> that
>>>>>> is not revelant to supporting analog displays.
>>>>>>
>>>>>> 2. Stereo sync
>>>>>>
>>>>>> With regards to stereo sync, I didn't find any reference to
>>>>>> this in
>>>>>> the
>>>>>> legacy display code, so I assumed either it is unsupported or
>>>>>> the
>>>>>> VBIOS
>>>>>> already sets it up correctly. At least, considering that the
>>>>>> legacy
>>>>>> code didn't bother setting it up, we don't lose any
>>>>>> functionality
>>>>>> if we
>>>>>> leave it out of DC as well.
>>>>>>
>>>>>> That being said, upon some further digging in the DCE
>>>>>> register
>>>>>> files, I
>>>>>> found a register called DAC_STEREOSYNC_SELECT so maybe I
>>>>>> could
>>>>>> investigate using that. Maybe it would be better to work with
>>>>>> the
>>>>>> registers directly instead of the VBIOS? Would it be okay to
>>>>>> investigate that further in a future patch series once this
>>>>>> one is
>>>>>> merged?
>>>>>>
>>>>>
>>>>> I don't think DC supports stereo sync currently. I'm not sure
>>>>> there
>>>>> is
>>>>> much value in pursuing that.
>>>>
>>>> If stereo sync is not supported, what does setup_stereo_sync()
>>>> do?
>>>>
>>>
>>> My bad. Not sure then. But no objection if you want to explore it.
>>>
>>> Harry
>>>>>>
>>>>>>>> diff --git
>>>>>>>> a/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>>>>> b/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>>>>> index a10d6b988aab..825a08fcb125 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>>>>> +++ b/drivers/gpu/drm/amd/display/include/signal_types.h
>>>>>>>> @@ -118,6 +118,11 @@ static inline bool
>>>>>>>> dc_is_dvi_signal(enum
>>>>>>>> signal_type signal)
>>>>>>>>  	}
>>>>>>>>  }
>>>>>>>>  
>>>>>>>> +static inline bool dc_is_rgb_signal(enum signal_type
>>>>>>>> signal)
>>>>>
>>>>> To avoid confusion with people that haven't worked on analog
>>>>> signals in years (or ever) it might be better to name this
>>>>> dc_is_analog_signal.
>>>>>
>>>>> Harry
>>>>
>>>> Sounds good, I'll rename it in the next version of the series.
>>>> To further ease the confusion, what do you think about renaming
>>>> SIGNAL_TYPE_RGB to SIGNAL_TYPE_ANALOG?
>> I think Harry hasn't answered your proposition. I must say that the 
>> first time I looked for VGA in the legacy code, I stumbled upon the
>> RGB 
>> usage. But then, it began to make sense (I'm not completely sure if 
>> signals and connector types are used properly everywhere), because we
>> are mostly translating DRM signal types to supported connector 
>> types.That being said, while both dc_is_rgb_signal() and 
>> dc_is_analog_signal() could be used here, we are specifically
>> querying 
>> the signal type and this signal type is RGB. Because of this, I would
>> be 
>> in favor of keeping dc_is_rgb_signal() unless there is another analog
>> type that could be queried and not rename SIGNAL_TYPE_RGB to 
>> SIGNAL_TYPE_ANALOG in any case. Cheers, Alexandre
> 
> Hi Alexandre,
> 
> I think the confusion comes from "RGB" being a very overloaded term in
> this space, so I am in favour of clarifying the name. I am open to
> suggestion as to what is the best clarification. If you want to keep
> the "RGB" part then I propose:
> 
> SIGNAL_TYPE_RGB -> SIGNAL_TYPE_ANALOG_RGB
> 
> Which should make it very clear what it is.
> 
> Otherwise, I would like to apply Harry's suggestion to name the new
> helper function dc_is_analog_singal. Considering we don't support other
> types of analog signals, I don't think there is any confusion with
> that.
> 
> Let me know what you think.

After going through the entire series I'm not so sure
it only makes sense to rename this function to _analog_.

Either rename all of SIGNAL_TYPE_RGB (like you suggest)
or leave it all as RGB. The former creates a whole bunch
of churn and it might make sense to just leave things as
RGB. My confusion came from the fact that I've spent a
lot of time in the world of color spaces and over the
years have forgotten our terms for analog connectors.

So, no strong opinion from me. Maybe slightly in favor
of avoiding churn.

Harry

> 
> Timur
> 
> 
> 
>>>> Thanks,
>>>> Timur
>>>>
>>>>
>>>>>
>>>>>>>> +{
>>>>>>>> +	return (signal == SIGNAL_TYPE_RGB);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>  static inline bool dc_is_tmds_signal(enum signal_type
>>>>>>>> signal)
>>>>>>>>  {
>>>>>>>>  	switch (signal) {
>>


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals
  2025-08-01 14:55                 ` Harry Wentland
@ 2025-08-01 15:09                   ` Timur Kristóf
  0 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-08-01 15:09 UTC (permalink / raw)
  To: Harry Wentland, alexandre.f.demers, amd-gfx

On Fri, 2025-08-01 at 10:55 -0400, Harry Wentland wrote:
> 
> 
> On 2025-08-01 04:39, Timur Kristóf wrote:
> > On Fri, 2025-08-01 at 03:19 -0400, Alexandre Demers wrote:
> > > > On 2025-07-30 13:08, Timur Kristóf wrote:
> > > > > On Wed, 2025-07-30 at 10:34 -0400, Harry Wentland wrote:
> > > > > > 
> > > > > > 
> > > > > > On 2025-07-30 04:19, Timur Kristóf wrote:
> > > > > > > On Tue, 2025-07-29 at 14:21 -0400, Harry Wentland wrote:
> > > > > > > > 
> > > > > > > > 
> > > > > > > > On 2025-07-23 11:58, Timur Kristóf wrote:
> > > > > > > > > Features like stereo sync and audio are not supported
> > > > > > > > > by
> > > > > > > > > RGB
> > > > > > > > > signals, so don't try to use them.
> > > > > > > > > 
> > > > > > > > 
> > > > > > > > Where does it say that?
> > > > > > > > 
> > > > > > > > Harry
> > > > > > > 
> > > > > > > 1. Audio
> > > > > > > 
> > > > > > > VGA ports (and the analog part of DVI-I ports) simply
> > > > > > > cannot
> > > > > > > carry
> > > > > > > audio. So there is no hardware to control any audio,
> > > > > > > therefore
> > > > > > > there is
> > > > > > > nothing for this code to enable, which is why I added
> > > > > > > those
> > > > > > > ifs to
> > > > > > > not
> > > > > > > even try to enable audio on analog video signals.
> > > > > > > 
> > > > > > 
> > > > > > My bad, I was thinking RGB as opposed to YCbCr. Forgot that
> > > > > > we
> > > > > > use
> > > > > > RGB signal to refer to VGA.
> > > > > 
> > > > > Sorry for the confusion.
> > > > > 
> > > > > > 
> > > > > > > As a side note, DVI-D ports (and the digital part of DVI-
> > > > > > > I
> > > > > > > ports)
> > > > > > > may
> > > > > > > have a non-standard extension to carry digital audio
> > > > > > > signals,
> > > > > > > but
> > > > > > > that
> > > > > > > is not revelant to supporting analog displays.
> > > > > > > 
> > > > > > > 2. Stereo sync
> > > > > > > 
> > > > > > > With regards to stereo sync, I didn't find any reference
> > > > > > > to
> > > > > > > this in
> > > > > > > the
> > > > > > > legacy display code, so I assumed either it is
> > > > > > > unsupported or
> > > > > > > the
> > > > > > > VBIOS
> > > > > > > already sets it up correctly. At least, considering that
> > > > > > > the
> > > > > > > legacy
> > > > > > > code didn't bother setting it up, we don't lose any
> > > > > > > functionality
> > > > > > > if we
> > > > > > > leave it out of DC as well.
> > > > > > > 
> > > > > > > That being said, upon some further digging in the DCE
> > > > > > > register
> > > > > > > files, I
> > > > > > > found a register called DAC_STEREOSYNC_SELECT so maybe I
> > > > > > > could
> > > > > > > investigate using that. Maybe it would be better to work
> > > > > > > with
> > > > > > > the
> > > > > > > registers directly instead of the VBIOS? Would it be okay
> > > > > > > to
> > > > > > > investigate that further in a future patch series once
> > > > > > > this
> > > > > > > one is
> > > > > > > merged?
> > > > > > > 
> > > > > > 
> > > > > > I don't think DC supports stereo sync currently. I'm not
> > > > > > sure
> > > > > > there
> > > > > > is
> > > > > > much value in pursuing that.
> > > > > 
> > > > > If stereo sync is not supported, what does
> > > > > setup_stereo_sync()
> > > > > do?
> > > > > 
> > > > 
> > > > My bad. Not sure then. But no objection if you want to explore
> > > > it.
> > > > 
> > > > Harry
> > > > > > > 
> > > > > > > > > diff --git
> > > > > > > > > a/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > > > > > > b/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > > > > > > index a10d6b988aab..825a08fcb125 100644
> > > > > > > > > ---
> > > > > > > > > a/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > > > > > > +++
> > > > > > > > > b/drivers/gpu/drm/amd/display/include/signal_types.h
> > > > > > > > > @@ -118,6 +118,11 @@ static inline bool
> > > > > > > > > dc_is_dvi_signal(enum
> > > > > > > > > signal_type signal)
> > > > > > > > >  	}
> > > > > > > > >  }
> > > > > > > > >  
> > > > > > > > > +static inline bool dc_is_rgb_signal(enum signal_type
> > > > > > > > > signal)
> > > > > > 
> > > > > > To avoid confusion with people that haven't worked on
> > > > > > analog
> > > > > > signals in years (or ever) it might be better to name this
> > > > > > dc_is_analog_signal.
> > > > > > 
> > > > > > Harry
> > > > > 
> > > > > Sounds good, I'll rename it in the next version of the
> > > > > series.
> > > > > To further ease the confusion, what do you think about
> > > > > renaming
> > > > > SIGNAL_TYPE_RGB to SIGNAL_TYPE_ANALOG?
> > > I think Harry hasn't answered your proposition. I must say that
> > > the 
> > > first time I looked for VGA in the legacy code, I stumbled upon
> > > the
> > > RGB 
> > > usage. But then, it began to make sense (I'm not completely sure
> > > if 
> > > signals and connector types are used properly everywhere),
> > > because we
> > > are mostly translating DRM signal types to supported connector 
> > > types.That being said, while both dc_is_rgb_signal() and 
> > > dc_is_analog_signal() could be used here, we are specifically
> > > querying 
> > > the signal type and this signal type is RGB. Because of this, I
> > > would
> > > be 
> > > in favor of keeping dc_is_rgb_signal() unless there is another
> > > analog
> > > type that could be queried and not rename SIGNAL_TYPE_RGB to 
> > > SIGNAL_TYPE_ANALOG in any case. Cheers, Alexandre
> > 
> > Hi Alexandre,
> > 
> > I think the confusion comes from "RGB" being a very overloaded term
> > in
> > this space, so I am in favour of clarifying the name. I am open to
> > suggestion as to what is the best clarification. If you want to
> > keep
> > the "RGB" part then I propose:
> > 
> > SIGNAL_TYPE_RGB -> SIGNAL_TYPE_ANALOG_RGB
> > 
> > Which should make it very clear what it is.
> > 
> > Otherwise, I would like to apply Harry's suggestion to name the new
> > helper function dc_is_analog_singal. Considering we don't support
> > other
> > types of analog signals, I don't think there is any confusion with
> > that.
> > 
> > Let me know what you think.
> 
> After going through the entire series I'm not so sure
> it only makes sense to rename this function to _analog_.
> 
> Either rename all of SIGNAL_TYPE_RGB (like you suggest)
> or leave it all as RGB. The former creates a whole bunch
> of churn and it might make sense to just leave things as
> RGB. My confusion came from the fact that I've spent a
> lot of time in the world of color spaces and over the
> years have forgotten our terms for analog connectors.
> 
> So, no strong opinion from me. Maybe slightly in favor
> of avoiding churn.
> 
> Harry

Hi Harry,

It sounds like both Alexandre and yourself are slightly in favour of
keeping the old names, SIGNAL_TYPE_RGB and dc_is_rgb_signal.

So, I'll just leave them as they are.
I will soon send a v2 for the series addressing the feedback.

Thanks,
Timur



> 
> > 
> > Timur
> > 
> > 
> > 
> > > > > Thanks,
> > > > > Timur
> > > > > 
> > > > > 
> > > > > > 
> > > > > > > > > +{
> > > > > > > > > +	return (signal == SIGNAL_TYPE_RGB);
> > > > > > > > > +}
> > > > > > > > > +
> > > > > > > > >  static inline bool dc_is_tmds_signal(enum
> > > > > > > > > signal_type
> > > > > > > > > signal)
> > > > > > > > >  {
> > > > > > > > >  	switch (signal) {
> > > 

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders
  2025-07-23 15:58 ` [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders Timur Kristóf
@ 2025-08-01 18:05   ` Alexandre Demers
  2025-08-01 21:29     ` Timur Kristóf
  2025-08-01 18:06   ` Alexandre Demers
  1 sibling, 1 reply; 61+ messages in thread
From: Alexandre Demers @ 2025-08-01 18:05 UTC (permalink / raw)
  To: amd-gfx

[-- Attachment #1: Type: text/plain, Size: 2472 bytes --]

> Add stream encoders for DCE6-10 only, because there are definitely
> graphics cards with analog connectors out there with these DCE
> versions. I am not aware of newer ones.

> Considering that all stream encoder functions currently have to do
> with digital streams, there is nothing for an analog stream
> encoder to do, making them basically a no-op.
> That being said, we still need some kind of stream encoder to
> represent an analog stream, and it is beneficial to split them from
> digital stream encoders in the code to make sure they don't
> accidentally write any DIG* registers.
> 
> Signed-off-by: Timur Kristóf <timur.kristof at gmail.com <https://lists.freedesktop.org/mailman/listinfo/amd-gfx>>
> ---
>  .../drm/amd/display/dc/dce/dce_stream_encoder.c    | 14 ++++++++++++++
>  .../drm/amd/display/dc/dce/dce_stream_encoder.h    |  5 +++++
>  .../display/dc/resource/dce100/dce100_resource.c   |  6 ++++++
>  .../amd/display/dc/resource/dce60/dce60_resource.c |  8 ++++++++
>  .../amd/display/dc/resource/dce80/dce80_resource.c |  8 ++++++++
>  5 files changed, 41 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> index 1130d7619b26..f8996ee2856b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> @@ -1567,3 +1567,17 @@ void dce110_stream_encoder_construct(
>  	enc110->se_shift = se_shift;
>  	enc110->se_mask = se_mask;
>  }
> +
> +static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {0};
> +
> +void dce110_analog_stream_encoder_construct(
> +	struct dce110_stream_encoder *enc110,
> +	struct dc_context *ctx,
> +	struct dc_bios *bp,
> +	enum engine_id eng_id)
> +{
> +	enc110->base.funcs = &dce110_an_str_enc_funcs;
> +	enc110->base.ctx = ctx;
> +	enc110->base.id = eng_id;
> +	enc110->base.bp = bp;
> +}

  Since we are adding analog stream encoder support only up to DCE10, wouldn't it be better if the prefix "dce100_" was used instead? I know there are a few functions in there that use "dce110_" as prefix and are replaced by functions specific to the DCE versions that behave differently (we even have dce60_ and dce80_ in the current patch), but this seems off otherwise.
  
  IMO, if thie DCE code should be revisited, "dce_" should be the general prefix instead of "dce110_", with "dceXY_" being specific (as it is right now).
  Alexandre

[-- Attachment #2: Type: text/html, Size: 2841 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders
  2025-07-23 15:58 ` [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders Timur Kristóf
  2025-08-01 18:05   ` Alexandre Demers
@ 2025-08-01 18:06   ` Alexandre Demers
  1 sibling, 0 replies; 61+ messages in thread
From: Alexandre Demers @ 2025-08-01 18:06 UTC (permalink / raw)
  To: amd-gfx, timur.kristof

[-- Attachment #1: Type: text/plain, Size: 2472 bytes --]

> Add stream encoders for DCE6-10 only, because there are definitely
> graphics cards with analog connectors out there with these DCE
> versions. I am not aware of newer ones.

> Considering that all stream encoder functions currently have to do
> with digital streams, there is nothing for an analog stream
> encoder to do, making them basically a no-op.
> That being said, we still need some kind of stream encoder to
> represent an analog stream, and it is beneficial to split them from
> digital stream encoders in the code to make sure they don't
> accidentally write any DIG* registers.
> 
> Signed-off-by: Timur Kristóf <timur.kristof at gmail.com <https://lists.freedesktop.org/mailman/listinfo/amd-gfx>>
> ---
>  .../drm/amd/display/dc/dce/dce_stream_encoder.c    | 14 ++++++++++++++
>  .../drm/amd/display/dc/dce/dce_stream_encoder.h    |  5 +++++
>  .../display/dc/resource/dce100/dce100_resource.c   |  6 ++++++
>  .../amd/display/dc/resource/dce60/dce60_resource.c |  8 ++++++++
>  .../amd/display/dc/resource/dce80/dce80_resource.c |  8 ++++++++
>  5 files changed, 41 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> index 1130d7619b26..f8996ee2856b 100644
> --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> @@ -1567,3 +1567,17 @@ void dce110_stream_encoder_construct(
>  	enc110->se_shift = se_shift;
>  	enc110->se_mask = se_mask;
>  }
> +
> +static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {0};
> +
> +void dce110_analog_stream_encoder_construct(
> +	struct dce110_stream_encoder *enc110,
> +	struct dc_context *ctx,
> +	struct dc_bios *bp,
> +	enum engine_id eng_id)
> +{
> +	enc110->base.funcs = &dce110_an_str_enc_funcs;
> +	enc110->base.ctx = ctx;
> +	enc110->base.id = eng_id;
> +	enc110->base.bp = bp;
> +}

  Since we are adding analog stream encoder support only up to DCE10, wouldn't it be better if the prefix "dce100_" was used instead? I know there are a few functions in there that use "dce110_" as prefix and are replaced by functions specific to the DCE versions that behave differently (we even have dce60_ and dce80_ in the current patch), but this seems off otherwise.
  
  IMO, if thie DCE code should be revisited, "dce_" should be the general prefix instead of "dce110_", with "dceXY_" being specific (as it is right now).
  Alexandre

[-- Attachment #2: Type: text/html, Size: 2840 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders
  2025-07-23 15:58 ` [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders Timur Kristóf
@ 2025-08-01 19:30   ` Alexandre Demers
  2025-08-01 22:02     ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Alexandre Demers @ 2025-08-01 19:30 UTC (permalink / raw)
  To: amd-gfx, timur.kristof

[-- Attachment #1: Type: text/plain, Size: 1167 bytes --]

> We support two kinds of analog connections:
> 
> 1. VGA, which only supports analog signals:
> For VGA, we need to create a link encoder that only works with the
> DAC without perturbing any digital transmitter functionality.
> This is achieved by the new dce110_analog_link_encoder_construct.
> 
> 2. DVI-I, which allows both digital and analog signals:
> The DC code base only allows 1 encoder per connector, and the
> preferred engine type is still going to be digital. So, for DVI-I
> to work, we need to make sure the pre-existing link encoder can
> also work with analog signals.
> 
> Signed-off-by: Timur Kristóf <timur.kristof at gmail.com <https://lists.freedesktop.org/mailman/listinfo/amd-gfx>>
> ---
>  .../drm/amd/display/dc/dce/dce_link_encoder.c | 100 ++++++++++++++++++
>  .../drm/amd/display/dc/dce/dce_link_encoder.h |  21 ++--
  
  I have the same comment about the use of "dce110_" prefix under general/global DCE code that I left on the previous patch.
  
  For consistency with the current code, I understand why this prefix is used, but I'd gladly clean this up once the patches have landed in if there is a common agreement.
  
  Alexandre

[-- Attachment #2: Type: text/html, Size: 1423 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders
  2025-08-01 18:05   ` Alexandre Demers
@ 2025-08-01 21:29     ` Timur Kristóf
  2025-08-03 16:10       ` Alexandre Demers
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-08-01 21:29 UTC (permalink / raw)
  To: alexandre.f.demers@gmail.com; +Cc: amd-gfx@lists.freedesktop.org

[-- Attachment #1: Type: text/plain, Size: 3487 bytes --]

2025. augusztus 1., péntek dátummal Alexandre Demers <
alexandre.f.demers@gmail.com> ezt írta:
>> Add stream encoders for DCE6-10 only, because there are definitely
>> graphics cards with analog connectors out there with these DCE
>> versions. I am not aware of newer ones.
>
>> Considering that all stream encoder functions currently have to do
>> with digital streams, there is nothing for an analog stream
>> encoder to do, making them basically a no-op.
>> That being said, we still need some kind of stream encoder to
>> represent an analog stream, and it is beneficial to split them from
>> digital stream encoders in the code to make sure they don't
>> accidentally write any DIG* registers.
>>
>> Signed-off-by: Timur Kristóf <timur.kristof at gmail.com>
>> ---
>> .../drm/amd/display/dc/dce/dce_stream_encoder.c | 14 ++++++++++++++
>> .../drm/amd/display/dc/dce/dce_stream_encoder.h | 5 +++++
>> .../display/dc/resource/dce100/dce100_resource.c | 6 ++++++
>> .../amd/display/dc/resource/dce60/dce60_resource.c | 8 ++++++++
>> .../amd/display/dc/resource/dce80/dce80_resource.c | 8 ++++++++
>> 5 files changed, 41 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
>> index 1130d7619b26..f8996ee2856b 100644
>> --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
>> +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
>> @@ -1567,3 +1567,17 @@ void dce110_stream_encoder_construct(
>> enc110->se_shift = se_shift;
>> enc110->se_mask = se_mask;
>> }
>> +
>> +static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {0};
>> +
>> +void dce110_analog_stream_encoder_construct(
>> + struct dce110_stream_encoder *enc110,
>> + struct dc_context *ctx,
>> + struct dc_bios *bp,
>> + enum engine_id eng_id)
>> +{
>> + enc110->base.funcs = &dce110_an_str_enc_funcs;
>> + enc110->base.ctx = ctx;
>> + enc110->base.id = eng_id;
>> + enc110->base.bp = bp;
>> +}
>
> Since we are adding analog stream encoder support only up to DCE10,
wouldn't it be better if the prefix "dce100_" was used instead? I know
there are a few functions in there that use "dce110_" as prefix and are
replaced by functions specific to the DCE versions that behave differently
(we even have dce60_ and dce80_ in the current patch), but this seems off
otherwise.
>
> IMO, if thie DCE code should be revisited, "dce_" should be the general
prefix instead of "dce110_", with "dceXY_" being specific (as it is right
now).
> Alexandre

Hi Alexandre,

Two reasons:

1. As best as I can tell, all DCE versions use dce110_stream_encoder
regardless of its name. I agree that this is somewhat counter-intuitive but
I wanted to follow the conventions in the rest of this file.

2. It is unclear which DCE versions actually have a DAC. On one hand there
is some conversation on this ML that suggests that Hawaii and newer don't
have a DAC, which is apparently wrong. Looking at the register headers, all
DCE including the latest one have the DAC registers. Theoretically, if
there were newer GPUs with DAC, this code would work fine on them too.

If you are not happy with the code style, I respect that but I would like
if we tackled that separarely.

With these series, I want to just focus on fixing things and getting DC to
work on SI and CIK with the least possible risk of breaking things.

Best regards,
Timur

[-- Attachment #2: Type: text/html, Size: 4075 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders
  2025-08-01 19:30   ` Alexandre Demers
@ 2025-08-01 22:02     ` Timur Kristóf
  2025-08-03 16:26       ` Alexandre Demers
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-08-01 22:02 UTC (permalink / raw)
  To: Alexandre Demers; +Cc: amd-gfx@lists.freedesktop.org

[-- Attachment #1: Type: text/plain, Size: 1797 bytes --]

2025. augusztus 1., péntek dátummal Alexandre Demers <
alexandre.f.demers@gmail.com> ezt írta:
>> We support two kinds of analog connections:
>>
>> 1. VGA, which only supports analog signals:
>> For VGA, we need to create a link encoder that only works with the
>> DAC without perturbing any digital transmitter functionality.
>> This is achieved by the new dce110_analog_link_encoder_construct.
>>
>> 2. DVI-I, which allows both digital and analog signals:
>> The DC code base only allows 1 encoder per connector, and the
>> preferred engine type is still going to be digital. So, for DVI-I
>> to work, we need to make sure the pre-existing link encoder can
>> also work with analog signals.
>>
>> Signed-off-by: Timur Kristóf <timur.kristof at gmail.com>
>> ---
>> .../drm/amd/display/dc/dce/dce_link_encoder.c | 100 ++++++++++++++++++
>> .../drm/amd/display/dc/dce/dce_link_encoder.h | 21 ++--
>
> I have the same comment about the use of "dce110_" prefix under
general/global DCE code that I left on the previous patch.
>
> For consistency with the current code, I understand why this prefix is
used, but I'd gladly clean this up once the patches have landed in if there
is a common agreement.
>
> Alexandre

Hi Alexandre,

With regards to the coding style. I already replied to your other thread
about it, let's have that conversation there.

With regards to the link encoders specifically. Due to DVI-I, we need
dce110_link_encoder to handle analog signals in addition to digital, so the
question about this part is, is there any need to have a separate
dce110_analog_link_encoder? When I wrote the patch I felt yes, but now I
feel maybe we should just let dce110_link_encoder handle VGA as well.

What do you think about that?

Thanks,
Timur

[-- Attachment #2: Type: text/html, Size: 2110 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders
  2025-08-01 21:29     ` Timur Kristóf
@ 2025-08-03 16:10       ` Alexandre Demers
  2025-08-03 20:04         ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Alexandre Demers @ 2025-08-03 16:10 UTC (permalink / raw)
  To: Timur Kristóf; +Cc: amd-gfx@lists.freedesktop.org

[-- Attachment #1: Type: text/plain, Size: 4185 bytes --]

Hi Timur,

I agree with you about the coding style (the prefix), it was more of a
general comment since the style is inconsistent with some other parts in
the DC code.

If the code applies to any DCE version (even though it is unclear if any >
DCE 10 is in the field with a DAC), then it's good for me. My only
remaining concern would be about encountering one of those special GPU
cards hardly testable. But this seems unlikely.

Alexandre

On Fri, Aug 1, 2025 at 5:29 PM Timur Kristóf <timur.kristof@gmail.com>
wrote:

>
> 2025. augusztus 1., péntek dátummal Alexandre Demers <
> alexandre.f.demers@gmail.com> ezt írta:
> >> Add stream encoders for DCE6-10 only, because there are definitely
> >> graphics cards with analog connectors out there with these DCE
> >> versions. I am not aware of newer ones.
> >
> >> Considering that all stream encoder functions currently have to do
> >> with digital streams, there is nothing for an analog stream
> >> encoder to do, making them basically a no-op.
> >> That being said, we still need some kind of stream encoder to
> >> represent an analog stream, and it is beneficial to split them from
> >> digital stream encoders in the code to make sure they don't
> >> accidentally write any DIG* registers.
> >>
> >> Signed-off-by: Timur Kristóf <timur.kristof at gmail.com>
> >> ---
> >> .../drm/amd/display/dc/dce/dce_stream_encoder.c | 14 ++++++++++++++
> >> .../drm/amd/display/dc/dce/dce_stream_encoder.h | 5 +++++
> >> .../display/dc/resource/dce100/dce100_resource.c | 6 ++++++
> >> .../amd/display/dc/resource/dce60/dce60_resource.c | 8 ++++++++
> >> .../amd/display/dc/resource/dce80/dce80_resource.c | 8 ++++++++
> >> 5 files changed, 41 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> >> index 1130d7619b26..f8996ee2856b 100644
> >> --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> >> +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
> >> @@ -1567,3 +1567,17 @@ void dce110_stream_encoder_construct(
> >> enc110->se_shift = se_shift;
> >> enc110->se_mask = se_mask;
> >> }
> >> +
> >> +static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {0};
> >> +
> >> +void dce110_analog_stream_encoder_construct(
> >> + struct dce110_stream_encoder *enc110,
> >> + struct dc_context *ctx,
> >> + struct dc_bios *bp,
> >> + enum engine_id eng_id)
> >> +{
> >> + enc110->base.funcs = &dce110_an_str_enc_funcs;
> >> + enc110->base.ctx = ctx;
> >> + enc110->base.id = eng_id;
> >> + enc110->base.bp = bp;
> >> +}
> >
> > Since we are adding analog stream encoder support only up to DCE10,
> wouldn't it be better if the prefix "dce100_" was used instead? I know
> there are a few functions in there that use "dce110_" as prefix and are
> replaced by functions specific to the DCE versions that behave differently
> (we even have dce60_ and dce80_ in the current patch), but this seems off
> otherwise.
> >
> > IMO, if thie DCE code should be revisited, "dce_" should be the general
> prefix instead of "dce110_", with "dceXY_" being specific (as it is right
> now).
> > Alexandre
>
> Hi Alexandre,
>
> Two reasons:
>
> 1. As best as I can tell, all DCE versions use dce110_stream_encoder
> regardless of its name. I agree that this is somewhat counter-intuitive but
> I wanted to follow the conventions in the rest of this file.
>
> 2. It is unclear which DCE versions actually have a DAC. On one hand there
> is some conversation on this ML that suggests that Hawaii and newer don't
> have a DAC, which is apparently wrong. Looking at the register headers, all
> DCE including the latest one have the DAC registers. Theoretically, if
> there were newer GPUs with DAC, this code would work fine on them too.
>
> If you are not happy with the code style, I respect that but I would like
> if we tackled that separarely.
>
> With these series, I want to just focus on fixing things and getting DC to
> work on SI and CIK with the least possible risk of breaking things.
>
> Best regards,
> Timur

[-- Attachment #2: Type: text/html, Size: 5042 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders
  2025-08-01 22:02     ` Timur Kristóf
@ 2025-08-03 16:26       ` Alexandre Demers
  2025-08-03 20:08         ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Alexandre Demers @ 2025-08-03 16:26 UTC (permalink / raw)
  To: Timur Kristóf; +Cc: amd-gfx@lists.freedesktop.org

[-- Attachment #1: Type: text/plain, Size: 2218 bytes --]

On Fri, Aug 1, 2025 at 6:02 PM Timur Kristóf <timur.kristof@gmail.com>
wrote:

>
>
> 2025. augusztus 1., péntek dátummal Alexandre Demers <
> alexandre.f.demers@gmail.com> ezt írta:
> >> We support two kinds of analog connections:
> >>
> >> 1. VGA, which only supports analog signals:
> >> For VGA, we need to create a link encoder that only works with the
> >> DAC without perturbing any digital transmitter functionality.
> >> This is achieved by the new dce110_analog_link_encoder_construct.
> >>
> >> 2. DVI-I, which allows both digital and analog signals:
> >> The DC code base only allows 1 encoder per connector, and the
> >> preferred engine type is still going to be digital. So, for DVI-I
> >> to work, we need to make sure the pre-existing link encoder can
> >> also work with analog signals.
> >>
> >> Signed-off-by: Timur Kristóf <timur.kristof at gmail.com>
> >> ---
> >> .../drm/amd/display/dc/dce/dce_link_encoder.c | 100 ++++++++++++++++++
> >> .../drm/amd/display/dc/dce/dce_link_encoder.h | 21 ++--
> >
> > I have the same comment about the use of "dce110_" prefix under
> general/global DCE code that I left on the previous patch.
> >
> > For consistency with the current code, I understand why this prefix is
> used, but I'd gladly clean this up once the patches have landed in if there
> is a common agreement.
> >
> > Alexandre
>
> Hi Alexandre,
>
> With regards to the coding style. I already replied to your other thread
> about it, let's have that conversation there.
>
> With regards to the link encoders specifically. Due to DVI-I, we need
> dce110_link_encoder to handle analog signals in addition to digital, so the
> question about this part is, is there any need to have a separate
> dce110_analog_link_encoder? When I wrote the patch I felt yes, but now I
> feel maybe we should just let dce110_link_encoder handle VGA as well.
>
> What do you think about that?
>
> Thanks,
> Timur
>
>
> Since a distinction is already made in the code between digital and analog
encoders, I would be tempted to go with the dce110_analog_link_encoder so
it may be just easier/quicker to distinguish what this part of code does.

Alexandre

[-- Attachment #2: Type: text/html, Size: 2789 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders
  2025-08-03 16:10       ` Alexandre Demers
@ 2025-08-03 20:04         ` Timur Kristóf
  0 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-08-03 20:04 UTC (permalink / raw)
  To: Alexandre Demers; +Cc: amd-gfx@lists.freedesktop.org

On Sun, 2025-08-03 at 12:10 -0400, Alexandre Demers wrote:
> Hi Timur,
> 
> I agree with you about the coding style (the prefix), it was more of
> a general comment since the style is inconsistent with some other
> parts in the DC code.
> 
> If the code applies to any DCE version (even though it is unclear if
> any > DCE 10 is in the field with a DAC), then it's good for me. My
> only remaining concern would be about encountering one of those
> special GPU cards hardly testable. But this seems unlikely.

Hi Alexandre,

I'll stay with the current style then.

I would appreciate a review on the rest of my patch series too, if you
have time.

(By the way, you can convince me to do some code cleanup too, after all
of my DC related series are accepted.)

Thanks & best regards,
Timur

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders
  2025-08-03 16:26       ` Alexandre Demers
@ 2025-08-03 20:08         ` Timur Kristóf
  0 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-08-03 20:08 UTC (permalink / raw)
  To: Alexandre Demers; +Cc: amd-gfx@lists.freedesktop.org

On Sun, 2025-08-03 at 12:26 -0400, Alexandre Demers wrote:
> On Fri, Aug 1, 2025 at 6:02 PM Timur Kristóf
> <timur.kristof@gmail.com> wrote:
> > 
> > Hi Alexandre,
> > 
> > With regards to the coding style. I already replied to your other
> > thread about it, let's have that conversation there.
> > 
> > With regards to the link encoders specifically. Due to DVI-I, we
> > need dce110_link_encoder to handle analog signals in addition to
> > digital, so the question about this part is, is there any need to
> > have a separate dce110_analog_link_encoder? When I wrote the patch
> > I felt yes, but now I feel maybe we should just let
> > dce110_link_encoder handle VGA as well.
> > 
> > What do you think about that?
> > 
> > Thanks,
> > Timur
> > 
> > 
> > 
> 
> Since a distinction is already made in the code between digital and
> analog encoders, I would be tempted to go with the
> dce110_analog_link_encoder so it may be just easier/quicker to
> distinguish what this part of code does.
> 
> Alexandre

Well, that's the issue. The distinction isn't really there:

- dce110_link_encoder does both analog and digital for DVI-I
- dce110_analog_link_encoder can only do analog for VGA

At this point I feel that adding the dce110_analog_link_encoder just
creates unnecessary confusion.

Since dce110_link_encoder does both analog and digital already, it will
make more sense to have just dce110_link_encoder. I'll make that change
in v2 of this series.

Timur

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-07-23 15:57 ` [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately Timur Kristóf
  2025-07-29 18:03   ` Harry Wentland
@ 2025-08-06 14:56   ` Harry Wentland
  2025-08-06 17:45     ` Timur Kristóf
  1 sibling, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-08-06 14:56 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx

On 2025-07-23 11:57, Timur Kristóf wrote:
> Previously, DC determined the DRM connector type based on the
> signal type, which becomes problematic when a connector may
> support different signal types, such as DVI-I.
> 
> With this patch, it is now determined according to the actual
> connector type in DC, meaning it can now distinguish between
> DVI-D and DVI-I connectors.
> 
> A subsequent commit will enable polling for these connectors.
> 

Hi Timur,

this patch regresses the kms_bw IGT test with Navi 31 and 48
with a single 4k60 DP display connected. These subtests fail
when they should pass:

linear-tiling-2-displays-1920x1080p
linear-tiling-2-displays-2160x1440p
linear-tiling-2-displays-2560x1440p
linear-tiling-2-displays-3840x2160p
linear-tiling-3-displays-1920x1080p
linear-tiling-3-displays-2160x1440p
linear-tiling-3-displays-2560x1440p
linear-tiling-3-displays-3840x2160p
linear-tiling-4-displays-1920x1080p
linear-tiling-4-displays-2160x1440p
linear-tiling-4-displays-2560x1440p
linear-tiling-4-displays-3840x2160p

We confirmed with a revert of this patch.

Harry

> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++--------
>  1 file changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 096b23ad4845..c347b232ae06 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -8038,24 +8038,26 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
>  	return 0;
>  }
>  
> -static int to_drm_connector_type(enum signal_type st)
> +static int to_drm_connector_type(uint32_t connector_id)
>  {
> -	switch (st) {
> -	case SIGNAL_TYPE_HDMI_TYPE_A:
> +	switch (connector_id) {
> +	case CONNECTOR_ID_HDMI_TYPE_A:
>  		return DRM_MODE_CONNECTOR_HDMIA;
> -	case SIGNAL_TYPE_EDP:
> +	case CONNECTOR_ID_EDP:
>  		return DRM_MODE_CONNECTOR_eDP;
> -	case SIGNAL_TYPE_LVDS:
> +	case CONNECTOR_ID_LVDS:
>  		return DRM_MODE_CONNECTOR_LVDS;
> -	case SIGNAL_TYPE_RGB:
> +	case CONNECTOR_ID_VGA:
>  		return DRM_MODE_CONNECTOR_VGA;
> -	case SIGNAL_TYPE_DISPLAY_PORT:
> -	case SIGNAL_TYPE_DISPLAY_PORT_MST:
> +	case CONNECTOR_ID_DISPLAY_PORT:
>  		return DRM_MODE_CONNECTOR_DisplayPort;
> -	case SIGNAL_TYPE_DVI_DUAL_LINK:
> -	case SIGNAL_TYPE_DVI_SINGLE_LINK:
> +	case CONNECTOR_ID_SINGLE_LINK_DVID:
> +	case CONNECTOR_ID_DUAL_LINK_DVID:
>  		return DRM_MODE_CONNECTOR_DVID;
> -	case SIGNAL_TYPE_VIRTUAL:
> +	case CONNECTOR_ID_SINGLE_LINK_DVII:
> +	case CONNECTOR_ID_DUAL_LINK_DVII:
> +		return DRM_MODE_CONNECTOR_DVII;
> +	case CONNECTOR_ID_VIRTUAL:
>  		return DRM_MODE_CONNECTOR_VIRTUAL;
>  
>  	default:
> @@ -8440,6 +8442,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
>  			link->link_enc->features.dp_ycbcr420_supported ? true : false;
>  		break;
>  	case DRM_MODE_CONNECTOR_DVID:
> +	case DRM_MODE_CONNECTOR_DVII:
> +	case DRM_MODE_CONNECTOR_VGA:
>  		aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
>  		break;
>  	default:
> @@ -8631,7 +8635,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
>  		goto out_free;
>  	}
>  
> -	connector_type = to_drm_connector_type(link->connector_signal);
> +	connector_type = to_drm_connector_type(link->link_id.id);
>  
>  	res = drm_connector_init_with_ddc(
>  			dm->ddev,


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-08-06 14:56   ` Harry Wentland
@ 2025-08-06 17:45     ` Timur Kristóf
  2025-08-06 18:13       ` Harry Wentland
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-08-06 17:45 UTC (permalink / raw)
  To: Harry Wentland; +Cc: amd-gfx list

[-- Attachment #1: Type: text/plain, Size: 4368 bytes --]

Harry Wentland <harry.wentland@amd.com> ezt írta (időpont: 2025. aug. 6.,
Sze 16:56):

> On 2025-07-23 11:57, Timur Kristóf wrote:
> > Previously, DC determined the DRM connector type based on the
> > signal type, which becomes problematic when a connector may
> > support different signal types, such as DVI-I.
> >
> > With this patch, it is now determined according to the actual
> > connector type in DC, meaning it can now distinguish between
> > DVI-D and DVI-I connectors.
> >
> > A subsequent commit will enable polling for these connectors.
> >
>
> Hi Timur,
>
> this patch regresses the kms_bw IGT test with Navi 31 and 48
> with a single 4k60 DP display connected. These subtests fail
> when they should pass:
>
> linear-tiling-2-displays-1920x1080p
> linear-tiling-2-displays-2160x1440p
> linear-tiling-2-displays-2560x1440p
> linear-tiling-2-displays-3840x2160p
> linear-tiling-3-displays-1920x1080p
> linear-tiling-3-displays-2160x1440p
> linear-tiling-3-displays-2560x1440p
> linear-tiling-3-displays-3840x2160p
> linear-tiling-4-displays-1920x1080p
> linear-tiling-4-displays-2160x1440p
> linear-tiling-4-displays-2560x1440p
> linear-tiling-4-displays-3840x2160p
>
> We confirmed with a revert of this patch.
>
> Harry
>

Hi Harry,

Also, can you please help me figure out how do I reproduce this on my own?

At the moment I don't see what is there that would make a difference to
Navi 31 or 48.

Thanks,
Timur



> > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > ---
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++--------
> >  1 file changed, 16 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > index 096b23ad4845..c347b232ae06 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -8038,24 +8038,26 @@ static int
> dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
> >       return 0;
> >  }
> >
> > -static int to_drm_connector_type(enum signal_type st)
> > +static int to_drm_connector_type(uint32_t connector_id)
> >  {
> > -     switch (st) {
> > -     case SIGNAL_TYPE_HDMI_TYPE_A:
> > +     switch (connector_id) {
> > +     case CONNECTOR_ID_HDMI_TYPE_A:
> >               return DRM_MODE_CONNECTOR_HDMIA;
> > -     case SIGNAL_TYPE_EDP:
> > +     case CONNECTOR_ID_EDP:
> >               return DRM_MODE_CONNECTOR_eDP;
> > -     case SIGNAL_TYPE_LVDS:
> > +     case CONNECTOR_ID_LVDS:
> >               return DRM_MODE_CONNECTOR_LVDS;
> > -     case SIGNAL_TYPE_RGB:
> > +     case CONNECTOR_ID_VGA:
> >               return DRM_MODE_CONNECTOR_VGA;
> > -     case SIGNAL_TYPE_DISPLAY_PORT:
> > -     case SIGNAL_TYPE_DISPLAY_PORT_MST:
> > +     case CONNECTOR_ID_DISPLAY_PORT:
> >               return DRM_MODE_CONNECTOR_DisplayPort;
> > -     case SIGNAL_TYPE_DVI_DUAL_LINK:
> > -     case SIGNAL_TYPE_DVI_SINGLE_LINK:
> > +     case CONNECTOR_ID_SINGLE_LINK_DVID:
> > +     case CONNECTOR_ID_DUAL_LINK_DVID:
> >               return DRM_MODE_CONNECTOR_DVID;
> > -     case SIGNAL_TYPE_VIRTUAL:
> > +     case CONNECTOR_ID_SINGLE_LINK_DVII:
> > +     case CONNECTOR_ID_DUAL_LINK_DVII:
> > +             return DRM_MODE_CONNECTOR_DVII;
> > +     case CONNECTOR_ID_VIRTUAL:
> >               return DRM_MODE_CONNECTOR_VIRTUAL;
> >
> >       default:
> > @@ -8440,6 +8442,8 @@ void amdgpu_dm_connector_init_helper(struct
> amdgpu_display_manager *dm,
> >                       link->link_enc->features.dp_ycbcr420_supported ?
> true : false;
> >               break;
> >       case DRM_MODE_CONNECTOR_DVID:
> > +     case DRM_MODE_CONNECTOR_DVII:
> > +     case DRM_MODE_CONNECTOR_VGA:
> >               aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
> >               break;
> >       default:
> > @@ -8631,7 +8635,7 @@ static int amdgpu_dm_connector_init(struct
> amdgpu_display_manager *dm,
> >               goto out_free;
> >       }
> >
> > -     connector_type = to_drm_connector_type(link->connector_signal);
> > +     connector_type = to_drm_connector_type(link->link_id.id);
> >
> >       res = drm_connector_init_with_ddc(
> >                       dm->ddev,
>
>

[-- Attachment #2: Type: text/html, Size: 5931 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-08-06 17:45     ` Timur Kristóf
@ 2025-08-06 18:13       ` Harry Wentland
  2025-08-20 11:49         ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-08-06 18:13 UTC (permalink / raw)
  To: Timur Kristóf; +Cc: amd-gfx list



On 2025-08-06 13:45, Timur Kristóf wrote:
> 
> Harry Wentland <harry.wentland@amd.com <mailto:harry.wentland@amd.com>> ezt írta (időpont: 2025. aug. 6., Sze 16:56):
> 
>     On 2025-07-23 11:57, Timur Kristóf wrote:
>     > Previously, DC determined the DRM connector type based on the
>     > signal type, which becomes problematic when a connector may
>     > support different signal types, such as DVI-I.
>     >
>     > With this patch, it is now determined according to the actual
>     > connector type in DC, meaning it can now distinguish between
>     > DVI-D and DVI-I connectors.
>     >
>     > A subsequent commit will enable polling for these connectors.
>     >
> 
>     Hi Timur,
> 
>     this patch regresses the kms_bw IGT test with Navi 31 and 48
>     with a single 4k60 DP display connected. These subtests fail
>     when they should pass:
> 
>     linear-tiling-2-displays-1920x1080p
>     linear-tiling-2-displays-2160x1440p
>     linear-tiling-2-displays-2560x1440p
>     linear-tiling-2-displays-3840x2160p
>     linear-tiling-3-displays-1920x1080p
>     linear-tiling-3-displays-2160x1440p
>     linear-tiling-3-displays-2560x1440p
>     linear-tiling-3-displays-3840x2160p
>     linear-tiling-4-displays-1920x1080p
>     linear-tiling-4-displays-2160x1440p
>     linear-tiling-4-displays-2560x1440p
>     linear-tiling-4-displays-3840x2160p
> 
>     We confirmed with a revert of this patch.
> 
>     Harry
> 
> 
> Hi Harry,
> 
> Also, can you please help me figure out how do I reproduce this on my own?
> 

- Build IGT using the guide at https://gitlab.freedesktop.org/drm/igt-gpu-tools
  (it's really just meson and ninja)
- Switch to a free VT (e.g., Ctrl+Alt+F3)
- log in as root
- run the test tests/kms_bw
  (optionally use --list-subtests to list subtests, and
   --run-subtest <subtestname> to run a subtest)

> At the moment I don't see what is there that would make a difference to Navi 31 or 48.
> 

Not sure either. But that's why we have these tests because
they often catch things that aren't obvious.

Harry

> Thanks,
> Timur
> 
> 
> 
>     > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com <mailto:timur.kristof@gmail.com>>
>     > ---
>     >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +++++++++++--------
>     >  1 file changed, 16 insertions(+), 12 deletions(-)
>     >
>     > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>     > index 096b23ad4845..c347b232ae06 100644
>     > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>     > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>     > @@ -8038,24 +8038,26 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
>     >       return 0;
>     >  }
>     > 
>     > -static int to_drm_connector_type(enum signal_type st)
>     > +static int to_drm_connector_type(uint32_t connector_id)
>     >  {
>     > -     switch (st) {
>     > -     case SIGNAL_TYPE_HDMI_TYPE_A:
>     > +     switch (connector_id) {
>     > +     case CONNECTOR_ID_HDMI_TYPE_A:
>     >               return DRM_MODE_CONNECTOR_HDMIA;
>     > -     case SIGNAL_TYPE_EDP:
>     > +     case CONNECTOR_ID_EDP:
>     >               return DRM_MODE_CONNECTOR_eDP;
>     > -     case SIGNAL_TYPE_LVDS:
>     > +     case CONNECTOR_ID_LVDS:
>     >               return DRM_MODE_CONNECTOR_LVDS;
>     > -     case SIGNAL_TYPE_RGB:
>     > +     case CONNECTOR_ID_VGA:
>     >               return DRM_MODE_CONNECTOR_VGA;
>     > -     case SIGNAL_TYPE_DISPLAY_PORT:
>     > -     case SIGNAL_TYPE_DISPLAY_PORT_MST:
>     > +     case CONNECTOR_ID_DISPLAY_PORT:
>     >               return DRM_MODE_CONNECTOR_DisplayPort;
>     > -     case SIGNAL_TYPE_DVI_DUAL_LINK:
>     > -     case SIGNAL_TYPE_DVI_SINGLE_LINK:
>     > +     case CONNECTOR_ID_SINGLE_LINK_DVID:
>     > +     case CONNECTOR_ID_DUAL_LINK_DVID:
>     >               return DRM_MODE_CONNECTOR_DVID;
>     > -     case SIGNAL_TYPE_VIRTUAL:
>     > +     case CONNECTOR_ID_SINGLE_LINK_DVII:
>     > +     case CONNECTOR_ID_DUAL_LINK_DVII:
>     > +             return DRM_MODE_CONNECTOR_DVII;
>     > +     case CONNECTOR_ID_VIRTUAL:
>     >               return DRM_MODE_CONNECTOR_VIRTUAL;
>     > 
>     >       default:
>     > @@ -8440,6 +8442,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
>     >                       link->link_enc->features.dp_ycbcr420_supported ? true : false;
>     >               break;
>     >       case DRM_MODE_CONNECTOR_DVID:
>     > +     case DRM_MODE_CONNECTOR_DVII:
>     > +     case DRM_MODE_CONNECTOR_VGA:
>     >               aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
>     >               break;
>     >       default:
>     > @@ -8631,7 +8635,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
>     >               goto out_free;
>     >       }
>     > 
>     > -     connector_type = to_drm_connector_type(link->connector_signal);
>     > +     connector_type = to_drm_connector_type(link->link_id.id <http://link_id.id>);
>     > 
>     >       res = drm_connector_init_with_ddc(
>     >                       dm->ddev,
> 


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-07-23 15:58 ` [PATCH 13/20] drm/amd/display: Add analog link detection Timur Kristóf
@ 2025-08-07 19:12   ` Harry Wentland
  2025-08-07 20:34     ` Harry Wentland
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-08-07 19:12 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx

On 2025-07-23 11:58, Timur Kristóf wrote:
> Analog displays typically have a DDC connection which can be
> used by the GPU to read EDID. This commit adds the capability
> to probe analog displays using DDC, reading the EDID header and
> deciding whether the analog link is connected based on the data
> that was read.
> 
> As a reference, I used the following functions:
> amdgpu_connector_vga_detect
> amdgpu_display_ddc_probe
> 
> DAC load detection will be implemented in a separate commit.

Another regression in our internal testing with this patch, unfortunately
only on not-yet released HW.

I wonder if pipe-ctx->stream could be NULL in some cases.

Harry

> 
> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
>  .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
>  .../drm/amd/display/dc/link/link_detection.c  | 80 ++++++++++++++++++-
>  .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
>  .../drm/amd/display/dc/link/link_factory.c    |  3 +
>  4 files changed, 95 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> index f3470716734d..b9ebb992dc98 100644
> --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> @@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
>  		return;
>  	}
>  
> -	link_enc->funcs->connect_dig_be_to_fe(link_enc,
> -			pipe_ctx->stream_res.stream_enc->id, true);
> +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> +		link_enc->funcs->connect_dig_be_to_fe(link_enc,
> +				pipe_ctx->stream_res.stream_enc->id, true);
>  	if (dc_is_dp_signal(pipe_ctx->stream->signal))
>  		pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(pipe_ctx->stream->link,
>  				DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
> @@ -98,10 +99,13 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
>  	if (stream_enc->funcs->enable_stream)
>  		stream_enc->funcs->enable_stream(stream_enc,
>  				pipe_ctx->stream->signal, false);
> -	link_enc->funcs->connect_dig_be_to_fe(
> -			link_enc,
> -			pipe_ctx->stream_res.stream_enc->id,
> -			false);
> +
> +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> +		link_enc->funcs->connect_dig_be_to_fe(
> +				link_enc,
> +				pipe_ctx->stream_res.stream_enc->id,
> +				false);
> +
>  	if (dc_is_dp_signal(pipe_ctx->stream->signal))
>  		pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(
>  				pipe_ctx->stream->link,
> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> index 827b630daf49..fcabc83464af 100644
> --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> @@ -942,6 +942,12 @@ static bool detect_link_and_local_sink(struct dc_link *link,
>  			break;
>  		}
>  
> +		case SIGNAL_TYPE_RGB: {
> +			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
> +			sink_caps.signal = SIGNAL_TYPE_RGB;
> +			break;
> +		}
> +
>  		case SIGNAL_TYPE_LVDS: {
>  			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
>  			sink_caps.signal = SIGNAL_TYPE_LVDS;
> @@ -1133,9 +1139,17 @@ static bool detect_link_and_local_sink(struct dc_link *link,
>  				sink = prev_sink;
>  				prev_sink = NULL;
>  			}
> -			query_hdcp_capability(sink->sink_signal, link);
> +
> +			if (!sink->edid_caps.analog)
> +				query_hdcp_capability(sink->sink_signal, link);
>  		}
>  
> +		/* DVI-I connector connected to analog display. */
> +		if ((link->link_enc->connector.id == CONNECTOR_ID_DUAL_LINK_DVII ||
> +		     link->link_enc->connector.id == CONNECTOR_ID_SINGLE_LINK_DVII) &&
> +			sink->edid_caps.analog)
> +			sink->sink_signal = SIGNAL_TYPE_RGB;
> +
>  		/* HDMI-DVI Dongle */
>  		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
>  		    !sink->edid_caps.edid_hdmi)
> @@ -1228,6 +1242,64 @@ static bool detect_link_and_local_sink(struct dc_link *link,
>  	return true;
>  }
>  
> +/**
> + * Evaluates whether an EDID header is acceptable,
> + * for the purpose of determining a connection with a display.
> + */
> +static bool link_detect_evaluate_edid_header(uint8_t edid_header[8])
> +{
> +	int edid_header_score = 0;
> +	int i;
> +
> +	for (i = 0; i < 8; ++i)
> +		edid_header_score += edid_header[i] == ((i == 0 || i == 7) ? 0x00 : 0xff);
> +
> +	return edid_header_score >= 6;
> +}
> +
> +/**
> + * Tries to detect a connected display by probing the DDC
> + * and reading the EDID header.
> + * The probing is considered successful if we receive a
> + * reply from the DDC over I2C and the EDID header matches.
> + */
> +static bool link_detect_ddc_probe(struct dc_link *link)
> +{
> +	if (!link->ddc)
> +		return false;
> +
> +	uint8_t edid_header[8] = {0};
> +	bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header, sizeof(edid_header));
> +
> +	if (!ddc_probed)
> +		return false;
> +
> +	if (!link_detect_evaluate_edid_header(edid_header))
> +		return false;
> +
> +	return true;
> +}
> +
> +/**
> + * Determines if there is an analog sink connected.
> + */
> +static bool link_detect_analog(struct dc_link *link, enum dc_connection_type *type)
> +{
> +	/* Don't care about connectors that don't support an analog signal. */
> +	if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
> +		link->link_enc->connector.id != CONNECTOR_ID_SINGLE_LINK_DVII &&
> +		link->link_enc->connector.id != CONNECTOR_ID_DUAL_LINK_DVII)
> +		return false;
> +
> +	if (link_detect_ddc_probe(link)) {
> +		*type = dc_connection_single;
> +		return true;
> +	}
> +
> +	*type = dc_connection_none;
> +	return true;
> +}
> +
>  /*
>   * link_detect_connection_type() - Determine if there is a sink connected
>   *
> @@ -1238,6 +1310,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
>  bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type)
>  {
>  	uint32_t is_hpd_high = 0;
> +	bool supports_hpd = link->irq_source_hpd != DC_IRQ_SOURCE_INVALID;
>  
>  	if (link->connector_signal == SIGNAL_TYPE_LVDS) {
>  		*type = dc_connection_single;
> @@ -1261,6 +1334,8 @@ bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *
>  		return true;
>  	}
>  
> +	if (!supports_hpd)
> +		return link_detect_analog(link, type);
>  
>  	if (!query_hpd_status(link, &is_hpd_high))
>  		goto hpd_gpio_failure;
> @@ -1269,6 +1344,9 @@ bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *
>  		*type = dc_connection_single;
>  		/* TODO: need to do the actual detection */
>  	} else {
> +		if (link_detect_analog(link, type))
> +			return true;
> +
>  		*type = dc_connection_none;
>  		if (link->connector_signal == SIGNAL_TYPE_EDP) {
>  			/* eDP is not connected, power down it */
> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> index d6b7347c6c11..ac25d89a4148 100644
> --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> @@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
>  		enable_link_lvds(pipe_ctx);
>  		status = DC_OK;
>  		break;
> +	case SIGNAL_TYPE_RGB:
> +		status = DC_OK;
> +		break;
>  	case SIGNAL_TYPE_VIRTUAL:
>  		status = enable_link_virtual(pipe_ctx);
>  		break;
> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> index 71c10a1261b9..c9725fd316f6 100644
> --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> @@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link *link,
>  	case CONNECTOR_ID_DUAL_LINK_DVII:
>  		link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
>  		break;
> +	case CONNECTOR_ID_VGA:
> +		link->connector_signal = SIGNAL_TYPE_RGB;
> +		break;
>  	case CONNECTOR_ID_DISPLAY_PORT:
>  	case CONNECTOR_ID_MXM:
>  	case CONNECTOR_ID_USBC:


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-08-07 19:12   ` Harry Wentland
@ 2025-08-07 20:34     ` Harry Wentland
  2025-08-07 21:32       ` Timur Kristóf
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-08-07 20:34 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx



On 2025-08-07 15:12, Harry Wentland wrote:
> On 2025-07-23 11:58, Timur Kristóf wrote:
>> Analog displays typically have a DDC connection which can be
>> used by the GPU to read EDID. This commit adds the capability
>> to probe analog displays using DDC, reading the EDID header and
>> deciding whether the analog link is connected based on the data
>> that was read.
>>
>> As a reference, I used the following functions:
>> amdgpu_connector_vga_detect
>> amdgpu_display_ddc_probe
>>
>> DAC load detection will be implemented in a separate commit.
> 
> Another regression in our internal testing with this patch, unfortunately
> only on not-yet released HW.
> 

While this shows on unreleased HW I wouldn't be surprised if it
repros on other (recent-ish) APUs (integrated GPUs). It's just
that this week's test was on currently unreleased HW.

Harry

> I wonder if pipe-ctx->stream could be NULL in some cases.
> 
> Harry
> 
>>
>> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
>> ---
>>  .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
>>  .../drm/amd/display/dc/link/link_detection.c  | 80 ++++++++++++++++++-
>>  .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
>>  .../drm/amd/display/dc/link/link_factory.c    |  3 +
>>  4 files changed, 95 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>> index f3470716734d..b9ebb992dc98 100644
>> --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>> +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>> @@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
>>  		return;
>>  	}
>>  
>> -	link_enc->funcs->connect_dig_be_to_fe(link_enc,
>> -			pipe_ctx->stream_res.stream_enc->id, true);
>> +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
>> +		link_enc->funcs->connect_dig_be_to_fe(link_enc,
>> +				pipe_ctx->stream_res.stream_enc->id, true);
>>  	if (dc_is_dp_signal(pipe_ctx->stream->signal))
>>  		pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(pipe_ctx->stream->link,
>>  				DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
>> @@ -98,10 +99,13 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
>>  	if (stream_enc->funcs->enable_stream)
>>  		stream_enc->funcs->enable_stream(stream_enc,
>>  				pipe_ctx->stream->signal, false);
>> -	link_enc->funcs->connect_dig_be_to_fe(
>> -			link_enc,
>> -			pipe_ctx->stream_res.stream_enc->id,
>> -			false);
>> +
>> +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
>> +		link_enc->funcs->connect_dig_be_to_fe(
>> +				link_enc,
>> +				pipe_ctx->stream_res.stream_enc->id,
>> +				false);
>> +
>>  	if (dc_is_dp_signal(pipe_ctx->stream->signal))
>>  		pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(
>>  				pipe_ctx->stream->link,
>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>> index 827b630daf49..fcabc83464af 100644
>> --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>> @@ -942,6 +942,12 @@ static bool detect_link_and_local_sink(struct dc_link *link,
>>  			break;
>>  		}
>>  
>> +		case SIGNAL_TYPE_RGB: {
>> +			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
>> +			sink_caps.signal = SIGNAL_TYPE_RGB;
>> +			break;
>> +		}
>> +
>>  		case SIGNAL_TYPE_LVDS: {
>>  			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
>>  			sink_caps.signal = SIGNAL_TYPE_LVDS;
>> @@ -1133,9 +1139,17 @@ static bool detect_link_and_local_sink(struct dc_link *link,
>>  				sink = prev_sink;
>>  				prev_sink = NULL;
>>  			}
>> -			query_hdcp_capability(sink->sink_signal, link);
>> +
>> +			if (!sink->edid_caps.analog)
>> +				query_hdcp_capability(sink->sink_signal, link);
>>  		}
>>  
>> +		/* DVI-I connector connected to analog display. */
>> +		if ((link->link_enc->connector.id == CONNECTOR_ID_DUAL_LINK_DVII ||
>> +		     link->link_enc->connector.id == CONNECTOR_ID_SINGLE_LINK_DVII) &&
>> +			sink->edid_caps.analog)
>> +			sink->sink_signal = SIGNAL_TYPE_RGB;
>> +
>>  		/* HDMI-DVI Dongle */
>>  		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
>>  		    !sink->edid_caps.edid_hdmi)
>> @@ -1228,6 +1242,64 @@ static bool detect_link_and_local_sink(struct dc_link *link,
>>  	return true;
>>  }
>>  
>> +/**
>> + * Evaluates whether an EDID header is acceptable,
>> + * for the purpose of determining a connection with a display.
>> + */
>> +static bool link_detect_evaluate_edid_header(uint8_t edid_header[8])
>> +{
>> +	int edid_header_score = 0;
>> +	int i;
>> +
>> +	for (i = 0; i < 8; ++i)
>> +		edid_header_score += edid_header[i] == ((i == 0 || i == 7) ? 0x00 : 0xff);
>> +
>> +	return edid_header_score >= 6;
>> +}
>> +
>> +/**
>> + * Tries to detect a connected display by probing the DDC
>> + * and reading the EDID header.
>> + * The probing is considered successful if we receive a
>> + * reply from the DDC over I2C and the EDID header matches.
>> + */
>> +static bool link_detect_ddc_probe(struct dc_link *link)
>> +{
>> +	if (!link->ddc)
>> +		return false;
>> +
>> +	uint8_t edid_header[8] = {0};
>> +	bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header, sizeof(edid_header));
>> +
>> +	if (!ddc_probed)
>> +		return false;
>> +
>> +	if (!link_detect_evaluate_edid_header(edid_header))
>> +		return false;
>> +
>> +	return true;
>> +}
>> +
>> +/**
>> + * Determines if there is an analog sink connected.
>> + */
>> +static bool link_detect_analog(struct dc_link *link, enum dc_connection_type *type)
>> +{
>> +	/* Don't care about connectors that don't support an analog signal. */
>> +	if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
>> +		link->link_enc->connector.id != CONNECTOR_ID_SINGLE_LINK_DVII &&
>> +		link->link_enc->connector.id != CONNECTOR_ID_DUAL_LINK_DVII)
>> +		return false;
>> +
>> +	if (link_detect_ddc_probe(link)) {
>> +		*type = dc_connection_single;
>> +		return true;
>> +	}
>> +
>> +	*type = dc_connection_none;
>> +	return true;
>> +}
>> +
>>  /*
>>   * link_detect_connection_type() - Determine if there is a sink connected
>>   *
>> @@ -1238,6 +1310,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
>>  bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type)
>>  {
>>  	uint32_t is_hpd_high = 0;
>> +	bool supports_hpd = link->irq_source_hpd != DC_IRQ_SOURCE_INVALID;
>>  
>>  	if (link->connector_signal == SIGNAL_TYPE_LVDS) {
>>  		*type = dc_connection_single;
>> @@ -1261,6 +1334,8 @@ bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *
>>  		return true;
>>  	}
>>  
>> +	if (!supports_hpd)
>> +		return link_detect_analog(link, type);
>>  
>>  	if (!query_hpd_status(link, &is_hpd_high))
>>  		goto hpd_gpio_failure;
>> @@ -1269,6 +1344,9 @@ bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type *
>>  		*type = dc_connection_single;
>>  		/* TODO: need to do the actual detection */
>>  	} else {
>> +		if (link_detect_analog(link, type))
>> +			return true;
>> +
>>  		*type = dc_connection_none;
>>  		if (link->connector_signal == SIGNAL_TYPE_EDP) {
>>  			/* eDP is not connected, power down it */
>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>> index d6b7347c6c11..ac25d89a4148 100644
>> --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>> @@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
>>  		enable_link_lvds(pipe_ctx);
>>  		status = DC_OK;
>>  		break;
>> +	case SIGNAL_TYPE_RGB:
>> +		status = DC_OK;
>> +		break;
>>  	case SIGNAL_TYPE_VIRTUAL:
>>  		status = enable_link_virtual(pipe_ctx);
>>  		break;
>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>> index 71c10a1261b9..c9725fd316f6 100644
>> --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>> @@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link *link,
>>  	case CONNECTOR_ID_DUAL_LINK_DVII:
>>  		link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
>>  		break;
>> +	case CONNECTOR_ID_VGA:
>> +		link->connector_signal = SIGNAL_TYPE_RGB;
>> +		break;
>>  	case CONNECTOR_ID_DISPLAY_PORT:
>>  	case CONNECTOR_ID_MXM:
>>  	case CONNECTOR_ID_USBC:
> 


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-08-07 20:34     ` Harry Wentland
@ 2025-08-07 21:32       ` Timur Kristóf
  2025-08-08 14:03         ` Harry Wentland
  0 siblings, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-08-07 21:32 UTC (permalink / raw)
  To: Harry Wentland, amd-gfx

On Thu, 2025-08-07 at 16:34 -0400, Harry Wentland wrote:
> 
> 
> On 2025-08-07 15:12, Harry Wentland wrote:
> > On 2025-07-23 11:58, Timur Kristóf wrote:
> > > Analog displays typically have a DDC connection which can be
> > > used by the GPU to read EDID. This commit adds the capability
> > > to probe analog displays using DDC, reading the EDID header and
> > > deciding whether the analog link is connected based on the data
> > > that was read.
> > > 
> > > As a reference, I used the following functions:
> > > amdgpu_connector_vga_detect
> > > amdgpu_display_ddc_probe
> > > 
> > > DAC load detection will be implemented in a separate commit.
> > 
> > Another regression in our internal testing with this patch,
> > unfortunately
> > only on not-yet released HW.
> > 
> 
> While this shows on unreleased HW I wouldn't be surprised if it
> repros on other (recent-ish) APUs (integrated GPUs). It's just
> that this week's test was on currently unreleased HW.
> 
> Harry
> 
> > I wonder if pipe-ctx->stream could be NULL in some cases.
> > 
> > Harry
> > 

Hi Harry,

Can you elaborate when / how it is valid for pipe->ctx->stream to be
NULL when the code gets here? Maybe that would give me a hint how to
resolve it.

Thanks,
Timur


> > > 
> > > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > > ---
> > >  .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
> > >  .../drm/amd/display/dc/link/link_detection.c  | 80
> > > ++++++++++++++++++-
> > >  .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
> > >  .../drm/amd/display/dc/link/link_factory.c    |  3 +
> > >  4 files changed, 95 insertions(+), 7 deletions(-)
> > > 
> > > diff --git
> > > a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > index f3470716734d..b9ebb992dc98 100644
> > > --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > @@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct pipe_ctx
> > > *pipe_ctx)
> > >  		return;
> > >  	}
> > >  
> > > -	link_enc->funcs->connect_dig_be_to_fe(link_enc,
> > > -			pipe_ctx->stream_res.stream_enc->id,
> > > true);
> > > +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > > +		link_enc->funcs->connect_dig_be_to_fe(link_enc,
> > > +				pipe_ctx->stream_res.stream_enc-
> > > >id, true);
> > >  	if (dc_is_dp_signal(pipe_ctx->stream->signal))
> > >  		pipe_ctx->stream->ctx->dc->link_srv-
> > > >dp_trace_source_sequence(pipe_ctx->stream->link,
> > >  				DPCD_SOURCE_SEQ_AFTER_CONNECT_DI
> > > G_FE_BE);
> > > @@ -98,10 +99,13 @@ void reset_dio_stream_encoder(struct pipe_ctx
> > > *pipe_ctx)
> > >  	if (stream_enc->funcs->enable_stream)
> > >  		stream_enc->funcs->enable_stream(stream_enc,
> > >  				pipe_ctx->stream->signal,
> > > false);
> > > -	link_enc->funcs->connect_dig_be_to_fe(
> > > -			link_enc,
> > > -			pipe_ctx->stream_res.stream_enc->id,
> > > -			false);
> > > +
> > > +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > > +		link_enc->funcs->connect_dig_be_to_fe(
> > > +				link_enc,
> > > +				pipe_ctx->stream_res.stream_enc-
> > > >id,
> > > +				false);
> > > +
> > >  	if (dc_is_dp_signal(pipe_ctx->stream->signal))
> > >  		pipe_ctx->stream->ctx->dc->link_srv-
> > > >dp_trace_source_sequence(
> > >  				pipe_ctx->stream->link,
> > > diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > index 827b630daf49..fcabc83464af 100644
> > > --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > @@ -942,6 +942,12 @@ static bool
> > > detect_link_and_local_sink(struct dc_link *link,
> > >  			break;
> > >  		}
> > >  
> > > +		case SIGNAL_TYPE_RGB: {
> > > +			sink_caps.transaction_type =
> > > DDC_TRANSACTION_TYPE_I2C;
> > > +			sink_caps.signal = SIGNAL_TYPE_RGB;
> > > +			break;
> > > +		}
> > > +
> > >  		case SIGNAL_TYPE_LVDS: {
> > >  			sink_caps.transaction_type =
> > > DDC_TRANSACTION_TYPE_I2C;
> > >  			sink_caps.signal = SIGNAL_TYPE_LVDS;
> > > @@ -1133,9 +1139,17 @@ static bool
> > > detect_link_and_local_sink(struct dc_link *link,
> > >  				sink = prev_sink;
> > >  				prev_sink = NULL;
> > >  			}
> > > -			query_hdcp_capability(sink->sink_signal,
> > > link);
> > > +
> > > +			if (!sink->edid_caps.analog)
> > > +				query_hdcp_capability(sink-
> > > >sink_signal, link);
> > >  		}
> > >  
> > > +		/* DVI-I connector connected to analog display.
> > > */
> > > +		if ((link->link_enc->connector.id ==
> > > CONNECTOR_ID_DUAL_LINK_DVII ||
> > > +		     link->link_enc->connector.id ==
> > > CONNECTOR_ID_SINGLE_LINK_DVII) &&
> > > +			sink->edid_caps.analog)
> > > +			sink->sink_signal = SIGNAL_TYPE_RGB;
> > > +
> > >  		/* HDMI-DVI Dongle */
> > >  		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A
> > > &&
> > >  		    !sink->edid_caps.edid_hdmi)
> > > @@ -1228,6 +1242,64 @@ static bool
> > > detect_link_and_local_sink(struct dc_link *link,
> > >  	return true;
> > >  }
> > >  
> > > +/**
> > > + * Evaluates whether an EDID header is acceptable,
> > > + * for the purpose of determining a connection with a display.
> > > + */
> > > +static bool link_detect_evaluate_edid_header(uint8_t
> > > edid_header[8])
> > > +{
> > > +	int edid_header_score = 0;
> > > +	int i;
> > > +
> > > +	for (i = 0; i < 8; ++i)
> > > +		edid_header_score += edid_header[i] == ((i == 0
> > > || i == 7) ? 0x00 : 0xff);
> > > +
> > > +	return edid_header_score >= 6;
> > > +}
> > > +
> > > +/**
> > > + * Tries to detect a connected display by probing the DDC
> > > + * and reading the EDID header.
> > > + * The probing is considered successful if we receive a
> > > + * reply from the DDC over I2C and the EDID header matches.
> > > + */
> > > +static bool link_detect_ddc_probe(struct dc_link *link)
> > > +{
> > > +	if (!link->ddc)
> > > +		return false;
> > > +
> > > +	uint8_t edid_header[8] = {0};
> > > +	bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header,
> > > sizeof(edid_header));
> > > +
> > > +	if (!ddc_probed)
> > > +		return false;
> > > +
> > > +	if (!link_detect_evaluate_edid_header(edid_header))
> > > +		return false;
> > > +
> > > +	return true;
> > > +}
> > > +
> > > +/**
> > > + * Determines if there is an analog sink connected.
> > > + */
> > > +static bool link_detect_analog(struct dc_link *link, enum
> > > dc_connection_type *type)
> > > +{
> > > +	/* Don't care about connectors that don't support an
> > > analog signal. */
> > > +	if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
> > > +		link->link_enc->connector.id !=
> > > CONNECTOR_ID_SINGLE_LINK_DVII &&
> > > +		link->link_enc->connector.id !=
> > > CONNECTOR_ID_DUAL_LINK_DVII)
> > > +		return false;
> > > +
> > > +	if (link_detect_ddc_probe(link)) {
> > > +		*type = dc_connection_single;
> > > +		return true;
> > > +	}
> > > +
> > > +	*type = dc_connection_none;
> > > +	return true;
> > > +}
> > > +
> > >  /*
> > >   * link_detect_connection_type() - Determine if there is a sink
> > > connected
> > >   *
> > > @@ -1238,6 +1310,7 @@ static bool
> > > detect_link_and_local_sink(struct dc_link *link,
> > >  bool link_detect_connection_type(struct dc_link *link, enum
> > > dc_connection_type *type)
> > >  {
> > >  	uint32_t is_hpd_high = 0;
> > > +	bool supports_hpd = link->irq_source_hpd !=
> > > DC_IRQ_SOURCE_INVALID;
> > >  
> > >  	if (link->connector_signal == SIGNAL_TYPE_LVDS) {
> > >  		*type = dc_connection_single;
> > > @@ -1261,6 +1334,8 @@ bool link_detect_connection_type(struct
> > > dc_link *link, enum dc_connection_type *
> > >  		return true;
> > >  	}
> > >  
> > > +	if (!supports_hpd)
> > > +		return link_detect_analog(link, type);
> > >  
> > >  	if (!query_hpd_status(link, &is_hpd_high))
> > >  		goto hpd_gpio_failure;
> > > @@ -1269,6 +1344,9 @@ bool link_detect_connection_type(struct
> > > dc_link *link, enum dc_connection_type *
> > >  		*type = dc_connection_single;
> > >  		/* TODO: need to do the actual detection */
> > >  	} else {
> > > +		if (link_detect_analog(link, type))
> > > +			return true;
> > > +
> > >  		*type = dc_connection_none;
> > >  		if (link->connector_signal == SIGNAL_TYPE_EDP) {
> > >  			/* eDP is not connected, power down it
> > > */
> > > diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > index d6b7347c6c11..ac25d89a4148 100644
> > > --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > @@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
> > >  		enable_link_lvds(pipe_ctx);
> > >  		status = DC_OK;
> > >  		break;
> > > +	case SIGNAL_TYPE_RGB:
> > > +		status = DC_OK;
> > > +		break;
> > >  	case SIGNAL_TYPE_VIRTUAL:
> > >  		status = enable_link_virtual(pipe_ctx);
> > >  		break;
> > > diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > index 71c10a1261b9..c9725fd316f6 100644
> > > --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > @@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link
> > > *link,
> > >  	case CONNECTOR_ID_DUAL_LINK_DVII:
> > >  		link->connector_signal =
> > > SIGNAL_TYPE_DVI_DUAL_LINK;
> > >  		break;
> > > +	case CONNECTOR_ID_VGA:
> > > +		link->connector_signal = SIGNAL_TYPE_RGB;
> > > +		break;
> > >  	case CONNECTOR_ID_DISPLAY_PORT:
> > >  	case CONNECTOR_ID_MXM:
> > >  	case CONNECTOR_ID_USBC:
> > 

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-08-07 21:32       ` Timur Kristóf
@ 2025-08-08 14:03         ` Harry Wentland
  2025-08-08 14:22           ` Wheeler, Daniel
  0 siblings, 1 reply; 61+ messages in thread
From: Harry Wentland @ 2025-08-08 14:03 UTC (permalink / raw)
  To: Timur Kristóf, amd-gfx, Daniel Wheeler



On 2025-08-07 17:32, Timur Kristóf wrote:
> On Thu, 2025-08-07 at 16:34 -0400, Harry Wentland wrote:
>>
>>
>> On 2025-08-07 15:12, Harry Wentland wrote:
>>> On 2025-07-23 11:58, Timur Kristóf wrote:
>>>> Analog displays typically have a DDC connection which can be
>>>> used by the GPU to read EDID. This commit adds the capability
>>>> to probe analog displays using DDC, reading the EDID header and
>>>> deciding whether the analog link is connected based on the data
>>>> that was read.
>>>>
>>>> As a reference, I used the following functions:
>>>> amdgpu_connector_vga_detect
>>>> amdgpu_display_ddc_probe
>>>>
>>>> DAC load detection will be implemented in a separate commit.
>>>
>>> Another regression in our internal testing with this patch,
>>> unfortunately
>>> only on not-yet released HW.
>>>
>>
>> While this shows on unreleased HW I wouldn't be surprised if it
>> repros on other (recent-ish) APUs (integrated GPUs). It's just
>> that this week's test was on currently unreleased HW.
>>
>> Harry
>>
>>> I wonder if pipe-ctx->stream could be NULL in some cases.
>>>
>>> Harry
>>>
> 
> Hi Harry,
> 
> Can you elaborate when / how it is valid for pipe->ctx->stream to be
> NULL when the code gets here? Maybe that would give me a hint how to
> resolve it.
> 

I don't know. It was just a guess.

I should've mentioned... the NULL pointer access happens on driver
load.

Dan might have more info.

Harry

> Thanks,
> Timur
> 
> 
>>>>
>>>> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
>>>> ---
>>>>  .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
>>>>  .../drm/amd/display/dc/link/link_detection.c  | 80
>>>> ++++++++++++++++++-
>>>>  .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
>>>>  .../drm/amd/display/dc/link/link_factory.c    |  3 +
>>>>  4 files changed, 95 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git
>>>> a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>>>> b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>>>> index f3470716734d..b9ebb992dc98 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>>>> @@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct pipe_ctx
>>>> *pipe_ctx)
>>>>  		return;
>>>>  	}
>>>>  
>>>> -	link_enc->funcs->connect_dig_be_to_fe(link_enc,
>>>> -			pipe_ctx->stream_res.stream_enc->id,
>>>> true);
>>>> +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
>>>> +		link_enc->funcs->connect_dig_be_to_fe(link_enc,
>>>> +				pipe_ctx->stream_res.stream_enc-
>>>>> id, true);
>>>>  	if (dc_is_dp_signal(pipe_ctx->stream->signal))
>>>>  		pipe_ctx->stream->ctx->dc->link_srv-
>>>>> dp_trace_source_sequence(pipe_ctx->stream->link,
>>>>  				DPCD_SOURCE_SEQ_AFTER_CONNECT_DI
>>>> G_FE_BE);
>>>> @@ -98,10 +99,13 @@ void reset_dio_stream_encoder(struct pipe_ctx
>>>> *pipe_ctx)
>>>>  	if (stream_enc->funcs->enable_stream)
>>>>  		stream_enc->funcs->enable_stream(stream_enc,
>>>>  				pipe_ctx->stream->signal,
>>>> false);
>>>> -	link_enc->funcs->connect_dig_be_to_fe(
>>>> -			link_enc,
>>>> -			pipe_ctx->stream_res.stream_enc->id,
>>>> -			false);
>>>> +
>>>> +	if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
>>>> +		link_enc->funcs->connect_dig_be_to_fe(
>>>> +				link_enc,
>>>> +				pipe_ctx->stream_res.stream_enc-
>>>>> id,
>>>> +				false);
>>>> +
>>>>  	if (dc_is_dp_signal(pipe_ctx->stream->signal))
>>>>  		pipe_ctx->stream->ctx->dc->link_srv-
>>>>> dp_trace_source_sequence(
>>>>  				pipe_ctx->stream->link,
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>>>> b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>>>> index 827b630daf49..fcabc83464af 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>>>> @@ -942,6 +942,12 @@ static bool
>>>> detect_link_and_local_sink(struct dc_link *link,
>>>>  			break;
>>>>  		}
>>>>  
>>>> +		case SIGNAL_TYPE_RGB: {
>>>> +			sink_caps.transaction_type =
>>>> DDC_TRANSACTION_TYPE_I2C;
>>>> +			sink_caps.signal = SIGNAL_TYPE_RGB;
>>>> +			break;
>>>> +		}
>>>> +
>>>>  		case SIGNAL_TYPE_LVDS: {
>>>>  			sink_caps.transaction_type =
>>>> DDC_TRANSACTION_TYPE_I2C;
>>>>  			sink_caps.signal = SIGNAL_TYPE_LVDS;
>>>> @@ -1133,9 +1139,17 @@ static bool
>>>> detect_link_and_local_sink(struct dc_link *link,
>>>>  				sink = prev_sink;
>>>>  				prev_sink = NULL;
>>>>  			}
>>>> -			query_hdcp_capability(sink->sink_signal,
>>>> link);
>>>> +
>>>> +			if (!sink->edid_caps.analog)
>>>> +				query_hdcp_capability(sink-
>>>>> sink_signal, link);
>>>>  		}
>>>>  
>>>> +		/* DVI-I connector connected to analog display.
>>>> */
>>>> +		if ((link->link_enc->connector.id ==
>>>> CONNECTOR_ID_DUAL_LINK_DVII ||
>>>> +		     link->link_enc->connector.id ==
>>>> CONNECTOR_ID_SINGLE_LINK_DVII) &&
>>>> +			sink->edid_caps.analog)
>>>> +			sink->sink_signal = SIGNAL_TYPE_RGB;
>>>> +
>>>>  		/* HDMI-DVI Dongle */
>>>>  		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A
>>>> &&
>>>>  		    !sink->edid_caps.edid_hdmi)
>>>> @@ -1228,6 +1242,64 @@ static bool
>>>> detect_link_and_local_sink(struct dc_link *link,
>>>>  	return true;
>>>>  }
>>>>  
>>>> +/**
>>>> + * Evaluates whether an EDID header is acceptable,
>>>> + * for the purpose of determining a connection with a display.
>>>> + */
>>>> +static bool link_detect_evaluate_edid_header(uint8_t
>>>> edid_header[8])
>>>> +{
>>>> +	int edid_header_score = 0;
>>>> +	int i;
>>>> +
>>>> +	for (i = 0; i < 8; ++i)
>>>> +		edid_header_score += edid_header[i] == ((i == 0
>>>> || i == 7) ? 0x00 : 0xff);
>>>> +
>>>> +	return edid_header_score >= 6;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Tries to detect a connected display by probing the DDC
>>>> + * and reading the EDID header.
>>>> + * The probing is considered successful if we receive a
>>>> + * reply from the DDC over I2C and the EDID header matches.
>>>> + */
>>>> +static bool link_detect_ddc_probe(struct dc_link *link)
>>>> +{
>>>> +	if (!link->ddc)
>>>> +		return false;
>>>> +
>>>> +	uint8_t edid_header[8] = {0};
>>>> +	bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header,
>>>> sizeof(edid_header));
>>>> +
>>>> +	if (!ddc_probed)
>>>> +		return false;
>>>> +
>>>> +	if (!link_detect_evaluate_edid_header(edid_header))
>>>> +		return false;
>>>> +
>>>> +	return true;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Determines if there is an analog sink connected.
>>>> + */
>>>> +static bool link_detect_analog(struct dc_link *link, enum
>>>> dc_connection_type *type)
>>>> +{
>>>> +	/* Don't care about connectors that don't support an
>>>> analog signal. */
>>>> +	if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
>>>> +		link->link_enc->connector.id !=
>>>> CONNECTOR_ID_SINGLE_LINK_DVII &&
>>>> +		link->link_enc->connector.id !=
>>>> CONNECTOR_ID_DUAL_LINK_DVII)
>>>> +		return false;
>>>> +
>>>> +	if (link_detect_ddc_probe(link)) {
>>>> +		*type = dc_connection_single;
>>>> +		return true;
>>>> +	}
>>>> +
>>>> +	*type = dc_connection_none;
>>>> +	return true;
>>>> +}
>>>> +
>>>>  /*
>>>>   * link_detect_connection_type() - Determine if there is a sink
>>>> connected
>>>>   *
>>>> @@ -1238,6 +1310,7 @@ static bool
>>>> detect_link_and_local_sink(struct dc_link *link,
>>>>  bool link_detect_connection_type(struct dc_link *link, enum
>>>> dc_connection_type *type)
>>>>  {
>>>>  	uint32_t is_hpd_high = 0;
>>>> +	bool supports_hpd = link->irq_source_hpd !=
>>>> DC_IRQ_SOURCE_INVALID;
>>>>  
>>>>  	if (link->connector_signal == SIGNAL_TYPE_LVDS) {
>>>>  		*type = dc_connection_single;
>>>> @@ -1261,6 +1334,8 @@ bool link_detect_connection_type(struct
>>>> dc_link *link, enum dc_connection_type *
>>>>  		return true;
>>>>  	}
>>>>  
>>>> +	if (!supports_hpd)
>>>> +		return link_detect_analog(link, type);
>>>>  
>>>>  	if (!query_hpd_status(link, &is_hpd_high))
>>>>  		goto hpd_gpio_failure;
>>>> @@ -1269,6 +1344,9 @@ bool link_detect_connection_type(struct
>>>> dc_link *link, enum dc_connection_type *
>>>>  		*type = dc_connection_single;
>>>>  		/* TODO: need to do the actual detection */
>>>>  	} else {
>>>> +		if (link_detect_analog(link, type))
>>>> +			return true;
>>>> +
>>>>  		*type = dc_connection_none;
>>>>  		if (link->connector_signal == SIGNAL_TYPE_EDP) {
>>>>  			/* eDP is not connected, power down it
>>>> */
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>>>> b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>>>> index d6b7347c6c11..ac25d89a4148 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>>>> @@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
>>>>  		enable_link_lvds(pipe_ctx);
>>>>  		status = DC_OK;
>>>>  		break;
>>>> +	case SIGNAL_TYPE_RGB:
>>>> +		status = DC_OK;
>>>> +		break;
>>>>  	case SIGNAL_TYPE_VIRTUAL:
>>>>  		status = enable_link_virtual(pipe_ctx);
>>>>  		break;
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>>>> b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>>>> index 71c10a1261b9..c9725fd316f6 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>>>> @@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link
>>>> *link,
>>>>  	case CONNECTOR_ID_DUAL_LINK_DVII:
>>>>  		link->connector_signal =
>>>> SIGNAL_TYPE_DVI_DUAL_LINK;
>>>>  		break;
>>>> +	case CONNECTOR_ID_VGA:
>>>> +		link->connector_signal = SIGNAL_TYPE_RGB;
>>>> +		break;
>>>>  	case CONNECTOR_ID_DISPLAY_PORT:
>>>>  	case CONNECTOR_ID_MXM:
>>>>  	case CONNECTOR_ID_USBC:
>>>


^ permalink raw reply	[flat|nested] 61+ messages in thread

* RE: [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-08-08 14:03         ` Harry Wentland
@ 2025-08-08 14:22           ` Wheeler, Daniel
  2025-08-09 20:17             ` Timur Kristóf
  2025-08-20 12:01             ` Timur Kristóf
  0 siblings, 2 replies; 61+ messages in thread
From: Wheeler, Daniel @ 2025-08-08 14:22 UTC (permalink / raw)
  To: Wentland, Harry, Timur Kristóf,
	amd-gfx@lists.freedesktop.org

[AMD Official Use Only - AMD Internal Distribution Only]

The NULL pointer happens right after this error -> "[   10.046542] amdgpu 0000:c4:00.0: amdgpu: [drm] *ERROR* KMS: Failed to detect connector" and only happens with this error. When bisecting the patchset I was getting just the error without the NULL pointer, and after removing "drm/amd/display: Add analog link detection" there was no NULL pointer or error. Probably just need to solve that error and it'd be good to go.


It looks like it's an APU issue as I was able to reproduce this on a system with an AMD Radeon 8060S and eDP or DP, and yes, the NULL pointer happens at driver load.

Thank you,

Dan Wheeler
Sr. Technologist | AMD
SW Display
------------------------------------------------------------------------------------------------------------------
1 Commerce Valley Dr E, Thornhill, ON L3T 7X6
amd.com


-----Original Message-----
From: Wentland, Harry <Harry.Wentland@amd.com>
Sent: Friday, August 8, 2025 10:03 AM
To: Timur Kristóf <timur.kristof@gmail.com>; amd-gfx@lists.freedesktop.org; Wheeler, Daniel <Daniel.Wheeler@amd.com>
Subject: Re: [PATCH 13/20] drm/amd/display: Add analog link detection



On 2025-08-07 17:32, Timur Kristóf wrote:
> On Thu, 2025-08-07 at 16:34 -0400, Harry Wentland wrote:
>>
>>
>> On 2025-08-07 15:12, Harry Wentland wrote:
>>> On 2025-07-23 11:58, Timur Kristóf wrote:
>>>> Analog displays typically have a DDC connection which can be used
>>>> by the GPU to read EDID. This commit adds the capability to probe
>>>> analog displays using DDC, reading the EDID header and deciding
>>>> whether the analog link is connected based on the data that was
>>>> read.
>>>>
>>>> As a reference, I used the following functions:
>>>> amdgpu_connector_vga_detect
>>>> amdgpu_display_ddc_probe
>>>>
>>>> DAC load detection will be implemented in a separate commit.
>>>
>>> Another regression in our internal testing with this patch,
>>> unfortunately only on not-yet released HW.
>>>
>>
>> While this shows on unreleased HW I wouldn't be surprised if it
>> repros on other (recent-ish) APUs (integrated GPUs). It's just
>> that this week's test was on currently unreleased HW.
>>
>> Harry
>>
>>> I wonder if pipe-ctx->stream could be NULL in some cases.
>>>
>>> Harry
>>>
>
> Hi Harry,
>
> Can you elaborate when / how it is valid for pipe->ctx->stream to be
> NULL when the code gets here? Maybe that would give me a hint how to
> resolve it.
>

I don't know. It was just a guess.

I should've mentioned... the NULL pointer access happens on driver
load.

Dan might have more info.

Harry

> Thanks,
> Timur
>
>
>>>>
>>>> Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
>>>> ---
>>>>  .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
>>>>  .../drm/amd/display/dc/link/link_detection.c  | 80
>>>> ++++++++++++++++++-
>>>>  .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
>>>>  .../drm/amd/display/dc/link/link_factory.c    |  3 +
>>>>  4 files changed, 95 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git
>>>> a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>>>> b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>>>> index f3470716734d..b9ebb992dc98 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
>>>> @@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct pipe_ctx
>>>> *pipe_ctx)
>>>>            return;
>>>>    }
>>>>
>>>> -  link_enc->funcs->connect_dig_be_to_fe(link_enc,
>>>> -                  pipe_ctx->stream_res.stream_enc->id,
>>>> true);
>>>> +  if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
>>>> +          link_enc->funcs->connect_dig_be_to_fe(link_enc,
>>>> +                          pipe_ctx->stream_res.stream_enc-
>>>>> id, true);
>>>>    if (dc_is_dp_signal(pipe_ctx->stream->signal))
>>>>            pipe_ctx->stream->ctx->dc->link_srv-
>>>>> dp_trace_source_sequence(pipe_ctx->stream->link,
>>>>                            DPCD_SOURCE_SEQ_AFTER_CONNECT_DI
>>>> G_FE_BE);
>>>> @@ -98,10 +99,13 @@ void reset_dio_stream_encoder(struct pipe_ctx
>>>> *pipe_ctx)
>>>>    if (stream_enc->funcs->enable_stream)
>>>>            stream_enc->funcs->enable_stream(stream_enc,
>>>>                            pipe_ctx->stream->signal,
>>>> false);
>>>> -  link_enc->funcs->connect_dig_be_to_fe(
>>>> -                  link_enc,
>>>> -                  pipe_ctx->stream_res.stream_enc->id,
>>>> -                  false);
>>>> +
>>>> +  if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
>>>> +          link_enc->funcs->connect_dig_be_to_fe(
>>>> +                          link_enc,
>>>> +                          pipe_ctx->stream_res.stream_enc-
>>>>> id,
>>>> +                          false);
>>>> +
>>>>    if (dc_is_dp_signal(pipe_ctx->stream->signal))
>>>>            pipe_ctx->stream->ctx->dc->link_srv-
>>>>> dp_trace_source_sequence(
>>>>                            pipe_ctx->stream->link,
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>>>> b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>>>> index 827b630daf49..fcabc83464af 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
>>>> @@ -942,6 +942,12 @@ static bool
>>>> detect_link_and_local_sink(struct dc_link *link,
>>>>                    break;
>>>>            }
>>>>
>>>> +          case SIGNAL_TYPE_RGB: {
>>>> +                  sink_caps.transaction_type =
>>>> DDC_TRANSACTION_TYPE_I2C;
>>>> +                  sink_caps.signal = SIGNAL_TYPE_RGB;
>>>> +                  break;
>>>> +          }
>>>> +
>>>>            case SIGNAL_TYPE_LVDS: {
>>>>                    sink_caps.transaction_type =
>>>> DDC_TRANSACTION_TYPE_I2C;
>>>>                    sink_caps.signal = SIGNAL_TYPE_LVDS;
>>>> @@ -1133,9 +1139,17 @@ static bool
>>>> detect_link_and_local_sink(struct dc_link *link,
>>>>                            sink = prev_sink;
>>>>                            prev_sink = NULL;
>>>>                    }
>>>> -                  query_hdcp_capability(sink->sink_signal,
>>>> link);
>>>> +
>>>> +                  if (!sink->edid_caps.analog)
>>>> +                          query_hdcp_capability(sink-
>>>>> sink_signal, link);
>>>>            }
>>>>
>>>> +          /* DVI-I connector connected to analog display.
>>>> */
>>>> +          if ((link->link_enc->connector.id ==
>>>> CONNECTOR_ID_DUAL_LINK_DVII ||
>>>> +               link->link_enc->connector.id ==
>>>> CONNECTOR_ID_SINGLE_LINK_DVII) &&
>>>> +                  sink->edid_caps.analog)
>>>> +                  sink->sink_signal = SIGNAL_TYPE_RGB;
>>>> +
>>>>            /* HDMI-DVI Dongle */
>>>>            if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A
>>>> &&
>>>>                !sink->edid_caps.edid_hdmi)
>>>> @@ -1228,6 +1242,64 @@ static bool
>>>> detect_link_and_local_sink(struct dc_link *link,
>>>>    return true;
>>>>  }
>>>>
>>>> +/**
>>>> + * Evaluates whether an EDID header is acceptable,
>>>> + * for the purpose of determining a connection with a display.
>>>> + */
>>>> +static bool link_detect_evaluate_edid_header(uint8_t
>>>> edid_header[8])
>>>> +{
>>>> +  int edid_header_score = 0;
>>>> +  int i;
>>>> +
>>>> +  for (i = 0; i < 8; ++i)
>>>> +          edid_header_score += edid_header[i] == ((i == 0
>>>> || i == 7) ? 0x00 : 0xff);
>>>> +
>>>> +  return edid_header_score >= 6;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Tries to detect a connected display by probing the DDC
>>>> + * and reading the EDID header.
>>>> + * The probing is considered successful if we receive a
>>>> + * reply from the DDC over I2C and the EDID header matches.
>>>> + */
>>>> +static bool link_detect_ddc_probe(struct dc_link *link)
>>>> +{
>>>> +  if (!link->ddc)
>>>> +          return false;
>>>> +
>>>> +  uint8_t edid_header[8] = {0};
>>>> +  bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header,
>>>> sizeof(edid_header));
>>>> +
>>>> +  if (!ddc_probed)
>>>> +          return false;
>>>> +
>>>> +  if (!link_detect_evaluate_edid_header(edid_header))
>>>> +          return false;
>>>> +
>>>> +  return true;
>>>> +}
>>>> +
>>>> +/**
>>>> + * Determines if there is an analog sink connected.
>>>> + */
>>>> +static bool link_detect_analog(struct dc_link *link, enum
>>>> dc_connection_type *type)
>>>> +{
>>>> +  /* Don't care about connectors that don't support an
>>>> analog signal. */
>>>> +  if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
>>>> +          link->link_enc->connector.id !=
>>>> CONNECTOR_ID_SINGLE_LINK_DVII &&
>>>> +          link->link_enc->connector.id !=
>>>> CONNECTOR_ID_DUAL_LINK_DVII)
>>>> +          return false;
>>>> +
>>>> +  if (link_detect_ddc_probe(link)) {
>>>> +          *type = dc_connection_single;
>>>> +          return true;
>>>> +  }
>>>> +
>>>> +  *type = dc_connection_none;
>>>> +  return true;
>>>> +}
>>>> +
>>>>  /*
>>>>   * link_detect_connection_type() - Determine if there is a sink
>>>> connected
>>>>   *
>>>> @@ -1238,6 +1310,7 @@ static bool
>>>> detect_link_and_local_sink(struct dc_link *link,
>>>>  bool link_detect_connection_type(struct dc_link *link, enum
>>>> dc_connection_type *type)
>>>>  {
>>>>    uint32_t is_hpd_high = 0;
>>>> +  bool supports_hpd = link->irq_source_hpd !=
>>>> DC_IRQ_SOURCE_INVALID;
>>>>
>>>>    if (link->connector_signal == SIGNAL_TYPE_LVDS) {
>>>>            *type = dc_connection_single;
>>>> @@ -1261,6 +1334,8 @@ bool link_detect_connection_type(struct
>>>> dc_link *link, enum dc_connection_type *
>>>>            return true;
>>>>    }
>>>>
>>>> +  if (!supports_hpd)
>>>> +          return link_detect_analog(link, type);
>>>>
>>>>    if (!query_hpd_status(link, &is_hpd_high))
>>>>            goto hpd_gpio_failure;
>>>> @@ -1269,6 +1344,9 @@ bool link_detect_connection_type(struct
>>>> dc_link *link, enum dc_connection_type *
>>>>            *type = dc_connection_single;
>>>>            /* TODO: need to do the actual detection */
>>>>    } else {
>>>> +          if (link_detect_analog(link, type))
>>>> +                  return true;
>>>> +
>>>>            *type = dc_connection_none;
>>>>            if (link->connector_signal == SIGNAL_TYPE_EDP) {
>>>>                    /* eDP is not connected, power down it
>>>> */
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>>>> b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>>>> index d6b7347c6c11..ac25d89a4148 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
>>>> @@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
>>>>            enable_link_lvds(pipe_ctx);
>>>>            status = DC_OK;
>>>>            break;
>>>> +  case SIGNAL_TYPE_RGB:
>>>> +          status = DC_OK;
>>>> +          break;
>>>>    case SIGNAL_TYPE_VIRTUAL:
>>>>            status = enable_link_virtual(pipe_ctx);
>>>>            break;
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>>>> b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>>>> index 71c10a1261b9..c9725fd316f6 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
>>>> @@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link
>>>> *link,
>>>>    case CONNECTOR_ID_DUAL_LINK_DVII:
>>>>            link->connector_signal =
>>>> SIGNAL_TYPE_DVI_DUAL_LINK;
>>>>            break;
>>>> +  case CONNECTOR_ID_VGA:
>>>> +          link->connector_signal = SIGNAL_TYPE_RGB;
>>>> +          break;
>>>>    case CONNECTOR_ID_DISPLAY_PORT:
>>>>    case CONNECTOR_ID_MXM:
>>>>    case CONNECTOR_ID_USBC:
>>>


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-08-08 14:22           ` Wheeler, Daniel
@ 2025-08-09 20:17             ` Timur Kristóf
  2025-08-15 14:28               ` Wheeler, Daniel
  2025-08-20 12:01             ` Timur Kristóf
  1 sibling, 1 reply; 61+ messages in thread
From: Timur Kristóf @ 2025-08-09 20:17 UTC (permalink / raw)
  To: Wheeler, Daniel, Wentland, Harry, amd-gfx@lists.freedesktop.org

On Fri, 2025-08-08 at 14:22 +0000, Wheeler, Daniel wrote:
> [AMD Official Use Only - AMD Internal Distribution Only]
> 
> The NULL pointer happens right after this error -> "[   10.046542]
> amdgpu 0000:c4:00.0: amdgpu: [drm] *ERROR* KMS: Failed to detect
> connector" and only happens with this error. When bisecting the
> patchset I was getting just the error without the NULL pointer, and
> after removing "drm/amd/display: Add analog link detection" there was
> no NULL pointer or error. Probably just need to solve that error and
> it'd be good to go.
> 
> 
> It looks like it's an APU issue as I was able to reproduce this on a
> system with an AMD Radeon 8060S and eDP or DP, and yes, the NULL
> pointer happens at driver load.
> 
> Thank you,
> 
> Dan Wheeler
> Sr. Technologist | AMD
> SW Display

Hi Daniel,

Thanks for the reply. I appreciate the testing. I'll investigate this
and try to fix it in the second version of the series. Do you think it
could be reproducible on a Rembrandt APU? Or did you already test that?

Upon looking at the patch again, I find it unlikely that pipe_ctx-
>stream would be NULL, since the same was already accessed by other
branches in the same function. My current best guess is that maybe
link->link_enc would be NULL in the link_detect_analog function.

In the meantime, can I ask you guys to also take a look at my other
series with DCE 6 related fixes?

Thanks,
Timur


> ---------------------------------------------------------------------
> ---------------------------------------------
> 1 Commerce Valley Dr E, Thornhill, ON L3T 7X6
> amd.com
> 
> 
> -----Original Message-----
> From: Wentland, Harry <Harry.Wentland@amd.com>
> Sent: Friday, August 8, 2025 10:03 AM
> To: Timur Kristóf <timur.kristof@gmail.com>;
> amd-gfx@lists.freedesktop.org; Wheeler, Daniel
> <Daniel.Wheeler@amd.com>
> Subject: Re: [PATCH 13/20] drm/amd/display: Add analog link detection
> 
> 
> 
> On 2025-08-07 17:32, Timur Kristóf wrote:
> > On Thu, 2025-08-07 at 16:34 -0400, Harry Wentland wrote:
> > > 
> > > 
> > > On 2025-08-07 15:12, Harry Wentland wrote:
> > > > On 2025-07-23 11:58, Timur Kristóf wrote:
> > > > > Analog displays typically have a DDC connection which can be
> > > > > used
> > > > > by the GPU to read EDID. This commit adds the capability to
> > > > > probe
> > > > > analog displays using DDC, reading the EDID header and
> > > > > deciding
> > > > > whether the analog link is connected based on the data that
> > > > > was
> > > > > read.
> > > > > 
> > > > > As a reference, I used the following functions:
> > > > > amdgpu_connector_vga_detect
> > > > > amdgpu_display_ddc_probe
> > > > > 
> > > > > DAC load detection will be implemented in a separate commit.
> > > > 
> > > > Another regression in our internal testing with this patch,
> > > > unfortunately only on not-yet released HW.
> > > > 
> > > 
> > > While this shows on unreleased HW I wouldn't be surprised if it
> > > repros on other (recent-ish) APUs (integrated GPUs). It's just
> > > that this week's test was on currently unreleased HW.
> > > 
> > > Harry
> > > 
> > > > I wonder if pipe-ctx->stream could be NULL in some cases.
> > > > 
> > > > Harry
> > > > 
> > 
> > Hi Harry,
> > 
> > Can you elaborate when / how it is valid for pipe->ctx->stream to
> > be
> > NULL when the code gets here? Maybe that would give me a hint how
> > to
> > resolve it.
> > 
> 
> I don't know. It was just a guess.
> 
> I should've mentioned... the NULL pointer access happens on driver
> load.
> 
> Dan might have more info.
> 
> Harry
> 
> > Thanks,
> > Timur
> > 
> > 
> > > > > 
> > > > > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > > > > ---
> > > > >  .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
> > > > >  .../drm/amd/display/dc/link/link_detection.c  | 80
> > > > > ++++++++++++++++++-
> > > > >  .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
> > > > >  .../drm/amd/display/dc/link/link_factory.c    |  3 +
> > > > >  4 files changed, 95 insertions(+), 7 deletions(-)
> > > > > 
> > > > > diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > index f3470716734d..b9ebb992dc98 100644
> > > > > ---
> > > > > a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > +++
> > > > > b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > @@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct
> > > > > pipe_ctx
> > > > > *pipe_ctx)
> > > > >            return;
> > > > >    }
> > > > > 
> > > > > -  link_enc->funcs->connect_dig_be_to_fe(link_enc,
> > > > > -                  pipe_ctx->stream_res.stream_enc->id,
> > > > > true);
> > > > > +  if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > > > > +          link_enc->funcs->connect_dig_be_to_fe(link_enc,
> > > > > +                          pipe_ctx->stream_res.stream_enc-
> > > > > > id, true);
> > > > >    if (dc_is_dp_signal(pipe_ctx->stream->signal))
> > > > >            pipe_ctx->stream->ctx->dc->link_srv-
> > > > > > dp_trace_source_sequence(pipe_ctx->stream->link,
> > > > >                            DPCD_SOURCE_SEQ_AFTER_CONNECT_DI
> > > > > G_FE_BE);
> > > > > @@ -98,10 +99,13 @@ void reset_dio_stream_encoder(struct
> > > > > pipe_ctx
> > > > > *pipe_ctx)
> > > > >    if (stream_enc->funcs->enable_stream)
> > > > >            stream_enc->funcs->enable_stream(stream_enc,
> > > > >                            pipe_ctx->stream->signal,
> > > > > false);
> > > > > -  link_enc->funcs->connect_dig_be_to_fe(
> > > > > -                  link_enc,
> > > > > -                  pipe_ctx->stream_res.stream_enc->id,
> > > > > -                  false);
> > > > > +
> > > > > +  if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > > > > +          link_enc->funcs->connect_dig_be_to_fe(
> > > > > +                          link_enc,
> > > > > +                          pipe_ctx->stream_res.stream_enc-
> > > > > > id,
> > > > > +                          false);
> > > > > +
> > > > >    if (dc_is_dp_signal(pipe_ctx->stream->signal))
> > > > >            pipe_ctx->stream->ctx->dc->link_srv-
> > > > > > dp_trace_source_sequence(
> > > > >                            pipe_ctx->stream->link,
> > > > > diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > index 827b630daf49..fcabc83464af 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > @@ -942,6 +942,12 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >                    break;
> > > > >            }
> > > > > 
> > > > > +          case SIGNAL_TYPE_RGB: {
> > > > > +                  sink_caps.transaction_type =
> > > > > DDC_TRANSACTION_TYPE_I2C;
> > > > > +                  sink_caps.signal = SIGNAL_TYPE_RGB;
> > > > > +                  break;
> > > > > +          }
> > > > > +
> > > > >            case SIGNAL_TYPE_LVDS: {
> > > > >                    sink_caps.transaction_type =
> > > > > DDC_TRANSACTION_TYPE_I2C;
> > > > >                    sink_caps.signal = SIGNAL_TYPE_LVDS;
> > > > > @@ -1133,9 +1139,17 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >                            sink = prev_sink;
> > > > >                            prev_sink = NULL;
> > > > >                    }
> > > > > -                  query_hdcp_capability(sink->sink_signal,
> > > > > link);
> > > > > +
> > > > > +                  if (!sink->edid_caps.analog)
> > > > > +                          query_hdcp_capability(sink-
> > > > > > sink_signal, link);
> > > > >            }
> > > > > 
> > > > > +          /* DVI-I connector connected to analog display.
> > > > > */
> > > > > +          if ((link->link_enc->connector.id ==
> > > > > CONNECTOR_ID_DUAL_LINK_DVII ||
> > > > > +               link->link_enc->connector.id ==
> > > > > CONNECTOR_ID_SINGLE_LINK_DVII) &&
> > > > > +                  sink->edid_caps.analog)
> > > > > +                  sink->sink_signal = SIGNAL_TYPE_RGB;
> > > > > +
> > > > >            /* HDMI-DVI Dongle */
> > > > >            if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A
> > > > > &&
> > > > >                !sink->edid_caps.edid_hdmi)
> > > > > @@ -1228,6 +1242,64 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >    return true;
> > > > >  }
> > > > > 
> > > > > +/**
> > > > > + * Evaluates whether an EDID header is acceptable,
> > > > > + * for the purpose of determining a connection with a
> > > > > display.
> > > > > + */
> > > > > +static bool link_detect_evaluate_edid_header(uint8_t
> > > > > edid_header[8])
> > > > > +{
> > > > > +  int edid_header_score = 0;
> > > > > +  int i;
> > > > > +
> > > > > +  for (i = 0; i < 8; ++i)
> > > > > +          edid_header_score += edid_header[i] == ((i == 0
> > > > > > > i == 7) ? 0x00 : 0xff);
> > > > > +
> > > > > +  return edid_header_score >= 6;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * Tries to detect a connected display by probing the DDC
> > > > > + * and reading the EDID header.
> > > > > + * The probing is considered successful if we receive a
> > > > > + * reply from the DDC over I2C and the EDID header matches.
> > > > > + */
> > > > > +static bool link_detect_ddc_probe(struct dc_link *link)
> > > > > +{
> > > > > +  if (!link->ddc)
> > > > > +          return false;
> > > > > +
> > > > > +  uint8_t edid_header[8] = {0};
> > > > > +  bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header,
> > > > > sizeof(edid_header));
> > > > > +
> > > > > +  if (!ddc_probed)
> > > > > +          return false;
> > > > > +
> > > > > +  if (!link_detect_evaluate_edid_header(edid_header))
> > > > > +          return false;
> > > > > +
> > > > > +  return true;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * Determines if there is an analog sink connected.
> > > > > + */
> > > > > +static bool link_detect_analog(struct dc_link *link, enum
> > > > > dc_connection_type *type)
> > > > > +{
> > > > > +  /* Don't care about connectors that don't support an
> > > > > analog signal. */
> > > > > +  if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
> > > > > +          link->link_enc->connector.id !=
> > > > > CONNECTOR_ID_SINGLE_LINK_DVII &&
> > > > > +          link->link_enc->connector.id !=
> > > > > CONNECTOR_ID_DUAL_LINK_DVII)
> > > > > +          return false;
> > > > > +
> > > > > +  if (link_detect_ddc_probe(link)) {
> > > > > +          *type = dc_connection_single;
> > > > > +          return true;
> > > > > +  }
> > > > > +
> > > > > +  *type = dc_connection_none;
> > > > > +  return true;
> > > > > +}
> > > > > +
> > > > >  /*
> > > > >   * link_detect_connection_type() - Determine if there is a
> > > > > sink
> > > > > connected
> > > > >   *
> > > > > @@ -1238,6 +1310,7 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >  bool link_detect_connection_type(struct dc_link *link, enum
> > > > > dc_connection_type *type)
> > > > >  {
> > > > >    uint32_t is_hpd_high = 0;
> > > > > +  bool supports_hpd = link->irq_source_hpd !=
> > > > > DC_IRQ_SOURCE_INVALID;
> > > > > 
> > > > >    if (link->connector_signal == SIGNAL_TYPE_LVDS) {
> > > > >            *type = dc_connection_single;
> > > > > @@ -1261,6 +1334,8 @@ bool link_detect_connection_type(struct
> > > > > dc_link *link, enum dc_connection_type *
> > > > >            return true;
> > > > >    }
> > > > > 
> > > > > +  if (!supports_hpd)
> > > > > +          return link_detect_analog(link, type);
> > > > > 
> > > > >    if (!query_hpd_status(link, &is_hpd_high))
> > > > >            goto hpd_gpio_failure;
> > > > > @@ -1269,6 +1344,9 @@ bool link_detect_connection_type(struct
> > > > > dc_link *link, enum dc_connection_type *
> > > > >            *type = dc_connection_single;
> > > > >            /* TODO: need to do the actual detection */
> > > > >    } else {
> > > > > +          if (link_detect_analog(link, type))
> > > > > +                  return true;
> > > > > +
> > > > >            *type = dc_connection_none;
> > > > >            if (link->connector_signal == SIGNAL_TYPE_EDP) {
> > > > >                    /* eDP is not connected, power down it
> > > > > */
> > > > > diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > index d6b7347c6c11..ac25d89a4148 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > @@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
> > > > >            enable_link_lvds(pipe_ctx);
> > > > >            status = DC_OK;
> > > > >            break;
> > > > > +  case SIGNAL_TYPE_RGB:
> > > > > +          status = DC_OK;
> > > > > +          break;
> > > > >    case SIGNAL_TYPE_VIRTUAL:
> > > > >            status = enable_link_virtual(pipe_ctx);
> > > > >            break;
> > > > > diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > index 71c10a1261b9..c9725fd316f6 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > @@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link
> > > > > *link,
> > > > >    case CONNECTOR_ID_DUAL_LINK_DVII:
> > > > >            link->connector_signal =
> > > > > SIGNAL_TYPE_DVI_DUAL_LINK;
> > > > >            break;
> > > > > +  case CONNECTOR_ID_VGA:
> > > > > +          link->connector_signal = SIGNAL_TYPE_RGB;
> > > > > +          break;
> > > > >    case CONNECTOR_ID_DISPLAY_PORT:
> > > > >    case CONNECTOR_ID_MXM:
> > > > >    case CONNECTOR_ID_USBC:
> > > > 

^ permalink raw reply	[flat|nested] 61+ messages in thread

* RE: [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-08-09 20:17             ` Timur Kristóf
@ 2025-08-15 14:28               ` Wheeler, Daniel
  0 siblings, 0 replies; 61+ messages in thread
From: Wheeler, Daniel @ 2025-08-15 14:28 UTC (permalink / raw)
  To: Timur Kristóf, Wentland, Harry,
	amd-gfx@lists.freedesktop.org

[Public]

Hi Timur,

Sorry for the delay. It took me a bit to find my Rembrandt system. I tried booting up with your patches, and the system hard hangs after kernel load - I can't get into it via ssh. The error message doesn't seem like it would only be contained to one generation, so I wouldn't be surprised if this is the same issue as the newer systems, just presenting a different way.

Thank you,

Dan Wheeler
Sr. Technologist | AMD
SW Display
------------------------------------------------------------------------------------------------------------------
1 Commerce Valley Dr E, Thornhill, ON L3T 7X6
amd.com


-----Original Message-----
From: Timur Kristóf <timur.kristof@gmail.com>
Sent: Saturday, August 9, 2025 4:17 PM
To: Wheeler, Daniel <Daniel.Wheeler@amd.com>; Wentland, Harry <Harry.Wentland@amd.com>; amd-gfx@lists.freedesktop.org
Subject: Re: [PATCH 13/20] drm/amd/display: Add analog link detection

On Fri, 2025-08-08 at 14:22 +0000, Wheeler, Daniel wrote:
> [AMD Official Use Only - AMD Internal Distribution Only]
>
> The NULL pointer happens right after this error -> "[   10.046542]
> amdgpu 0000:c4:00.0: amdgpu: [drm] *ERROR* KMS: Failed to detect
> connector" and only happens with this error. When bisecting the
> patchset I was getting just the error without the NULL pointer, and
> after removing "drm/amd/display: Add analog link detection" there was
> no NULL pointer or error. Probably just need to solve that error and
> it'd be good to go.
>
>
> It looks like it's an APU issue as I was able to reproduce this on a
> system with an AMD Radeon 8060S and eDP or DP, and yes, the NULL
> pointer happens at driver load.
>
> Thank you,
>
> Dan Wheeler
> Sr. Technologist | AMD
> SW Display

Hi Daniel,

Thanks for the reply. I appreciate the testing. I'll investigate this and try to fix it in the second version of the series. Do you think it could be reproducible on a Rembrandt APU? Or did you already test that?

Upon looking at the patch again, I find it unlikely that pipe_ctx-
>stream would be NULL, since the same was already accessed by other
branches in the same function. My current best guess is that maybe
link->link_enc would be NULL in the link_detect_analog function.

In the meantime, can I ask you guys to also take a look at my other series with DCE 6 related fixes?

Thanks,
Timur


> ---------------------------------------------------------------------
> ---------------------------------------------
> 1 Commerce Valley Dr E, Thornhill, ON L3T 7X6 amd.com
>
>
> -----Original Message-----
> From: Wentland, Harry <Harry.Wentland@amd.com>
> Sent: Friday, August 8, 2025 10:03 AM
> To: Timur Kristóf <timur.kristof@gmail.com>;
> amd-gfx@lists.freedesktop.org; Wheeler, Daniel
> <Daniel.Wheeler@amd.com>
> Subject: Re: [PATCH 13/20] drm/amd/display: Add analog link detection
>
>
>
> On 2025-08-07 17:32, Timur Kristóf wrote:
> > On Thu, 2025-08-07 at 16:34 -0400, Harry Wentland wrote:
> > >
> > >
> > > On 2025-08-07 15:12, Harry Wentland wrote:
> > > > On 2025-07-23 11:58, Timur Kristóf wrote:
> > > > > Analog displays typically have a DDC connection which can be
> > > > > used by the GPU to read EDID. This commit adds the capability
> > > > > to probe analog displays using DDC, reading the EDID header
> > > > > and deciding whether the analog link is connected based on the
> > > > > data that was read.
> > > > >
> > > > > As a reference, I used the following functions:
> > > > > amdgpu_connector_vga_detect
> > > > > amdgpu_display_ddc_probe
> > > > >
> > > > > DAC load detection will be implemented in a separate commit.
> > > >
> > > > Another regression in our internal testing with this patch,
> > > > unfortunately only on not-yet released HW.
> > > >
> > >
> > > While this shows on unreleased HW I wouldn't be surprised if it
> > > repros on other (recent-ish) APUs (integrated GPUs). It's just
> > > that this week's test was on currently unreleased HW.
> > >
> > > Harry
> > >
> > > > I wonder if pipe-ctx->stream could be NULL in some cases.
> > > >
> > > > Harry
> > > >
> >
> > Hi Harry,
> >
> > Can you elaborate when / how it is valid for pipe->ctx->stream to be
> > NULL when the code gets here? Maybe that would give me a hint how to
> > resolve it.
> >
>
> I don't know. It was just a guess.
>
> I should've mentioned... the NULL pointer access happens on driver
> load.
>
> Dan might have more info.
>
> Harry
>
> > Thanks,
> > Timur
> >
> >
> > > > >
> > > > > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > > > > ---
> > > > >  .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
> > > > >  .../drm/amd/display/dc/link/link_detection.c  | 80
> > > > > ++++++++++++++++++-
> > > > >  .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
> > > > >  .../drm/amd/display/dc/link/link_factory.c    |  3 +
> > > > >  4 files changed, 95 insertions(+), 7 deletions(-)
> > > > >
> > > > > diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > index f3470716734d..b9ebb992dc98 100644
> > > > > ---
> > > > > a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > +++
> > > > > b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > @@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct
> > > > > pipe_ctx
> > > > > *pipe_ctx)
> > > > >            return;
> > > > >    }
> > > > >
> > > > > -  link_enc->funcs->connect_dig_be_to_fe(link_enc,
> > > > > -                  pipe_ctx->stream_res.stream_enc->id,
> > > > > true);
> > > > > +  if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > > > > +          link_enc->funcs->connect_dig_be_to_fe(link_enc,
> > > > > +                          pipe_ctx->stream_res.stream_enc-
> > > > > > id, true);
> > > > >    if (dc_is_dp_signal(pipe_ctx->stream->signal))
> > > > >            pipe_ctx->stream->ctx->dc->link_srv-
> > > > > > dp_trace_source_sequence(pipe_ctx->stream->link,
> > > > >                            DPCD_SOURCE_SEQ_AFTER_CONNECT_DI
> > > > > G_FE_BE); @@ -98,10 +99,13 @@ void
> > > > > reset_dio_stream_encoder(struct pipe_ctx
> > > > > *pipe_ctx)
> > > > >    if (stream_enc->funcs->enable_stream)
> > > > >            stream_enc->funcs->enable_stream(stream_enc,
> > > > >                            pipe_ctx->stream->signal, false);
> > > > > -  link_enc->funcs->connect_dig_be_to_fe(
> > > > > -                  link_enc,
> > > > > -                  pipe_ctx->stream_res.stream_enc->id,
> > > > > -                  false);
> > > > > +
> > > > > +  if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > > > > +          link_enc->funcs->connect_dig_be_to_fe(
> > > > > +                          link_enc,
> > > > > +                          pipe_ctx->stream_res.stream_enc-
> > > > > > id,
> > > > > +                          false);
> > > > > +
> > > > >    if (dc_is_dp_signal(pipe_ctx->stream->signal))
> > > > >            pipe_ctx->stream->ctx->dc->link_srv-
> > > > > > dp_trace_source_sequence(
> > > > >                            pipe_ctx->stream->link, diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > index 827b630daf49..fcabc83464af 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > @@ -942,6 +942,12 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >                    break;
> > > > >            }
> > > > >
> > > > > +          case SIGNAL_TYPE_RGB: {
> > > > > +                  sink_caps.transaction_type =
> > > > > DDC_TRANSACTION_TYPE_I2C;
> > > > > +                  sink_caps.signal = SIGNAL_TYPE_RGB;
> > > > > +                  break;
> > > > > +          }
> > > > > +
> > > > >            case SIGNAL_TYPE_LVDS: {
> > > > >                    sink_caps.transaction_type =
> > > > > DDC_TRANSACTION_TYPE_I2C;
> > > > >                    sink_caps.signal = SIGNAL_TYPE_LVDS; @@
> > > > > -1133,9 +1139,17 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >                            sink = prev_sink;
> > > > >                            prev_sink = NULL;
> > > > >                    }
> > > > > -                  query_hdcp_capability(sink->sink_signal,
> > > > > link);
> > > > > +
> > > > > +                  if (!sink->edid_caps.analog)
> > > > > +                          query_hdcp_capability(sink-
> > > > > > sink_signal, link);
> > > > >            }
> > > > >
> > > > > +          /* DVI-I connector connected to analog display.
> > > > > */
> > > > > +          if ((link->link_enc->connector.id ==
> > > > > CONNECTOR_ID_DUAL_LINK_DVII ||
> > > > > +               link->link_enc->connector.id ==
> > > > > CONNECTOR_ID_SINGLE_LINK_DVII) &&
> > > > > +                  sink->edid_caps.analog)
> > > > > +                  sink->sink_signal = SIGNAL_TYPE_RGB;
> > > > > +
> > > > >            /* HDMI-DVI Dongle */
> > > > >            if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
> > > > >                !sink->edid_caps.edid_hdmi) @@ -1228,6 +1242,64
> > > > > @@ static bool detect_link_and_local_sink(struct dc_link
> > > > > *link,
> > > > >    return true;
> > > > >  }
> > > > >
> > > > > +/**
> > > > > + * Evaluates whether an EDID header is acceptable,
> > > > > + * for the purpose of determining a connection with a
> > > > > display.
> > > > > + */
> > > > > +static bool link_detect_evaluate_edid_header(uint8_t
> > > > > edid_header[8])
> > > > > +{
> > > > > +  int edid_header_score = 0;
> > > > > +  int i;
> > > > > +
> > > > > +  for (i = 0; i < 8; ++i)
> > > > > +          edid_header_score += edid_header[i] == ((i == 0
> > > > > > > i == 7) ? 0x00 : 0xff);
> > > > > +
> > > > > +  return edid_header_score >= 6; }
> > > > > +
> > > > > +/**
> > > > > + * Tries to detect a connected display by probing the DDC
> > > > > + * and reading the EDID header.
> > > > > + * The probing is considered successful if we receive a
> > > > > + * reply from the DDC over I2C and the EDID header matches.
> > > > > + */
> > > > > +static bool link_detect_ddc_probe(struct dc_link *link) {
> > > > > +  if (!link->ddc)
> > > > > +          return false;
> > > > > +
> > > > > +  uint8_t edid_header[8] = {0};
> > > > > +  bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header,
> > > > > sizeof(edid_header));
> > > > > +
> > > > > +  if (!ddc_probed)
> > > > > +          return false;
> > > > > +
> > > > > +  if (!link_detect_evaluate_edid_header(edid_header))
> > > > > +          return false;
> > > > > +
> > > > > +  return true;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * Determines if there is an analog sink connected.
> > > > > + */
> > > > > +static bool link_detect_analog(struct dc_link *link, enum
> > > > > dc_connection_type *type)
> > > > > +{
> > > > > +  /* Don't care about connectors that don't support an
> > > > > analog signal. */
> > > > > +  if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
> > > > > +          link->link_enc->connector.id !=
> > > > > CONNECTOR_ID_SINGLE_LINK_DVII &&
> > > > > +          link->link_enc->connector.id !=
> > > > > CONNECTOR_ID_DUAL_LINK_DVII)
> > > > > +          return false;
> > > > > +
> > > > > +  if (link_detect_ddc_probe(link)) {
> > > > > +          *type = dc_connection_single;
> > > > > +          return true;
> > > > > +  }
> > > > > +
> > > > > +  *type = dc_connection_none;
> > > > > +  return true;
> > > > > +}
> > > > > +
> > > > >  /*
> > > > >   * link_detect_connection_type() - Determine if there is a
> > > > > sink connected
> > > > >   *
> > > > > @@ -1238,6 +1310,7 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >  bool link_detect_connection_type(struct dc_link *link, enum
> > > > > dc_connection_type *type)
> > > > >  {
> > > > >    uint32_t is_hpd_high = 0;
> > > > > +  bool supports_hpd = link->irq_source_hpd !=
> > > > > DC_IRQ_SOURCE_INVALID;
> > > > >
> > > > >    if (link->connector_signal == SIGNAL_TYPE_LVDS) {
> > > > >            *type = dc_connection_single; @@ -1261,6 +1334,8 @@
> > > > > bool link_detect_connection_type(struct
> > > > > dc_link *link, enum dc_connection_type *
> > > > >            return true;
> > > > >    }
> > > > >
> > > > > +  if (!supports_hpd)
> > > > > +          return link_detect_analog(link, type);
> > > > >
> > > > >    if (!query_hpd_status(link, &is_hpd_high))
> > > > >            goto hpd_gpio_failure; @@ -1269,6 +1344,9 @@ bool
> > > > > link_detect_connection_type(struct
> > > > > dc_link *link, enum dc_connection_type *
> > > > >            *type = dc_connection_single;
> > > > >            /* TODO: need to do the actual detection */
> > > > >    } else {
> > > > > +          if (link_detect_analog(link, type))
> > > > > +                  return true;
> > > > > +
> > > > >            *type = dc_connection_none;
> > > > >            if (link->connector_signal == SIGNAL_TYPE_EDP) {
> > > > >                    /* eDP is not connected, power down it */
> > > > > diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > index d6b7347c6c11..ac25d89a4148 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > @@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
> > > > >            enable_link_lvds(pipe_ctx);
> > > > >            status = DC_OK;
> > > > >            break;
> > > > > +  case SIGNAL_TYPE_RGB:
> > > > > +          status = DC_OK;
> > > > > +          break;
> > > > >    case SIGNAL_TYPE_VIRTUAL:
> > > > >            status = enable_link_virtual(pipe_ctx);
> > > > >            break;
> > > > > diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > index 71c10a1261b9..c9725fd316f6 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > @@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link
> > > > > *link,
> > > > >    case CONNECTOR_ID_DUAL_LINK_DVII:
> > > > >            link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
> > > > >            break;
> > > > > +  case CONNECTOR_ID_VGA:
> > > > > +          link->connector_signal = SIGNAL_TYPE_RGB;
> > > > > +          break;
> > > > >    case CONNECTOR_ID_DISPLAY_PORT:
> > > > >    case CONNECTOR_ID_MXM:
> > > > >    case CONNECTOR_ID_USBC:
> > > >

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately
  2025-08-06 18:13       ` Harry Wentland
@ 2025-08-20 11:49         ` Timur Kristóf
  0 siblings, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-08-20 11:49 UTC (permalink / raw)
  To: Harry Wentland; +Cc: amd-gfx list

On Wed, 2025-08-06 at 14:13 -0400, Harry Wentland wrote:
> 
> 
> On 2025-08-06 13:45, Timur Kristóf wrote:
> > 
> > Harry Wentland
> > <harry.wentland@amd.com <mailto:harry.wentland@amd.com>> ezt írta
> > (időpont: 2025. aug. 6., Sze 16:56):
> > 
> >     this patch regresses the kms_bw IGT test with Navi 31 and 48
> >     with a single 4k60 DP display connected. These subtests fail
> >     when they should pass:
> > 
> >     linear-tiling-2-displays-1920x1080p
> >     linear-tiling-2-displays-2160x1440p
> >     linear-tiling-2-displays-2560x1440p
> >     linear-tiling-2-displays-3840x2160p
> >     linear-tiling-3-displays-1920x1080p
> >     linear-tiling-3-displays-2160x1440p
> >     linear-tiling-3-displays-2560x1440p
> >     linear-tiling-3-displays-3840x2160p
> >     linear-tiling-4-displays-1920x1080p
> >     linear-tiling-4-displays-2160x1440p
> >     linear-tiling-4-displays-2560x1440p
> >     linear-tiling-4-displays-3840x2160p
> > 
> >     We confirmed with a revert of this patch.
> > 
> >     Harry
> 
> > At the moment I don't see what is there that would make a
> > difference to Navi 31 or 48.
> > 
> 
> Not sure either. But that's why we have these tests because
> they often catch things that aren't obvious.
> 
> Harry

Hi Harry,

I took a look at this issue.

I found the code for this igt test here:
https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/blob/master/tests/kms_bw.c?ref_type=heads

It seems to me that the test sets up a very simple display scenario and
tries to check that the CRC isn't zero.

However, the variable "igt_crc_t zero" is never initialized (and is
also of the wrong type). So what the test is actually doing is
comparing the "captured" CRC with a piece of uninitialized memory.

That being said, I decided to rewrite my patch and only check the DC
connector type for DVI signals to distinguish between DVI-D and DVI-I
specifically, and otherwise leave the rest of the code as-is in order
to avoid any potential regressions.

Does that sound OK to you?

Thanks & best regards,
Timur


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/20] drm/amd/display: Add analog link detection
  2025-08-08 14:22           ` Wheeler, Daniel
  2025-08-09 20:17             ` Timur Kristóf
@ 2025-08-20 12:01             ` Timur Kristóf
  1 sibling, 0 replies; 61+ messages in thread
From: Timur Kristóf @ 2025-08-20 12:01 UTC (permalink / raw)
  To: Wheeler, Daniel, Wentland, Harry, amd-gfx@lists.freedesktop.org

On Fri, 2025-08-08 at 14:22 +0000, Wheeler, Daniel wrote:
> [AMD Official Use Only - AMD Internal Distribution Only]
> 
> The NULL pointer happens right after this error -> "[   10.046542]
> amdgpu 0000:c4:00.0: amdgpu: [drm] *ERROR* KMS: Failed to detect
> connector" and only happens with this error. When bisecting the
> patchset I was getting just the error without the NULL pointer, and
> after removing "drm/amd/display: Add analog link detection" there was
> no NULL pointer or error. Probably just need to solve that error and
> it'd be good to go.
> 
> 
> It looks like it's an APU issue as I was able to reproduce this on a
> system with an AMD Radeon 8060S and eDP or DP, and yes, the NULL
> pointer happens at driver load.
> 
> Thank you,
> 
> Dan Wheeler
> Sr. Technologist | AMD
> SW Display


Hi Daniel,

I've managed to take a deeper look at this. I think there were actually
two problems in this patch:

1. NULL pointer dereference:

Seems to be caused by the link encoder not being initialized, although
I'm not fully sure how that happens, but I changed the parts that
accessed link_enc, and it no longer crashes now.

2. HPD pin issue:

In link_detect_connection_type() the DC code checks the status of the
HPD pins and returns false when HPD isn't supported. My patch changed
this to take the same code path as if the HPD pins were low. This seems
to have broken something and resulted in a black screen on Rembrandt.

It seems that some other part of the code expects that the link
detection fails when HPD isn't supported. So I fixed this by special
casing VGA connectors to allow link detection just on VGA to succeed
when there are no HPD pins, but left the other code path as-is.

Does that sound reasonable to you?

Thanks & best regards,
Timur



> ---------------------------------------------------------------------
> ---------------------------------------------
> 1 Commerce Valley Dr E, Thornhill, ON L3T 7X6
> amd.com
> 
> 
> -----Original Message-----
> From: Wentland, Harry <Harry.Wentland@amd.com>
> Sent: Friday, August 8, 2025 10:03 AM
> To: Timur Kristóf <timur.kristof@gmail.com>;
> amd-gfx@lists.freedesktop.org; Wheeler, Daniel
> <Daniel.Wheeler@amd.com>
> Subject: Re: [PATCH 13/20] drm/amd/display: Add analog link detection
> 
> 
> 
> On 2025-08-07 17:32, Timur Kristóf wrote:
> > On Thu, 2025-08-07 at 16:34 -0400, Harry Wentland wrote:
> > > 
> > > 
> > > On 2025-08-07 15:12, Harry Wentland wrote:
> > > > On 2025-07-23 11:58, Timur Kristóf wrote:
> > > > > Analog displays typically have a DDC connection which can be
> > > > > used
> > > > > by the GPU to read EDID. This commit adds the capability to
> > > > > probe
> > > > > analog displays using DDC, reading the EDID header and
> > > > > deciding
> > > > > whether the analog link is connected based on the data that
> > > > > was
> > > > > read.
> > > > > 
> > > > > As a reference, I used the following functions:
> > > > > amdgpu_connector_vga_detect
> > > > > amdgpu_display_ddc_probe
> > > > > 
> > > > > DAC load detection will be implemented in a separate commit.
> > > > 
> > > > Another regression in our internal testing with this patch,
> > > > unfortunately only on not-yet released HW.
> > > > 
> > > 
> > > While this shows on unreleased HW I wouldn't be surprised if it
> > > repros on other (recent-ish) APUs (integrated GPUs). It's just
> > > that this week's test was on currently unreleased HW.
> > > 
> > > Harry
> > > 
> > > > I wonder if pipe-ctx->stream could be NULL in some cases.
> > > > 
> > > > Harry
> > > > 
> > 
> > Hi Harry,
> > 
> > Can you elaborate when / how it is valid for pipe->ctx->stream to
> > be
> > NULL when the code gets here? Maybe that would give me a hint how
> > to
> > resolve it.
> > 
> 
> I don't know. It was just a guess.
> 
> I should've mentioned... the NULL pointer access happens on driver
> load.
> 
> Dan might have more info.
> 
> Harry
> 
> > Thanks,
> > Timur
> > 
> > 
> > > > > 
> > > > > Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
> > > > > ---
> > > > >  .../amd/display/dc/link/hwss/link_hwss_dio.c  | 16 ++--
> > > > >  .../drm/amd/display/dc/link/link_detection.c  | 80
> > > > > ++++++++++++++++++-
> > > > >  .../gpu/drm/amd/display/dc/link/link_dpms.c   |  3 +
> > > > >  .../drm/amd/display/dc/link/link_factory.c    |  3 +
> > > > >  4 files changed, 95 insertions(+), 7 deletions(-)
> > > > > 
> > > > > diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > index f3470716734d..b9ebb992dc98 100644
> > > > > ---
> > > > > a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > +++
> > > > > b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
> > > > > @@ -58,8 +58,9 @@ void setup_dio_stream_encoder(struct
> > > > > pipe_ctx
> > > > > *pipe_ctx)
> > > > >            return;
> > > > >    }
> > > > > 
> > > > > -  link_enc->funcs->connect_dig_be_to_fe(link_enc,
> > > > > -                  pipe_ctx->stream_res.stream_enc->id,
> > > > > true);
> > > > > +  if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > > > > +          link_enc->funcs->connect_dig_be_to_fe(link_enc,
> > > > > +                          pipe_ctx->stream_res.stream_enc-
> > > > > > id, true);
> > > > >    if (dc_is_dp_signal(pipe_ctx->stream->signal))
> > > > >            pipe_ctx->stream->ctx->dc->link_srv-
> > > > > > dp_trace_source_sequence(pipe_ctx->stream->link,
> > > > >                            DPCD_SOURCE_SEQ_AFTER_CONNECT_DI
> > > > > G_FE_BE);
> > > > > @@ -98,10 +99,13 @@ void reset_dio_stream_encoder(struct
> > > > > pipe_ctx
> > > > > *pipe_ctx)
> > > > >    if (stream_enc->funcs->enable_stream)
> > > > >            stream_enc->funcs->enable_stream(stream_enc,
> > > > >                            pipe_ctx->stream->signal,
> > > > > false);
> > > > > -  link_enc->funcs->connect_dig_be_to_fe(
> > > > > -                  link_enc,
> > > > > -                  pipe_ctx->stream_res.stream_enc->id,
> > > > > -                  false);
> > > > > +
> > > > > +  if (!dc_is_rgb_signal(pipe_ctx->stream->signal))
> > > > > +          link_enc->funcs->connect_dig_be_to_fe(
> > > > > +                          link_enc,
> > > > > +                          pipe_ctx->stream_res.stream_enc-
> > > > > > id,
> > > > > +                          false);
> > > > > +
> > > > >    if (dc_is_dp_signal(pipe_ctx->stream->signal))
> > > > >            pipe_ctx->stream->ctx->dc->link_srv-
> > > > > > dp_trace_source_sequence(
> > > > >                            pipe_ctx->stream->link,
> > > > > diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > index 827b630daf49..fcabc83464af 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> > > > > @@ -942,6 +942,12 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >                    break;
> > > > >            }
> > > > > 
> > > > > +          case SIGNAL_TYPE_RGB: {
> > > > > +                  sink_caps.transaction_type =
> > > > > DDC_TRANSACTION_TYPE_I2C;
> > > > > +                  sink_caps.signal = SIGNAL_TYPE_RGB;
> > > > > +                  break;
> > > > > +          }
> > > > > +
> > > > >            case SIGNAL_TYPE_LVDS: {
> > > > >                    sink_caps.transaction_type =
> > > > > DDC_TRANSACTION_TYPE_I2C;
> > > > >                    sink_caps.signal = SIGNAL_TYPE_LVDS;
> > > > > @@ -1133,9 +1139,17 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >                            sink = prev_sink;
> > > > >                            prev_sink = NULL;
> > > > >                    }
> > > > > -                  query_hdcp_capability(sink->sink_signal,
> > > > > link);
> > > > > +
> > > > > +                  if (!sink->edid_caps.analog)
> > > > > +                          query_hdcp_capability(sink-
> > > > > > sink_signal, link);
> > > > >            }
> > > > > 
> > > > > +          /* DVI-I connector connected to analog display.
> > > > > */
> > > > > +          if ((link->link_enc->connector.id ==
> > > > > CONNECTOR_ID_DUAL_LINK_DVII ||
> > > > > +               link->link_enc->connector.id ==
> > > > > CONNECTOR_ID_SINGLE_LINK_DVII) &&
> > > > > +                  sink->edid_caps.analog)
> > > > > +                  sink->sink_signal = SIGNAL_TYPE_RGB;
> > > > > +
> > > > >            /* HDMI-DVI Dongle */
> > > > >            if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A
> > > > > &&
> > > > >                !sink->edid_caps.edid_hdmi)
> > > > > @@ -1228,6 +1242,64 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >    return true;
> > > > >  }
> > > > > 
> > > > > +/**
> > > > > + * Evaluates whether an EDID header is acceptable,
> > > > > + * for the purpose of determining a connection with a
> > > > > display.
> > > > > + */
> > > > > +static bool link_detect_evaluate_edid_header(uint8_t
> > > > > edid_header[8])
> > > > > +{
> > > > > +  int edid_header_score = 0;
> > > > > +  int i;
> > > > > +
> > > > > +  for (i = 0; i < 8; ++i)
> > > > > +          edid_header_score += edid_header[i] == ((i == 0
> > > > > > > i == 7) ? 0x00 : 0xff);
> > > > > +
> > > > > +  return edid_header_score >= 6;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * Tries to detect a connected display by probing the DDC
> > > > > + * and reading the EDID header.
> > > > > + * The probing is considered successful if we receive a
> > > > > + * reply from the DDC over I2C and the EDID header matches.
> > > > > + */
> > > > > +static bool link_detect_ddc_probe(struct dc_link *link)
> > > > > +{
> > > > > +  if (!link->ddc)
> > > > > +          return false;
> > > > > +
> > > > > +  uint8_t edid_header[8] = {0};
> > > > > +  bool ddc_probed = i2c_read(link->ddc, 0x50, edid_header,
> > > > > sizeof(edid_header));
> > > > > +
> > > > > +  if (!ddc_probed)
> > > > > +          return false;
> > > > > +
> > > > > +  if (!link_detect_evaluate_edid_header(edid_header))
> > > > > +          return false;
> > > > > +
> > > > > +  return true;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > + * Determines if there is an analog sink connected.
> > > > > + */
> > > > > +static bool link_detect_analog(struct dc_link *link, enum
> > > > > dc_connection_type *type)
> > > > > +{
> > > > > +  /* Don't care about connectors that don't support an
> > > > > analog signal. */
> > > > > +  if (link->link_enc->connector.id != CONNECTOR_ID_VGA &&
> > > > > +          link->link_enc->connector.id !=
> > > > > CONNECTOR_ID_SINGLE_LINK_DVII &&
> > > > > +          link->link_enc->connector.id !=
> > > > > CONNECTOR_ID_DUAL_LINK_DVII)
> > > > > +          return false;
> > > > > +
> > > > > +  if (link_detect_ddc_probe(link)) {
> > > > > +          *type = dc_connection_single;
> > > > > +          return true;
> > > > > +  }
> > > > > +
> > > > > +  *type = dc_connection_none;
> > > > > +  return true;
> > > > > +}
> > > > > +
> > > > >  /*
> > > > >   * link_detect_connection_type() - Determine if there is a
> > > > > sink
> > > > > connected
> > > > >   *
> > > > > @@ -1238,6 +1310,7 @@ static bool
> > > > > detect_link_and_local_sink(struct dc_link *link,
> > > > >  bool link_detect_connection_type(struct dc_link *link, enum
> > > > > dc_connection_type *type)
> > > > >  {
> > > > >    uint32_t is_hpd_high = 0;
> > > > > +  bool supports_hpd = link->irq_source_hpd !=
> > > > > DC_IRQ_SOURCE_INVALID;
> > > > > 
> > > > >    if (link->connector_signal == SIGNAL_TYPE_LVDS) {
> > > > >            *type = dc_connection_single;
> > > > > @@ -1261,6 +1334,8 @@ bool link_detect_connection_type(struct
> > > > > dc_link *link, enum dc_connection_type *
> > > > >            return true;
> > > > >    }
> > > > > 
> > > > > +  if (!supports_hpd)
> > > > > +          return link_detect_analog(link, type);
> > > > > 
> > > > >    if (!query_hpd_status(link, &is_hpd_high))
> > > > >            goto hpd_gpio_failure;
> > > > > @@ -1269,6 +1344,9 @@ bool link_detect_connection_type(struct
> > > > > dc_link *link, enum dc_connection_type *
> > > > >            *type = dc_connection_single;
> > > > >            /* TODO: need to do the actual detection */
> > > > >    } else {
> > > > > +          if (link_detect_analog(link, type))
> > > > > +                  return true;
> > > > > +
> > > > >            *type = dc_connection_none;
> > > > >            if (link->connector_signal == SIGNAL_TYPE_EDP) {
> > > > >                    /* eDP is not connected, power down it
> > > > > */
> > > > > diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > index d6b7347c6c11..ac25d89a4148 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
> > > > > @@ -2256,6 +2256,9 @@ static enum dc_status enable_link(
> > > > >            enable_link_lvds(pipe_ctx);
> > > > >            status = DC_OK;
> > > > >            break;
> > > > > +  case SIGNAL_TYPE_RGB:
> > > > > +          status = DC_OK;
> > > > > +          break;
> > > > >    case SIGNAL_TYPE_VIRTUAL:
> > > > >            status = enable_link_virtual(pipe_ctx);
> > > > >            break;
> > > > > diff --git
> > > > > a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > index 71c10a1261b9..c9725fd316f6 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
> > > > > @@ -555,6 +555,9 @@ static bool construct_phy(struct dc_link
> > > > > *link,
> > > > >    case CONNECTOR_ID_DUAL_LINK_DVII:
> > > > >            link->connector_signal =
> > > > > SIGNAL_TYPE_DVI_DUAL_LINK;
> > > > >            break;
> > > > > +  case CONNECTOR_ID_VGA:
> > > > > +          link->connector_signal = SIGNAL_TYPE_RGB;
> > > > > +          break;
> > > > >    case CONNECTOR_ID_DISPLAY_PORT:
> > > > >    case CONNECTOR_ID_MXM:
> > > > >    case CONNECTOR_ID_USBC:
> > > > 

^ permalink raw reply	[flat|nested] 61+ messages in thread

end of thread, other threads:[~2025-08-20 12:01 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-23 15:57 [PATCH 00/20] Analog connector support in DC Timur Kristóf
2025-07-23 15:57 ` [PATCH 01/20] drm/amd/display: Determine DRM connector type more accurately Timur Kristóf
2025-07-29 18:03   ` Harry Wentland
2025-07-30  7:40     ` Timur Kristóf
2025-07-30 14:30       ` Harry Wentland
2025-07-30 17:03         ` Timur Kristóf
2025-07-30 17:29           ` Harry Wentland
2025-07-30 18:19             ` Timur Kristóf
2025-08-06 14:56   ` Harry Wentland
2025-08-06 17:45     ` Timur Kristóf
2025-08-06 18:13       ` Harry Wentland
2025-08-20 11:49         ` Timur Kristóf
2025-07-23 15:57 ` [PATCH 02/20] drm/amd/display: Add analog bit to edid_caps Timur Kristóf
2025-07-23 15:57 ` [PATCH 03/20] drm/amd/display: Introduce MAX_LINK_ENCODERS Timur Kristóf
2025-07-29 18:06   ` Harry Wentland
2025-07-30  7:40     ` Timur Kristóf
2025-07-23 15:57 ` [PATCH 04/20] drm/amd/display: Hook up DAC to bios_parser_encoder_control Timur Kristóf
2025-07-23 15:57 ` [PATCH 05/20] drm/amd/display: Add SelectCRTC_Source to BIOS parser Timur Kristóf
2025-07-23 15:57 ` [PATCH 06/20] drm/amd/display: Get maximum pixel clock from VBIOS Timur Kristóf
2025-07-23 15:58 ` [PATCH 07/20] drm/amd/display: Don't use stereo sync and audio on RGB signals Timur Kristóf
2025-07-29 18:21   ` Harry Wentland
2025-07-30  8:19     ` Timur Kristóf
2025-07-30 14:34       ` Harry Wentland
2025-07-30 17:08         ` Timur Kristóf
2025-07-31 15:37           ` Harry Wentland
2025-08-01  7:19             ` Alexandre Demers
2025-08-01  8:39               ` Timur Kristóf
2025-08-01 14:55                 ` Harry Wentland
2025-08-01 15:09                   ` Timur Kristóf
2025-07-23 15:58 ` [PATCH 08/20] drm/amd/display: Don't try to enable/disable HPD when unavailable Timur Kristóf
2025-07-23 15:58 ` [PATCH 09/20] drm/amd/display: Add concept of analog encoders Timur Kristóf
2025-07-23 15:58 ` [PATCH 10/20] drm/amd/display: Implement DCE analog stream encoders Timur Kristóf
2025-08-01 18:05   ` Alexandre Demers
2025-08-01 21:29     ` Timur Kristóf
2025-08-03 16:10       ` Alexandre Demers
2025-08-03 20:04         ` Timur Kristóf
2025-08-01 18:06   ` Alexandre Demers
2025-07-23 15:58 ` [PATCH 11/20] drm/amd/display: Implement DCE analog link encoders Timur Kristóf
2025-08-01 19:30   ` Alexandre Demers
2025-08-01 22:02     ` Timur Kristóf
2025-08-03 16:26       ` Alexandre Demers
2025-08-03 20:08         ` Timur Kristóf
2025-07-23 15:58 ` [PATCH 12/20] drm/amd/display: Support DAC in dce110_hwseq Timur Kristóf
2025-07-23 15:58 ` [PATCH 13/20] drm/amd/display: Add analog link detection Timur Kristóf
2025-08-07 19:12   ` Harry Wentland
2025-08-07 20:34     ` Harry Wentland
2025-08-07 21:32       ` Timur Kristóf
2025-08-08 14:03         ` Harry Wentland
2025-08-08 14:22           ` Wheeler, Daniel
2025-08-09 20:17             ` Timur Kristóf
2025-08-15 14:28               ` Wheeler, Daniel
2025-08-20 12:01             ` Timur Kristóf
2025-07-23 15:58 ` [PATCH 14/20] drm/amd/display: Poll analog connectors Timur Kristóf
2025-07-23 15:58 ` [PATCH 15/20] drm/amd/display: Add DCE BIOS_SCRATCH_0 register Timur Kristóf
2025-07-23 15:58 ` [PATCH 16/20] drm/amd/display: Make get_support_mask_for_device_id reusable Timur Kristóf
2025-07-23 15:58 ` [PATCH 17/20] drm/amd/display: Add DAC_LoadDetection to BIOS parser Timur Kristóf
2025-07-23 15:58 ` [PATCH 18/20] drm/amd/display: Use DAC load detection on analog connectors Timur Kristóf
2025-07-23 15:58 ` [PATCH 19/20] drm/amd/display: Add common modes to analog displays without EDID Timur Kristóf
2025-07-23 15:58 ` [PATCH 20/20] drm/amdgpu: Use DC by default for Bonaire Timur Kristóf
2025-07-30 16:29 ` [PATCH 00/20] Analog connector support in DC Harry Wentland
2025-07-30 17:15   ` Timur Kristóf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).