All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/23] USB4 DP tunneling
@ 2021-10-04 14:40 Wayne Lin
  2021-10-04 14:40 ` [PATCH 01/23] drm/amd/display: Update link encoder object creation Wayne Lin
                   ` (23 more replies)
  0 siblings, 24 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Wayne Lin

These series patches are for supporting USB4 DP tunneling feature.

---

Jimmy Kizito (14):
  drm/amd/display: Update link encoder object creation.
  drm/amd/display: Support USB4 dynamic link encoder selection.
  drm/amd/display: Support USB4 for display endpoint control path.
  drm/amd/display: Support DP tunneling when DPRX detection
  drm/amd/display: Update training parameters for DPIA links
  drm/amd/display: Support USB4 when DP link training.
  drm/amd/display: Implement DPIA training loop
  drm/amd/display: Implement DPIA link configuration
  drm/amd/display: Implement DPIA clock recovery phase
  drm/amd/display: Implement DPIA equalisation phase
  drm/amd/display: Implement end of training for hop in DPIA display
    path
  drm/amd/display: Read USB4 DP tunneling data from DPCD.
  drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints.
  drm/amd/display: Add debug flags for USB4 DP link training.

Jude Shih (4):
  drm/amd/display: Support for SET_CONFIG processing with DMUB
  drm/amd/display: Deadlock/HPD Status/Crash Bug Fix
  drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly
  drm/amd/display: USB4 bring up set correct address

Meenakshikumar Somasundaram (5):
  drm/amd/display: USB4 DPIA enumeration and AUX Tunneling
  drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling
  drm/amd/display: Support for SET_CONFIG processing with DMUB
  drm/amd/display: Add dpia debug options
  drm/amd/display: Fix for access for ddc pin and aux engine.

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 106 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  12 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  17 +-
 drivers/gpu/drm/amd/display/dc/Makefile       |   2 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 179 +++-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  81 +-
 .../gpu/drm/amd/display/dc/core/dc_link_ddc.c |   9 +-
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  36 +-
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 945 ++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/core/dc_stat.c |   8 +
 drivers/gpu/drm/amd/display/dc/dc.h           |  22 +
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |  31 +
 drivers/gpu/drm/amd/display/dc/dc_types.h     |   1 +
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  |   3 +
 .../display/dc/dcn31/dcn31_dio_link_encoder.c | 126 ++-
 .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   6 +
 .../drm/amd/display/dc/dcn31/dcn31_resource.c |   7 +
 drivers/gpu/drm/amd/display/dc/dm_helpers.h   |   5 +
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   3 +
 .../gpu/drm/amd/display/dc/inc/dc_link_ddc.h  |   1 +
 .../gpu/drm/amd/display/dc/inc/dc_link_dpia.h |  98 ++
 drivers/gpu/drm/amd/display/dc/inc/resource.h |   1 +
 drivers/gpu/drm/amd/display/dc/os_types.h     |   1 +
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |   3 +
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 113 ++-
 .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c |   1 +
 .../drm/amd/display/dmub/src/dmub_srv_stat.c  |  16 +
 .../gpu/drm/amd/display/include/dal_asic_id.h |   2 +-
 28 files changed, 1793 insertions(+), 42 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h

-- 
2.25.1


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

* [PATCH 01/23] drm/amd/display: Update link encoder object creation.
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 02/23] drm/amd/display: USB4 DPIA enumeration and AUX Tunneling Wayne Lin
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why & How]
Add codes for commit "e1f4328f22c0 drm/amd/display: Update link
encoder object creation" to support USB4 DP tunneling feature

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 77 +++++++++++++++++++
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  2 +
 drivers/gpu/drm/amd/display/dc/inc/resource.h |  1 +
 3 files changed, 80 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8e0bcd4fd000..673fb0ef7a89 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -296,6 +296,75 @@ static bool create_links(
 	return false;
 }
 
+/* Create additional DIG link encoder objects if fewer than the platform
+ * supports were created during link construction. This can happen if the
+ * number of physical connectors is less than the number of DIGs.
+ */
+static bool create_link_encoders(struct dc *dc)
+{
+	bool res = true;
+	unsigned int num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia;
+	unsigned int num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc;
+	int i;
+
+	/* A platform without USB4 DPIA endpoints has a fixed mapping between DIG
+	 * link encoders and physical display endpoints and does not require
+	 * additional link encoder objects.
+	 */
+	if (num_usb4_dpia == 0)
+		return res;
+
+	/* Create as many link encoder objects as the platform supports. DPIA
+	 * endpoints can be programmably mapped to any DIG.
+	 */
+	if (num_dig_link_enc > dc->res_pool->dig_link_enc_count) {
+		for (i = 0; i < num_dig_link_enc; i++) {
+			struct link_encoder *link_enc = dc->res_pool->link_encoders[i];
+
+			if (!link_enc && dc->res_pool->funcs->link_enc_create_minimal) {
+				link_enc = dc->res_pool->funcs->link_enc_create_minimal(dc->ctx,
+						(enum engine_id)(ENGINE_ID_DIGA + i));
+				if (link_enc) {
+					dc->res_pool->link_encoders[i] = link_enc;
+					dc->res_pool->dig_link_enc_count++;
+				} else {
+					res = false;
+				}
+			}
+		}
+	}
+
+	return res;
+}
+
+/* Destroy any additional DIG link encoder objects created by
+ * create_link_encoders().
+ * NB: Must only be called after destroy_links().
+ */
+static void destroy_link_encoders(struct dc *dc)
+{
+	unsigned int num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia;
+	unsigned int num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc;
+	int i;
+
+	/* A platform without USB4 DPIA endpoints has a fixed mapping between DIG
+	 * link encoders and physical display endpoints and does not require
+	 * additional link encoder objects.
+	 */
+	if (num_usb4_dpia == 0)
+		return;
+
+	for (i = 0; i < num_dig_link_enc; i++) {
+		struct link_encoder *link_enc = dc->res_pool->link_encoders[i];
+
+		if (link_enc) {
+			link_enc->funcs->destroy(&link_enc);
+			dc->res_pool->link_encoders[i] = NULL;
+			dc->res_pool->dig_link_enc_count--;
+		}
+	}
+}
+
 static struct dc_perf_trace *dc_perf_trace_create(void)
 {
 	return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL);
@@ -729,6 +798,8 @@ static void dc_destruct(struct dc *dc)
 
 	destroy_links(dc);
 
+	destroy_link_encoders(dc);
+
 	if (dc->clk_mgr) {
 		dc_destroy_clk_mgr(dc->clk_mgr);
 		dc->clk_mgr = NULL;
@@ -933,6 +1004,12 @@ static bool dc_construct(struct dc *dc,
 	if (!create_links(dc, init_params->num_virtual_links))
 		goto fail;
 
+	/* Create additional DIG link encoder objects if fewer than the platform
+	 * supports were created during link construction.
+	 */
+	if (!create_link_encoders(dc))
+		goto fail;
+
 	/* Initialise DIG link encoder resource tracking variables. */
 	link_enc_cfg_init(dc, dc->current_state);
 
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 0fea258c6db3..ed09af238911 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -245,6 +245,8 @@ struct resource_pool {
 	 * entries in link_encoders array.
 	 */
 	unsigned int dig_link_enc_count;
+	/* Number of USB4 DPIA (DisplayPort Input Adapter) link objects created.*/
+	unsigned int usb4_dpia_count;
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	unsigned int hpo_dp_stream_enc_count;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index 3fbda9d7e257..372c0898facd 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -49,6 +49,7 @@ struct resource_caps {
 	int num_vmid;
 	int num_dsc;
 	unsigned int num_dig_link_enc; // Total number of DIGs (digital encoders) in DIO (Display Input/Output).
+	unsigned int num_usb4_dpia; // Total number of USB4 DPIA (DisplayPort Input Adapters).
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	int num_hpo_dp_stream_encoder;
 	int num_hpo_dp_link_encoder;
-- 
2.25.1


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

* [PATCH 02/23] drm/amd/display: USB4 DPIA enumeration and AUX Tunneling
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
  2021-10-04 14:40 ` [PATCH 01/23] drm/amd/display: Update link encoder object creation Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 03/23] drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling Wayne Lin
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito,
	Wayne Lin

From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>

[WHY]
To enable dc links for USB4 DPIA ports and AUX command tunneling
for YELLOW_CARP_B0.

[HOW]
1) Created dc links for all USB4 DPIA ports in create_links().
   dc_link_construct() implementation is split for legacy DDC and DPIAs.
   As usb4 has no ddc, ddc->ddc_pin will be set to NULL for its dc link
   and this parameter will be used to identify the dc links as DPIA. The
   dc link for DPIA is further to be enhanced with implementation for link
   encoder and link initialization.
2) usb4_dpia_count in struct resource_pool will be initialized to 4 in
   dcn31_resource_construct() if the DCN is YELLOW_CARP_B0.
3) Enabled DMUB AUX via outbox for YELLOW_CARP_B0.

Reviewed-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 32 ++++++++-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 71 ++++++++++++++++++-
 .../gpu/drm/amd/display/dc/core/dc_link_ddc.c |  3 +-
 .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |  6 ++
 .../drm/amd/display/dc/dcn31/dcn31_resource.c |  6 ++
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  1 +
 .../gpu/drm/amd/display/dc/inc/dc_link_ddc.h  |  1 +
 drivers/gpu/drm/amd/display/dc/irq_types.h    |  5 +-
 8 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 673fb0ef7a89..f4bb8ea4e83a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -231,6 +231,25 @@ static bool create_links(
 
 	DC_LOG_DC("BIOS object table - end");
 
+	/* Create a link for each usb4 dpia port */
+	for (i = 0; i < dc->res_pool->usb4_dpia_count; i++) {
+		struct link_init_data link_init_params = {0};
+		struct dc_link *link;
+
+		link_init_params.ctx = dc->ctx;
+		link_init_params.connector_index = i;
+		link_init_params.link_index = dc->link_count;
+		link_init_params.dc = dc;
+		link_init_params.is_dpia_link = true;
+
+		link = link_create(&link_init_params);
+		if (link) {
+			dc->links[dc->link_count] = link;
+			link->dc = dc;
+			++dc->link_count;
+		}
+	}
+
 	for (i = 0; i < num_virtual_links; i++) {
 		struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL);
 		struct encoder_init_data enc_init = {0};
@@ -3559,6 +3578,12 @@ void dc_hardware_release(struct dc *dc)
  */
 bool dc_enable_dmub_notifications(struct dc *dc)
 {
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	/* YELLOW_CARP B0 USB4 DPIA needs dmub notifications for interrupts */
+	if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
+	    dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0)
+		return true;
+#endif
 	/* dmub aux needs dmub notifications to be enabled */
 	return dc->debug.enable_dmub_aux_for_legacy_ddc;
 }
@@ -3584,7 +3609,12 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc,
 
 	cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS;
 	cmd.dp_aux_access.header.payload_bytes = 0;
-	cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC;
+	/* For dpia, ddc_pin is set to NULL */
+	if (!dc->links[link_index]->ddc->ddc_pin)
+		cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_DPIA;
+	else
+		cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC;
+
 	cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst;
 	cmd.dp_aux_access.aux_control.sw_crc_enabled = 0;
 	cmd.dp_aux_access.aux_control.timeout = 0;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 64b9c493dce2..20b4819b73e4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1425,8 +1425,8 @@ static enum transmitter translate_encoder_to_transmitter(struct graphics_object_
 	}
 }
 
-static bool dc_link_construct(struct dc_link *link,
-			      const struct link_init_data *init_params)
+static bool dc_link_construct_legacy(struct dc_link *link,
+				     const struct link_init_data *init_params)
 {
 	uint8_t i;
 	struct ddc_service_init_data ddc_service_init_data = { { 0 } };
@@ -1701,6 +1701,73 @@ static bool dc_link_construct(struct dc_link *link,
 	return false;
 }
 
+static bool dc_link_construct_dpia(struct dc_link *link,
+				   const struct link_init_data *init_params)
+{
+	struct ddc_service_init_data ddc_service_init_data = { { 0 } };
+	struct dc_context *dc_ctx = init_params->ctx;
+
+	DC_LOGGER_INIT(dc_ctx->logger);
+
+	/* Initialized dummy hpd and hpd rx */
+	link->irq_source_hpd = DC_IRQ_SOURCE_USB4_DMUB_HPD;
+	link->irq_source_hpd_rx = DC_IRQ_SOURCE_USB4_DMUB_HPDRX;
+	link->link_status.dpcd_caps = &link->dpcd_caps;
+
+	link->dc = init_params->dc;
+	link->ctx = dc_ctx;
+	link->link_index = init_params->link_index;
+
+	memset(&link->preferred_training_settings, 0,
+	       sizeof(struct dc_link_training_overrides));
+	memset(&link->preferred_link_setting, 0,
+	       sizeof(struct dc_link_settings));
+
+	/* Dummy Init for linkid */
+	link->link_id.type = OBJECT_TYPE_CONNECTOR;
+	link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
+	link->is_internal_display = false;
+	link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
+	LINK_INFO("Connector[%d] description:signal %d\n",
+		  init_params->connector_index,
+		  link->connector_signal);
+
+	/* TODO: Initialize link : funcs->link_init */
+
+	ddc_service_init_data.ctx = link->ctx;
+	ddc_service_init_data.id = link->link_id;
+	ddc_service_init_data.link = link;
+	/* Set indicator for dpia link so that ddc won't be created */
+	ddc_service_init_data.is_dpia_link = true;
+
+	link->ddc = dal_ddc_service_create(&ddc_service_init_data);
+	if (!link->ddc) {
+		DC_ERROR("Failed to create ddc_service!\n");
+		goto ddc_create_fail;
+	}
+
+	/* Set dpia port index : 0 to number of dpia ports */
+	link->ddc_hw_inst = init_params->connector_index;
+
+	/* TODO: Create link encoder */
+
+	link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
+
+	return true;
+
+ddc_create_fail:
+	return false;
+}
+
+static bool dc_link_construct(struct dc_link *link,
+			      const struct link_init_data *init_params)
+{
+	/* Handle dpia case */
+	if (init_params->is_dpia_link)
+		return dc_link_construct_dpia(link, init_params);
+	else
+		return dc_link_construct_legacy(link, init_params);
+}
 /*******************************************************************************
  * Public functions
  ******************************************************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
index ba6b56f20269..dd6c473be072 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
@@ -196,7 +196,8 @@ static void ddc_service_construct(
 	ddc_service->link = init_data->link;
 	ddc_service->ctx = init_data->ctx;
 
-	if (BP_RESULT_OK != dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info)) {
+	if (init_data->is_dpia_link ||
+	    dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) {
 		ddc_service->ddc_pin = NULL;
 	} else {
 		DC_LOGGER_INIT(ddc_service->ctx->logger);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
index 80f06ceccea8..18e33ef3d217 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
@@ -174,6 +174,10 @@ void dcn31_init_hw(struct dc *dc)
 		if (hws->funcs.dsc_pg_control != NULL)
 			hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
 
+	/* Enables outbox notifications for usb4 dpia */
+	if (dc->res_pool->usb4_dpia_count)
+		dmub_enable_outbox_notification(dc);
+
 	/* we want to turn off all dp displays before doing detection */
 	if (dc->config.power_down_display_on_boot)
 		blank_all_dp_displays(dc, true);
@@ -278,8 +282,10 @@ void dcn31_init_hw(struct dc *dc)
 	if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
 		dc->res_pool->hubbub->funcs->force_pstate_change_control(
 				dc->res_pool->hubbub, false, false);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
 	if (dc->res_pool->hubbub->funcs->init_crb)
 		dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
+#endif
 }
 
 void dcn31_dsc_pg_control(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index d5b58025f0cc..2e021f9345c0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -2427,6 +2427,12 @@ static bool dcn31_resource_construct(
 		pool->base.sw_i2cs[i] = NULL;
 	}
 
+	if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
+	    dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
+		/* YELLOW CARP B0 has 4 DPIA's */
+		pool->base.usb4_dpia_count = 4;
+	}
+
 	/* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */
 	if (!resource_construct(num_virtual_links, dc, &pool->base,
 			(!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ?
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 ed09af238911..6fc6488c54c0 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -62,6 +62,7 @@ struct link_init_data {
 	uint32_t connector_index; /* this will be mapped to the HPD pins */
 	uint32_t link_index; /* this is mapped to DAL display_index
 				TODO: remove it when DC is complete. */
+	bool is_dpia_link;
 };
 
 struct dc_link *link_create(const struct link_init_data *init_params);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
index 4d7b271b6409..95fb61d62778 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
@@ -69,6 +69,7 @@ struct ddc_service_init_data {
 	struct graphics_object_id id;
 	struct dc_context *ctx;
 	struct dc_link *link;
+	bool is_dpia_link;
 };
 
 struct ddc_service *dal_ddc_service_create(
diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h
index 530c2578db40..7a9f667d5edb 100644
--- a/drivers/gpu/drm/amd/display/dc/irq_types.h
+++ b/drivers/gpu/drm/amd/display/dc/irq_types.h
@@ -153,7 +153,10 @@ enum dc_irq_source {
 	DC_IRQ_SOURCE_DMCUB_OUTBOX,
 	DC_IRQ_SOURCE_DMCUB_OUTBOX0,
 	DC_IRQ_SOURCE_DMCUB_GENERAL_DATAOUT,
-	DAL_IRQ_SOURCES_NUMBER
+	DAL_IRQ_SOURCES_NUMBER,
+	/* Dummy interrupt source for USB4 HPD & HPD RX */
+	DC_IRQ_SOURCE_USB4_DMUB_HPD,
+	DC_IRQ_SOURCE_USB4_DMUB_HPDRX,
 };
 
 enum irq_type
-- 
2.25.1


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

* [PATCH 03/23] drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
  2021-10-04 14:40 ` [PATCH 01/23] drm/amd/display: Update link encoder object creation Wayne Lin
  2021-10-04 14:40 ` [PATCH 02/23] drm/amd/display: USB4 DPIA enumeration and AUX Tunneling Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 04/23] drm/amd/display: Support USB4 dynamic link encoder selection Wayne Lin
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jun Lei, Wayne Lin

From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>

[WHY]
To add support for HPD & HPD RX interrupt handling for USB4 DPIA in
YELLOW_CARP_B0. USB4 DPIA HPD & HPD RX interrupts are issued from DMUB to
driver as a outbox1 message.

[HOW]
1) Created get_link_index_from_dpia_port_index() to retrieve link index
   from dpia port index for HPD & HPD RX dmub notifications.
2) Added DMUB HPD & HPD RX handling in dmub_srv_stat_get_notification().

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 20 +++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/core/dc_stat.c |  7 +++++++
 drivers/gpu/drm/amd/display/dc/dc.h           |  3 +++
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |  4 ++++
 .../drm/amd/display/dmub/src/dmub_srv_stat.c  | 11 ++++++++++
 5 files changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index f4bb8ea4e83a..6cdf68ca9048 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3658,6 +3658,26 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc,
 	return true;
 }
 
+uint8_t get_link_index_from_dpia_port_index(const struct dc *dc,
+					    uint8_t dpia_port_index)
+{
+	uint8_t index, link_index = 0xFF;
+
+	for (index = 0; index < dc->link_count; index++) {
+		/* ddc_hw_inst has dpia port index for dpia links
+		 * and ddc instance for legacy links
+		 */
+		if (!dc->links[index]->ddc->ddc_pin) {
+			if (dc->links[index]->ddc_hw_inst == dpia_port_index) {
+				link_index = index;
+				break;
+			}
+		}
+	}
+	ASSERT(link_index != 0xFF);
+	return link_index;
+}
+
 /**
  * dc_disable_accelerated_mode - disable accelerated mode
  * @dc: dc structure
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
index 28ef9760fa34..7d4a5dc8fc91 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
@@ -61,6 +61,13 @@ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification
 
 	status = dmub_srv_stat_get_notification(dmub, notify);
 	ASSERT(status == DMUB_STATUS_OK);
+
+	/* For HPD/HPD RX, convert dpia port index into link index */
+	if (notify->type == DMUB_NOTIFICATION_HPD ||
+	    notify->type == DMUB_NOTIFICATION_HPD_IRQ) {
+		notify->link_index =
+			get_link_index_from_dpia_port_index(dc, notify->link_index);
+	}
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 204bab6f82ef..d51c7b000eb9 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1395,6 +1395,9 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc,
 				uint32_t link_index,
 				struct aux_payload *payload);
 
+/* Get dc link index from dpia port index */
+uint8_t get_link_index_from_dpia_port_index(const struct dc *dc,
+				uint8_t dpia_port_index);
 /*******************************************************************************
  * DSC Interfaces
  ******************************************************************************/
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 42956dd398f3..a693b743f0d4 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -676,6 +676,10 @@ enum dmub_out_cmd_type {
 	 * Command type used for DP AUX Reply data notification
 	 */
 	DMUB_OUT_CMD__DP_AUX_REPLY = 1,
+	/**
+	 * Command type used for DP HPD event notification
+	 */
+	DMUB_OUT_CMD__DP_HPD_NOTIFY = 2,
 };
 
 #pragma pack(push, 1)
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c
index 70766d534c9c..d7f66e5285c0 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c
@@ -76,6 +76,17 @@ enum dmub_status dmub_srv_stat_get_notification(struct dmub_srv *dmub,
 		dmub_memcpy((void *)&notify->aux_reply,
 			(void *)&cmd.dp_aux_reply.reply_data, sizeof(struct aux_reply_data));
 		break;
+	case DMUB_OUT_CMD__DP_HPD_NOTIFY:
+		if (cmd.dp_hpd_notify.hpd_data.hpd_type == DP_HPD) {
+			notify->type = DMUB_NOTIFICATION_HPD;
+			notify->hpd_status = cmd.dp_hpd_notify.hpd_data.hpd_status;
+		} else {
+			notify->type = DMUB_NOTIFICATION_HPD_IRQ;
+		}
+
+		notify->link_index = cmd.dp_hpd_notify.hpd_data.instance;
+		notify->result = AUX_RET_SUCCESS;
+		break;
 	default:
 		notify->type = DMUB_NOTIFICATION_NO_DATA;
 		break;
-- 
2.25.1


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

* [PATCH 04/23] drm/amd/display: Support USB4 dynamic link encoder selection.
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (2 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 03/23] drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 05/23] drm/amd/display: Support USB4 for display endpoint control path Wayne Lin
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[why & how]
Add codes for commit "f42ef862fb1f drm/amd/display: Add dynamic
link encoder selection" to support USB4 DP tunneling feature.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 ++
 drivers/gpu/drm/amd/display/dc/dc_types.h     | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 20b4819b73e4..66182b8c217b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1732,6 +1732,8 @@ static bool dc_link_construct_dpia(struct dc_link *link,
 		  init_params->connector_index,
 		  link->connector_signal);
 
+	link->ep_type = DISPLAY_ENDPOINT_USB4_DPIA;
+
 	/* TODO: Initialize link : funcs->link_init */
 
 	ddc_service_init_data.ctx = link->ctx;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 3c109c805447..15c353c389d8 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -955,6 +955,7 @@ enum dc_psr_version {
 /* Possible values of display_endpoint_id.endpoint */
 enum display_endpoint_type {
 	DISPLAY_ENDPOINT_PHY = 0, /* Physical connector. */
+	DISPLAY_ENDPOINT_USB4_DPIA, /* USB4 DisplayPort tunnel. */
 	DISPLAY_ENDPOINT_UNKNOWN = -1
 };
 
-- 
2.25.1


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

* [PATCH 05/23] drm/amd/display: Support USB4 for display endpoint control path.
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (3 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 04/23] drm/amd/display: Support USB4 dynamic link encoder selection Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 06/23] drm/amd/display: Support DP tunneling when DPRX detection Wayne Lin
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[why & how]
Add codes for commit "79ed7354d70f drm/amd/display: Update
display endpoint control path" to support USB4 DP tunneling
feature.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  30 ++++-
 .../display/dc/dcn31/dcn31_dio_link_encoder.c | 118 +++++++++++++++++-
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |  41 ++++++
 3 files changed, 182 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 649a9da338a7..4df71d728319 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2312,6 +2312,23 @@ enum link_training_result dc_link_dp_perform_link_training(
 	return status;
 }
 
+/*
+ * Train DP tunneling link for USB4 DPIA display endpoint.
+ *
+ * DPIA equivalent of dc_link_dp_perfrorm_link_training.
+ */
+enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *link,
+	const struct dc_link_settings *link_setting,
+	bool skip_video_pattern)
+{
+	enum link_training_result status;
+
+	/** @todo Always fail until USB4 DPIA training implemented. */
+	status = LINK_TRAINING_CR_FAIL_LANE0;
+
+	return status;
+}
+
 bool perform_link_training_with_retries(
 	const struct dc_link_settings *link_setting,
 	bool skip_video_pattern,
@@ -2383,10 +2400,15 @@ bool perform_link_training_with_retries(
 			dc_link_dp_perform_link_training_skip_aux(link, &current_setting);
 			return true;
 		} else {
-				status = dc_link_dp_perform_link_training(
-										link,
-										&current_setting,
-										skip_video_pattern);
+			if (link->is_dig_mapping_flexible)
+				status = dc_link_dpia_perform_link_training(link,
+									    link_setting,
+									    skip_video_pattern);
+			else
+				status = dc_link_dp_perform_link_training(link,
+									  &current_setting,
+									  skip_video_pattern);
+
 			if (status == LINK_TRAINING_SUCCESS)
 				return true;
 		}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
index 616a48d72afa..f86d4446f347 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
@@ -366,11 +366,44 @@ void dcn31_link_encoder_construct_minimal(
 		SIGNAL_TYPE_EDP;
 }
 
+/* DPIA equivalent of link_transmitter_control. */
+static bool link_dpia_control(struct dc_context *dc_ctx,
+	struct dmub_cmd_dig_dpia_control_data *dpia_control)
+{
+	union dmub_rb_cmd cmd;
+	struct dc_dmub_srv *dmub = dc_ctx->dmub_srv;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.dig1_dpia_control.header.type = DMUB_CMD__DPIA;
+	cmd.dig1_dpia_control.header.sub_type =
+			DMUB_CMD__DPIA_DIG1_DPIA_CONTROL;
+	cmd.dig1_dpia_control.header.payload_bytes =
+		sizeof(cmd.dig1_dpia_control) -
+		sizeof(cmd.dig1_dpia_control.header);
+
+	cmd.dig1_dpia_control.dpia_control = *dpia_control;
+
+	dc_dmub_srv_cmd_queue(dmub, &cmd);
+	dc_dmub_srv_cmd_execute(dmub);
+	dc_dmub_srv_wait_idle(dmub);
+
+	return false;
+}
+
+static void link_encoder_disable(struct dcn10_link_encoder *enc10)
+{
+	/* reset training complete */
+	REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
+}
+
 void dcn31_link_encoder_enable_dp_output(
 	struct link_encoder *enc,
 	const struct dc_link_settings *link_settings,
 	enum clock_source_id clock_source)
 {
+	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+
 	/* Enable transmitter and encoder. */
 	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
 
@@ -378,7 +411,30 @@ void dcn31_link_encoder_enable_dp_output(
 
 	} else {
 
-		/** @todo Handle transmitter with programmable mapping to link encoder. */
+		struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
+		struct dc_link *link;
+
+		link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine);
+
+		enc1_configure_encoder(enc10, link_settings);
+
+		dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_ENABLE;
+		dpia_control.enc_id = enc->preferred_engine;
+		dpia_control.mode_laneset.digmode = 0; /* 0 for SST; 5 for MST */
+		dpia_control.lanenum = (uint8_t)link_settings->lane_count;
+		dpia_control.symclk_10khz = link_settings->link_rate *
+				LINK_RATE_REF_FREQ_IN_KHZ / 10;
+		dpia_control.hpdsel = 5; /* Unused by DPIA */
+
+		if (link) {
+			dpia_control.dpia_id = link->ddc_hw_inst;
+		} else {
+			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
+			BREAK_TO_DEBUGGER();
+			return;
+		}
+
+		link_dpia_control(enc->ctx, &dpia_control);
 	}
 }
 
@@ -387,6 +443,8 @@ void dcn31_link_encoder_enable_dp_mst_output(
 	const struct dc_link_settings *link_settings,
 	enum clock_source_id clock_source)
 {
+	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+
 	/* Enable transmitter and encoder. */
 	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
 
@@ -394,7 +452,30 @@ void dcn31_link_encoder_enable_dp_mst_output(
 
 	} else {
 
-		/** @todo Handle transmitter with programmable mapping to link encoder. */
+		struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
+		struct dc_link *link;
+
+		link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine);
+
+		enc1_configure_encoder(enc10, link_settings);
+
+		dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_ENABLE;
+		dpia_control.enc_id = enc->preferred_engine;
+		dpia_control.mode_laneset.digmode = 5; /* 0 for SST; 5 for MST */
+		dpia_control.lanenum = (uint8_t)link_settings->lane_count;
+		dpia_control.symclk_10khz = link_settings->link_rate *
+				LINK_RATE_REF_FREQ_IN_KHZ / 10;
+		dpia_control.hpdsel = 5; /* Unused by DPIA */
+
+		if (link) {
+			dpia_control.dpia_id = link->ddc_hw_inst;
+		} else {
+			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
+			BREAK_TO_DEBUGGER();
+			return;
+		}
+
+		link_dpia_control(enc->ctx, &dpia_control);
 	}
 }
 
@@ -402,6 +483,8 @@ void dcn31_link_encoder_disable_output(
 	struct link_encoder *enc,
 	enum signal_type signal)
 {
+	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+
 	/* Disable transmitter and encoder. */
 	if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
 
@@ -409,7 +492,36 @@ void dcn31_link_encoder_disable_output(
 
 	} else {
 
-		/** @todo Handle transmitter with programmable mapping to link encoder. */
+		struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
+		struct dc_link *link;
+
+		if (!dcn10_is_dig_enabled(enc))
+			return;
+
+		link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine);
+
+		dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_DISABLE;
+		dpia_control.enc_id = enc->preferred_engine;
+		if (signal == SIGNAL_TYPE_DISPLAY_PORT) {
+			dpia_control.mode_laneset.digmode = 0; /* 0 for SST; 5 for MST */
+		} else if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
+			dpia_control.mode_laneset.digmode = 5; /* 0 for SST; 5 for MST */
+		} else {
+			DC_LOG_ERROR("%s: USB4 DPIA only supports DisplayPort.\n", __func__);
+			BREAK_TO_DEBUGGER();
+		}
+
+		if (link) {
+			dpia_control.dpia_id = link->ddc_hw_inst;
+		} else {
+			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
+			BREAK_TO_DEBUGGER();
+			return;
+		}
+
+		link_dpia_control(enc->ctx, &dpia_control);
+
+		link_encoder_disable(enc10);
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index a693b743f0d4..8461442b03a9 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -654,6 +654,10 @@ enum dmub_cmd_type {
 	 * Command type used for all panel control commands.
 	 */
 	DMUB_CMD__PANEL_CNTL = 74,
+	/**
+	 * Command type used for interfacing with DPIA.
+	 */
+	DMUB_CMD__DPIA = 77,
 	/**
 	 * Command type used for EDID CEA parsing
 	 */
@@ -682,6 +686,11 @@ enum dmub_out_cmd_type {
 	DMUB_OUT_CMD__DP_HPD_NOTIFY = 2,
 };
 
+/* DMUB_CMD__DPIA command sub-types. */
+enum dmub_cmd_dpia_type {
+	DMUB_CMD__DPIA_DIG1_DPIA_CONTROL = 0,
+};
+
 #pragma pack(push, 1)
 
 /**
@@ -1001,6 +1010,34 @@ struct dmub_rb_cmd_dig1_transmitter_control {
 	union dmub_cmd_dig1_transmitter_control_data transmitter_control; /**< payload */
 };
 
+/**
+ * DPIA tunnel command parameters.
+ */
+struct dmub_cmd_dig_dpia_control_data {
+	uint8_t enc_id;         /** 0 = ENGINE_ID_DIGA, ... */
+	uint8_t action;         /** ATOM_TRANSMITER_ACTION_DISABLE/ENABLE/SETUP_VSEMPH */
+	union {
+		uint8_t digmode;    /** enum atom_encode_mode_def */
+		uint8_t dplaneset;  /** DP voltage swing and pre-emphasis value */
+	} mode_laneset;
+	uint8_t lanenum;        /** Lane number 1, 2, 4, 8 */
+	uint32_t symclk_10khz;  /** Symbol Clock in 10Khz */
+	uint8_t hpdsel;         /** =0: HPD is not assigned */
+	uint8_t digfe_sel;      /** DIG stream( front-end ) selection, bit0 - DIG0 FE */
+	uint8_t dpia_id;        /** Index of DPIA */
+	uint8_t fec_rdy : 1;
+	uint8_t reserved : 7;
+	uint32_t reserved1;
+};
+
+/**
+ * DMUB command for DPIA tunnel control.
+ */
+struct dmub_rb_cmd_dig1_dpia_control {
+	struct dmub_cmd_header header;
+	struct dmub_cmd_dig_dpia_control_data dpia_control;
+};
+
 /**
  * struct dmub_rb_cmd_dpphy_init - DPPHY init.
  */
@@ -2442,6 +2479,10 @@ union dmub_rb_cmd {
 	 * Definition of a DMUB_CMD__VBIOS_LVTMA_CONTROL command.
 	 */
 	struct dmub_rb_cmd_lvtma_control lvtma_control;
+	/**
+	 * Definition of a DMUB_CMD__DPIA_DIG1_CONTROL command.
+	 */
+	struct dmub_rb_cmd_dig1_dpia_control dig1_dpia_control;
 	/**
 	 * Definition of a DMUB_CMD__EDID_CEA command.
 	 */
-- 
2.25.1


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

* [PATCH 06/23] drm/amd/display: Support DP tunneling when DPRX detection
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (4 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 05/23] drm/amd/display: Support USB4 for display endpoint control path Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 07/23] drm/amd/display: Update training parameters for DPIA links Wayne Lin
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[why & how]
Add codes for commit "99732e52e7f8 drm/amd/display: Update DPRX detection"
to support USB4 DP tunneling feature

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/Makefile       |  2 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  2 +
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  4 ++
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 34 +++++++++++++++++
 .../gpu/drm/amd/display/dc/inc/dc_link_dpia.h | 38 +++++++++++++++++++
 5 files changed, 79 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h

diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile
index 520f58538364..1a0e462bed42 100644
--- a/drivers/gpu/drm/amd/display/dc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/Makefile
@@ -61,7 +61,7 @@ include $(AMD_DC)
 
 DISPLAY_CORE = dc.o  dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
 dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o \
-dc_link_enc_cfg.o dc_link_dpcd.o
+dc_link_enc_cfg.o dc_link_dpia.o dc_link_dpcd.o
 
 ifdef CONFIG_DRM_AMD_DC_DCN
 DISPLAY_CORE += dc_vm_helper.o
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 66182b8c217b..1c397d5551ba 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1726,6 +1726,7 @@ static bool dc_link_construct_dpia(struct dc_link *link,
 	/* Dummy Init for linkid */
 	link->link_id.type = OBJECT_TYPE_CONNECTOR;
 	link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
+	link->link_id.enum_id = ENUM_ID_1 + init_params->connector_index;
 	link->is_internal_display = false;
 	link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
 	LINK_INFO("Connector[%d] description:signal %d\n",
@@ -1733,6 +1734,7 @@ static bool dc_link_construct_dpia(struct dc_link *link,
 		  link->connector_signal);
 
 	link->ep_type = DISPLAY_ENDPOINT_USB4_DPIA;
+	link->is_dig_mapping_flexible = true;
 
 	/* TODO: Initialize link : funcs->link_init */
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 4df71d728319..9bc5f49ea2ec 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -36,6 +36,7 @@
 #include "dpcd_defs.h"
 #include "dc_dmub_srv.h"
 #include "dce/dmub_hw_lock_mgr.h"
+#include "inc/dc_link_dpia.h"
 #include "inc/link_enc_cfg.h"
 
 /*Travis*/
@@ -4582,6 +4583,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
 
 		/* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */
 		is_lttpr_present = (dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) != 0 &&
+				link->dpcd_caps.lttpr_caps.phy_repeater_cnt < 0xff &&
 				link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
 				link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
 				link->dpcd_caps.lttpr_caps.revision.raw >= 0x14);
@@ -4630,6 +4632,8 @@ static bool retrieve_link_cap(struct dc_link *link)
 			LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD);
 
 	is_lttpr_present = dp_retrieve_lttpr_cap(link);
+	/* Read DP tunneling information. */
+	status = dpcd_get_tunneling_device_data(link);
 
 	status = core_link_read_dpcd(link, DP_SET_POWER,
 			&dpcd_power_state, sizeof(dpcd_power_state));
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
new file mode 100644
index 000000000000..183601e300fe
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dc_link_dpia.h"
+#include "inc/core_status.h"
+#include "dc_link.h"
+
+enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link)
+{
+	/** @todo Read corresponding DPCD region and update link caps. */
+	return DC_OK;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
new file mode 100644
index 000000000000..8ed0c9f6414b
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DC_LINK_DPIA_H__
+#define __DC_LINK_DPIA_H__
+
+/* This module implements functionality for training DPIA links. */
+
+struct dc_link;
+
+/* Read tunneling device capability from DPCD and update link capability
+ * accordingly.
+ */
+enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link);
+
+#endif /* __DC_LINK_DPIA_H__ */
-- 
2.25.1


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

* [PATCH 07/23] drm/amd/display: Update training parameters for DPIA links
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (5 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 06/23] drm/amd/display: Support DP tunneling when DPRX detection Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 08/23] drm/amd/display: Support USB4 when DP link training Wayne Lin
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[why & how]
Add codes for commit "ede4f6dac99e drm/amd/display: Update
setting of DP training parameters." to support USB4 DP tunneling
feature

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 9bc5f49ea2ec..dd1d0262ba40 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1777,6 +1777,13 @@ static enum dc_status configure_lttpr_mode_non_transparent(
 
 		if (encoding == DP_8b_10b_ENCODING) {
 			repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
+
+			/* Driver does not need to train the first hop. Skip DPCD read and clear
+			 * AUX_RD_INTERVAL for DPTX-to-DPIA hop.
+			 */
+			if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+				link->dpcd_caps.lttpr_caps.aux_rd_interval[--repeater_cnt] = 0;
+
 			for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) {
 				aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 +
 							((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1));
-- 
2.25.1


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

* [PATCH 08/23] drm/amd/display: Support USB4 when DP link training
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (6 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 07/23] drm/amd/display: Update training parameters for DPIA links Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 09/23] drm/amd/display: Implement DPIA training loop Wayne Lin
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why & How]
Add codes for commit "822536713066 drm/amd/display: Add fallback
and abort paths for DP link training" to support USB4 DP tunneling
feature

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c    | 6 ++++++
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 1c397d5551ba..6b5ddf0a29c1 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1862,6 +1862,12 @@ static enum dc_status enable_link_dp(struct dc_state *state,
 	/* get link settings for video mode timing */
 	decide_link_settings(stream, &link_settings);
 
+	/* Train with fallback when enabling DPIA link. Conventional links are
+	 * trained with fallback during sink detection.
+	 */
+	if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+		do_fallback = true;
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING &&
 			pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index dd1d0262ba40..d7dddc0998db 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2408,9 +2408,9 @@ bool perform_link_training_with_retries(
 			dc_link_dp_perform_link_training_skip_aux(link, &current_setting);
 			return true;
 		} else {
-			if (link->is_dig_mapping_flexible)
+			if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
 				status = dc_link_dpia_perform_link_training(link,
-									    link_setting,
+									    &current_setting,
 									    skip_video_pattern);
 			else
 				status = dc_link_dp_perform_link_training(link,
-- 
2.25.1


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

* [PATCH 09/23] drm/amd/display: Implement DPIA training loop
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (7 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 08/23] drm/amd/display: Support USB4 when DP link training Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 10/23] drm/amd/display: Implement DPIA link configuration Wayne Lin
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Training of DPIA link differs enough from that of conventional
DP link to warrant a separate implementation.

[How]
- Implement top-level of DPIA training loop.
- Make functions shared between DP and DPIA link training "public".

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  17 ---
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 109 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/inc/dc_link_dpia.h |  10 ++
 drivers/gpu/drm/amd/display/dc/os_types.h     |   1 +
 4 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index d7dddc0998db..7f6fd0a3bf18 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2320,23 +2320,6 @@ enum link_training_result dc_link_dp_perform_link_training(
 	return status;
 }
 
-/*
- * Train DP tunneling link for USB4 DPIA display endpoint.
- *
- * DPIA equivalent of dc_link_dp_perfrorm_link_training.
- */
-enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *link,
-	const struct dc_link_settings *link_setting,
-	bool skip_video_pattern)
-{
-	enum link_training_result status;
-
-	/** @todo Always fail until USB4 DPIA training implemented. */
-	status = LINK_TRAINING_CR_FAIL_LANE0;
-
-	return status;
-}
-
 bool perform_link_training_with_retries(
 	const struct dc_link_settings *link_setting,
 	bool skip_video_pattern,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index 183601e300fe..4e9bbc9180d0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -23,12 +23,121 @@
  *
  */
 
+#include "dc.h"
 #include "dc_link_dpia.h"
 #include "inc/core_status.h"
 #include "dc_link.h"
+#include "dc_link_dp.h"
 
 enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link)
 {
 	/** @todo Read corresponding DPCD region and update link caps. */
 	return DC_OK;
 }
+
+/* Configure link as prescribed in link_setting; set LTTPR mode; and
+ * Initialize link training settings.
+ */
+static enum link_training_result dpia_configure_link(struct dc_link *link,
+		const struct dc_link_settings *link_setting,
+		struct link_training_settings *lt_settings)
+{
+	enum link_training_result result;
+
+	/** @todo Fail until implemented. */
+	result = LINK_TRAINING_ABORT;
+
+	return result;
+}
+
+/* Execute clock recovery phase of link training for specified hop in display
+ * path.
+ */
+static enum link_training_result dpia_training_cr_phase(struct dc_link *link,
+		struct link_training_settings *lt_settings,
+		uint32_t hop)
+{
+	enum link_training_result result;
+
+	/** @todo Fail until implemented. */
+	result = LINK_TRAINING_ABORT;
+
+	return result;
+}
+
+/* Execute equalization phase of link training for specified hop in display
+ * path.
+ */
+static enum link_training_result dpia_training_eq_phase(struct dc_link *link,
+		struct link_training_settings *lt_settings,
+		uint32_t hop)
+{
+	enum link_training_result result;
+
+	/** @todo Fail until implemented. */
+	result = LINK_TRAINING_ABORT;
+
+	return result;
+}
+
+/* End training of specified hop in display path. */
+static enum link_training_result dpia_training_end(struct dc_link *link,
+		uint32_t hop)
+{
+	enum link_training_result result;
+
+	/** @todo Fail until implemented. */
+	result = LINK_TRAINING_ABORT;
+
+	return result;
+}
+
+enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *link,
+	const struct dc_link_settings *link_setting,
+	bool skip_video_pattern)
+{
+	enum link_training_result result;
+	struct link_training_settings lt_settings;
+	uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */
+	uint8_t repeater_id; /* Current hop. */
+
+	/* Configure link as prescribed in link_setting and set LTTPR mode. */
+	result = dpia_configure_link(link, link_setting, &lt_settings);
+	if (result != LINK_TRAINING_SUCCESS)
+		return result;
+
+	if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
+		repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
+
+	/* Train each hop in turn starting with the one closest to DPTX.
+	 * In transparent or non-LTTPR mode, train only the final hop (DPRX).
+	 */
+	for (repeater_id = repeater_cnt; repeater_id >= 0; repeater_id--) {
+		/* Clock recovery. */
+		result = dpia_training_cr_phase(link, &lt_settings, repeater_id);
+		if (result != LINK_TRAINING_SUCCESS)
+			break;
+
+		/* Equalization. */
+		result = dpia_training_eq_phase(link, &lt_settings, repeater_id);
+		if (result != LINK_TRAINING_SUCCESS)
+			break;
+
+		/* Stop training hop. */
+		result = dpia_training_end(link, repeater_id);
+		if (result != LINK_TRAINING_SUCCESS)
+			break;
+	}
+
+	/* Double-check link status if training successful; gracefully stop
+	 * training of current hop if training failed for any reason other than
+	 * sink unplug.
+	 */
+	if (result == LINK_TRAINING_SUCCESS) {
+		msleep(5);
+		result = dp_check_link_loss_status(link, &lt_settings);
+	} else if (result != LINK_TRAINING_ABORT) {
+		dpia_training_end(link, repeater_id);
+	}
+	return result;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
index 8ed0c9f6414b..1392eb689d1e 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
@@ -29,10 +29,20 @@
 /* This module implements functionality for training DPIA links. */
 
 struct dc_link;
+struct dc_link_settings;
 
 /* Read tunneling device capability from DPCD and update link capability
  * accordingly.
  */
 enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link);
 
+/* Train DP tunneling link for USB4 DPIA display endpoint.
+ * DPIA equivalent of dc_link_dp_perfrorm_link_training.
+ * Aborts link training upon detection of sink unplug.
+ */
+enum link_training_result
+dc_link_dpia_perform_link_training(struct dc_link *link,
+	const struct dc_link_settings *link_setting,
+	bool skip_video_pattern);
+
 #endif /* __DC_LINK_DPIA_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/os_types.h b/drivers/gpu/drm/amd/display/dc/os_types.h
index f50cae252de4..415b56223bcf 100644
--- a/drivers/gpu/drm/amd/display/dc/os_types.h
+++ b/drivers/gpu/drm/amd/display/dc/os_types.h
@@ -31,6 +31,7 @@
 #include <linux/kref.h>
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 
 #include <asm/byteorder.h>
 
-- 
2.25.1


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

* [PATCH 10/23] drm/amd/display: Implement DPIA link configuration
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (8 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 09/23] drm/amd/display: Implement DPIA training loop Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 11/23] drm/amd/display: Implement DPIA clock recovery phase Wayne Lin
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Training settings need to be applied to DPIA link at start of each
training loop. Note: FEC readiness should be configured before link
training while FEC enablement should be configured once training is
complete.

[How]
- Implement DPIA link configuration function.
- Account for dynamically assigned link encoders during link
configuration.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 49 ++++++++++++++++---
 .../display/dc/dcn31/dcn31_dio_link_encoder.c |  2 +
 2 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index 4e9bbc9180d0..5ffaf6ca372b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -29,6 +29,9 @@
 #include "dc_link.h"
 #include "dc_link_dp.h"
 
+#define DC_LOGGER \
+	link->ctx->logger
+
 enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link)
 {
 	/** @todo Read corresponding DPCD region and update link caps. */
@@ -37,17 +40,51 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link)
 
 /* Configure link as prescribed in link_setting; set LTTPR mode; and
  * Initialize link training settings.
+ * Abort link training if sink unplug detected.
+ *
+ * @param link DPIA link being trained.
+ * @param[in] link_setting Lane count, link rate and downspread control.
+ * @param[out] lt_settings Link settings and drive settings (voltage swing and pre-emphasis).
  */
 static enum link_training_result dpia_configure_link(struct dc_link *link,
 		const struct dc_link_settings *link_setting,
 		struct link_training_settings *lt_settings)
 {
-	enum link_training_result result;
-
-	/** @todo Fail until implemented. */
-	result = LINK_TRAINING_ABORT;
-
-	return result;
+	enum dc_status status;
+	bool fec_enable;
+
+	DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) configuring\n - LTTPR mode(%d)\n",
+				__func__,
+				link->link_id.enum_id - ENUM_ID_1,
+				link->lttpr_mode);
+
+	dp_decide_training_settings(link,
+		link_setting,
+		lt_settings);
+
+	status = dpcd_configure_channel_coding(link, lt_settings);
+	if (status != DC_OK && !link->hpd_status)
+		return LINK_TRAINING_ABORT;
+
+	/* Configure lttpr mode */
+	status = dpcd_configure_lttpr_mode(link, lt_settings);
+	if (status != DC_OK && !link->hpd_status)
+		return LINK_TRAINING_ABORT;
+
+	/* Set link rate, lane count and spread. */
+	status = dpcd_set_link_settings(link, lt_settings);
+	if (status != DC_OK && !link->hpd_status)
+		return LINK_TRAINING_ABORT;
+
+	if (link->preferred_training_settings.fec_enable)
+		fec_enable = *link->preferred_training_settings.fec_enable;
+	else
+		fec_enable = true;
+	status = dp_set_fec_ready(link, fec_enable);
+	if (status != DC_OK && !link->hpd_status)
+		return LINK_TRAINING_ABORT;
+
+	return LINK_TRAINING_SUCCESS;
 }
 
 /* Execute clock recovery phase of link training for specified hop in display
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
index f86d4446f347..a5266d5999d7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
@@ -428,6 +428,7 @@ void dcn31_link_encoder_enable_dp_output(
 
 		if (link) {
 			dpia_control.dpia_id = link->ddc_hw_inst;
+			dpia_control.fec_rdy = link->fec_state == dc_link_fec_ready ? 1 : 0;
 		} else {
 			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
 			BREAK_TO_DEBUGGER();
@@ -469,6 +470,7 @@ void dcn31_link_encoder_enable_dp_mst_output(
 
 		if (link) {
 			dpia_control.dpia_id = link->ddc_hw_inst;
+			dpia_control.fec_rdy = link->fec_state == dc_link_fec_ready ? 1 : 0;
 		} else {
 			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
 			BREAK_TO_DEBUGGER();
-- 
2.25.1


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

* [PATCH 11/23] drm/amd/display: Implement DPIA clock recovery phase
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (9 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 10/23] drm/amd/display: Implement DPIA link configuration Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 12/23] drm/amd/display: Implement DPIA equalisation phase Wayne Lin
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Clock recovery is the mandatory first phase of DP link training.

[How]
- Implement clock recovery phase in DPIA training module.
- Add helper functions for building SET_CONFIG messages.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 420 +++++++++++++++++-
 .../gpu/drm/amd/display/dc/inc/dc_link_dpia.h |  40 ++
 2 files changed, 453 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index 5ffaf6ca372b..9608fd345936 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -28,6 +28,9 @@
 #include "inc/core_status.h"
 #include "dc_link.h"
 #include "dc_link_dp.h"
+#include "dpcd_defs.h"
+#include "link_hwss.h"
+#include "inc/link_dpcd.h"
 
 #define DC_LOGGER \
 	link->ctx->logger
@@ -87,17 +90,385 @@ static enum link_training_result dpia_configure_link(struct dc_link *link,
 	return LINK_TRAINING_SUCCESS;
 }
 
+static enum dc_status core_link_send_set_config(struct dc_link *link,
+		uint8_t msg_type, uint8_t msg_data)
+{
+	/** @todo Implement */
+	return DC_OK;
+}
+
+/* Build SET_CONFIG message data payload for specified message type. */
+static uint8_t dpia_build_set_config_data(enum dpia_set_config_type type,
+		struct dc_link *link,
+		struct link_training_settings *lt_settings)
+{
+	union dpia_set_config_data data;
+
+	data.raw = 0;
+
+	switch (type) {
+	case DPIA_SET_CFG_SET_LINK:
+		data.set_link.mode = link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT ? 1 : 0;
+		break;
+	case DPIA_SET_CFG_SET_PHY_TEST_MODE:
+		break;
+	case DPIA_SET_CFG_SET_VSPE:
+		/* Assume all lanes have same drive settings. */
+		data.set_vspe.swing = lt_settings->lane_settings[0].VOLTAGE_SWING;
+		data.set_vspe.pre_emph = lt_settings->lane_settings[0].PRE_EMPHASIS;
+		data.set_vspe.max_swing_reached =
+			lt_settings->lane_settings[0].VOLTAGE_SWING == VOLTAGE_SWING_MAX_LEVEL ? 1 : 0;
+		data.set_vspe.max_pre_emph_reached =
+			lt_settings->lane_settings[0].PRE_EMPHASIS == PRE_EMPHASIS_MAX_LEVEL ? 1 : 0;
+		break;
+	default:
+		ASSERT(false); /* Message type not supported by helper function. */
+		break;
+	}
+
+	return data.raw;
+}
+
+/* Convert DC training pattern to DPIA training stage. */
+static enum dpia_set_config_ts convert_trng_ptn_to_trng_stg(enum dc_dp_training_pattern tps)
+{
+	enum dpia_set_config_ts ts;
+
+	switch (tps) {
+	case DP_TRAINING_PATTERN_SEQUENCE_1:
+		ts = DPIA_TS_TPS1;
+		break;
+	case DP_TRAINING_PATTERN_SEQUENCE_2:
+		ts = DPIA_TS_TPS2;
+		break;
+	case DP_TRAINING_PATTERN_SEQUENCE_3:
+		ts = DPIA_TS_TPS3;
+		break;
+	case DP_TRAINING_PATTERN_SEQUENCE_4:
+		ts = DPIA_TS_TPS4;
+		break;
+	default:
+		ASSERT(false); /* TPS not supported by helper function. */
+		break;
+	}
+
+	return ts;
+}
+
+/* Write training pattern to DPCD. */
+static enum dc_status dpcd_set_lt_pattern(struct dc_link *link,
+	enum dc_dp_training_pattern pattern,
+	uint32_t hop)
+{
+	union dpcd_training_pattern dpcd_pattern = { {0} };
+	uint32_t dpcd_tps_offset = DP_TRAINING_PATTERN_SET;
+	enum dc_status status;
+
+	if (hop != DPRX)
+		dpcd_tps_offset = DP_TRAINING_PATTERN_SET_PHY_REPEATER1 +
+			((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (hop - 1));
+
+	/* DpcdAddress_TrainingPatternSet */
+	dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
+		dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern);
+
+	dpcd_pattern.v1_4.SCRAMBLING_DISABLE =
+		dc_dp_initialize_scrambling_data_symbols(link, pattern);
+
+	if (hop != DPRX) {
+		DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n 0x%X pattern = %x\n",
+					__func__,
+					hop,
+					dpcd_tps_offset,
+					dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
+	} else {
+		DC_LOG_HW_LINK_TRAINING("%s\n 0x%X pattern = %x\n",
+					__func__,
+					dpcd_tps_offset,
+					dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
+	}
+
+	status = core_link_write_dpcd(link,
+				      DP_TRAINING_PATTERN_SET,
+				      &dpcd_pattern.raw,
+				      sizeof(dpcd_pattern.raw));
+
+	return status;
+}
+
+/* Execute clock recovery phase of link training for specified hop in display
+ * path.in non-transparent mode:
+ * - Driver issues both DPCD and SET_CONFIG transactions.
+ * - TPS1 is transmitted for any hops downstream of DPOA.
+ * - Drive (VS/PE) only transmitted for the hop immediately downstream of DPOA.
+ * - CR for the first hop (DPTX-to-DPIA) is assumed to be successful.
+ *
+ * @param link DPIA link being trained.
+ * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
+ * @param hop Hop in display path. DPRX = 0.
+ */
+static enum link_training_result dpia_training_cr_non_transparent(struct dc_link *link,
+		struct link_training_settings *lt_settings,
+		uint32_t hop)
+{
+	enum link_training_result result = LINK_TRAINING_CR_FAIL_LANE0;
+	uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */
+	enum dc_status status;
+	uint32_t retries_cr = 0; /* Number of consecutive attempts with same VS or PE. */
+	uint32_t retry_count = 0;
+	/* From DP spec, CR read interval is always 100us. */
+	uint32_t wait_time_microsec = TRAINING_AUX_RD_INTERVAL;
+	struct link_training_settings req_settings;
+	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
+	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
+	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
+	uint8_t set_cfg_data;
+	enum dpia_set_config_ts ts;
+
+	repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
+
+	/* Cap of LINK_TRAINING_MAX_CR_RETRY attempts at clock recovery.
+	 * Fix inherited from perform_clock_recovery_sequence() -
+	 * the DP equivalent of this function:
+	 * Required for Synaptics MST hub which can put the LT in
+	 * infinite loop by switching the VS between level 0 and level 1
+	 * continuously.
+	 */
+	while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
+	       (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
+		/* DPTX-to-DPIA */
+		if (hop == repeater_cnt) {
+			/* Send SET_CONFIG(SET_LINK:LC,LR,LTTPR) to notify DPOA that
+			 * non-transparent link training has started.
+			 * This also enables the transmission of clk_sync packets.
+			 */
+			set_cfg_data = dpia_build_set_config_data(DPIA_SET_CFG_SET_LINK,
+					link,
+					lt_settings);
+			status = core_link_send_set_config(link,
+					DPIA_SET_CFG_SET_LINK,
+					set_cfg_data);
+			/* CR for this hop is considered successful as long as
+			 * SET_CONFIG message is acknowledged by DPOA.
+			 */
+			if (status == DC_OK)
+				result = LINK_TRAINING_SUCCESS;
+			else
+				result = LINK_TRAINING_ABORT;
+			break;
+		}
+
+		/* DPOA-to-x */
+		/* Instruct DPOA to transmit TPS1 then update DPCD. */
+		if (retry_count == 0) {
+			ts = convert_trng_ptn_to_trng_stg(lt_settings->pattern_for_cr);
+			status = core_link_send_set_config(link,
+					DPIA_SET_CFG_SET_TRAINING,
+					ts);
+			if (status != DC_OK) {
+				result = LINK_TRAINING_ABORT;
+				break;
+			}
+			status = dpcd_set_lt_pattern(link, lt_settings->pattern_for_cr, hop);
+			if (status != DC_OK) {
+				result = LINK_TRAINING_ABORT;
+				break;
+			}
+		}
+
+		/* Update DPOA drive settings then DPCD. DPOA does only adjusts
+		 * drive settings for hops immediately downstream.
+		 */
+		if (hop == repeater_cnt - 1) {
+			set_cfg_data = dpia_build_set_config_data(DPIA_SET_CFG_SET_VSPE,
+					link,
+					lt_settings);
+			status = core_link_send_set_config(link,
+					DPIA_SET_CFG_SET_VSPE,
+					set_cfg_data);
+			if (status != DC_OK) {
+				result = LINK_TRAINING_ABORT;
+				break;
+			}
+		}
+		status = dpcd_set_lane_settings(link, lt_settings, hop);
+		if (status != DC_OK) {
+			result = LINK_TRAINING_ABORT;
+			break;
+		}
+
+		dp_wait_for_training_aux_rd_interval(link, wait_time_microsec);
+
+		/* Read status and adjustment requests from DPCD. */
+		status = dp_get_lane_status_and_drive_settings(link,
+				lt_settings,
+				dpcd_lane_status,
+				&dpcd_lane_status_updated,
+				&req_settings,
+				hop);
+		if (status != DC_OK) {
+			result = LINK_TRAINING_ABORT;
+			break;
+		}
+
+		/* Check if clock recovery successful. */
+		if (dp_is_cr_done(lane_count, dpcd_lane_status)) {
+			result = LINK_TRAINING_SUCCESS;
+			break;
+		}
+
+		result = dp_get_cr_failure(lane_count, dpcd_lane_status);
+
+		if (dp_is_max_vs_reached(lt_settings))
+			break;
+
+		/* Count number of attempts with same drive settings.
+		 * Note: settings are the same for all lanes,
+		 * so comparing first lane is sufficient.
+		 */
+		if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
+			req_settings.lane_settings[0].VOLTAGE_SWING &&
+			lt_settings->lane_settings[0].PRE_EMPHASIS ==
+			req_settings.lane_settings[0].PRE_EMPHASIS)
+			retries_cr++;
+		else
+			retries_cr = 0;
+
+		/* Update VS/PE. */
+		dp_update_drive_settings(lt_settings, req_settings);
+		retry_count++;
+	}
+
+	/* Abort link training if clock recovery failed due to HPD unplug. */
+	if (!link->hpd_status)
+		result = LINK_TRAINING_ABORT;
+
+	DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) clock recovery\n -hop(%d)\n - result(%d)\n - retries(%d)\n",
+				__func__,
+				link->link_id.enum_id - ENUM_ID_1,
+				hop,
+				result,
+				retry_count);
+
+	return result;
+}
+
+/* Execute clock recovery phase of link training in transparent LTTPR mode:
+ * - Driver only issues DPCD transactions and leaves USB4 tunneling (SET_CONFIG) messages to DPIA.
+ * - Driver writes TPS1 to DPCD to kick off training.
+ * - Clock recovery (CR) for link is handled by DPOA, which reports result to DPIA on completion.
+ * - DPIA communicates result to driver by updating CR status when driver reads DPCD.
+ *
+ * @param link DPIA link being trained.
+ * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
+ */
+static enum link_training_result dpia_training_cr_transparent(struct dc_link *link,
+		struct link_training_settings *lt_settings)
+{
+	enum link_training_result result = LINK_TRAINING_CR_FAIL_LANE0;
+	enum dc_status status;
+	uint32_t retries_cr = 0; /* Number of consecutive attempts with same VS or PE. */
+	uint32_t retry_count = 0;
+	uint32_t wait_time_microsec = lt_settings->cr_pattern_time;
+	struct link_training_settings req_settings;
+	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
+	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
+	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
+
+	/* Cap of LINK_TRAINING_MAX_CR_RETRY attempts at clock recovery.
+	 * Fix inherited from perform_clock_recovery_sequence() -
+	 * the DP equivalent of this function:
+	 * Required for Synaptics MST hub which can put the LT in
+	 * infinite loop by switching the VS between level 0 and level 1
+	 * continuously.
+	 */
+	while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
+	       (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
+		/* Write TPS1 (not VS or PE) to DPCD to start CR phase.
+		 * DPIA sends SET_CONFIG(SET_LINK) to notify DPOA to
+		 * start link training.
+		 */
+		if (retry_count == 0) {
+			status = dpcd_set_lt_pattern(link, lt_settings->pattern_for_cr, DPRX);
+			if (status != DC_OK) {
+				result = LINK_TRAINING_ABORT;
+				break;
+			}
+		}
+
+		dp_wait_for_training_aux_rd_interval(link, wait_time_microsec);
+
+		/* Read status and adjustment requests from DPCD. */
+		status = dp_get_lane_status_and_drive_settings(link,
+				lt_settings,
+				dpcd_lane_status,
+				&dpcd_lane_status_updated,
+				&req_settings,
+				DPRX);
+		if (status != DC_OK) {
+			result = LINK_TRAINING_ABORT;
+			break;
+		}
+
+		/* Check if clock recovery successful. */
+		if (dp_is_cr_done(lane_count, dpcd_lane_status)) {
+			result = LINK_TRAINING_SUCCESS;
+			break;
+		}
+
+		result = dp_get_cr_failure(lane_count, dpcd_lane_status);
+
+		if (dp_is_max_vs_reached(lt_settings))
+			break;
+
+		/* Count number of attempts with same drive settings.
+		 * Note: settings are the same for all lanes,
+		 * so comparing first lane is sufficient.
+		 */
+		if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
+			req_settings.lane_settings[0].VOLTAGE_SWING &&
+			lt_settings->lane_settings[0].PRE_EMPHASIS ==
+			req_settings.lane_settings[0].PRE_EMPHASIS)
+			retries_cr++;
+		else
+			retries_cr = 0;
+
+		/* Update VS/PE. */
+		dp_update_drive_settings(lt_settings, req_settings);
+		retry_count++;
+	}
+
+	/* Abort link training if clock recovery failed due to HPD unplug. */
+	if (!link->hpd_status)
+		result = LINK_TRAINING_ABORT;
+
+	DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) clock recovery\n -hop(%d)\n - result(%d)\n - retries(%d)\n",
+				__func__,
+				link->link_id.enum_id - ENUM_ID_1,
+				DPRX,
+				result,
+				retry_count);
+
+	return result;
+}
+
 /* Execute clock recovery phase of link training for specified hop in display
  * path.
+ *
+ * @param link DPIA link being trained.
+ * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
+ * @param hop Hop in display path. DPRX = 0.
  */
 static enum link_training_result dpia_training_cr_phase(struct dc_link *link,
 		struct link_training_settings *lt_settings,
 		uint32_t hop)
 {
-	enum link_training_result result;
+	enum link_training_result result = LINK_TRAINING_CR_FAIL_LANE0;
 
-	/** @todo Fail until implemented. */
-	result = LINK_TRAINING_ABORT;
+	if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
+		result = dpia_training_cr_non_transparent(link, lt_settings, hop);
+	else
+		result = dpia_training_cr_transparent(link, lt_settings);
 
 	return result;
 }
@@ -129,6 +500,38 @@ static enum link_training_result dpia_training_end(struct dc_link *link,
 	return result;
 }
 
+/* When aborting training of specified hop in display path, clean up by:
+ * - Attempting to clear DPCD TRAINING_PATTERN_SET, LINK_BW_SET and LANE_COUNT_SET.
+ * - Sending SET_CONFIG(SET_LINK) with lane count and link rate set to 0.
+ *
+ * @param link DPIA link being trained.
+ * @param hop Hop in display path. DPRX = 0.
+ */
+static void dpia_training_abort(struct dc_link *link, uint32_t hop)
+{
+	uint8_t data = 0;
+	uint32_t dpcd_tps_offset = DP_TRAINING_PATTERN_SET;
+
+	DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) aborting\n - LTTPR mode(%d)\n - HPD(%d)\n",
+				__func__,
+				link->link_id.enum_id - ENUM_ID_1,
+				link->lttpr_mode,
+				link->hpd_status);
+
+	/* Abandon clean-up if sink unplugged. */
+	if (!link->hpd_status)
+		return;
+
+	if (hop != DPRX)
+		dpcd_tps_offset = DP_TRAINING_PATTERN_SET_PHY_REPEATER1 +
+			((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (hop - 1));
+
+	core_link_write_dpcd(link, dpcd_tps_offset, &data, 1);
+	core_link_write_dpcd(link, DP_LINK_BW_SET, &data, 1);
+	core_link_write_dpcd(link, DP_LANE_COUNT_SET, &data, 1);
+	core_link_send_set_config(link, DPIA_SET_CFG_SET_LINK, data);
+}
+
 enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *link,
 	const struct dc_link_settings *link_setting,
 	bool skip_video_pattern)
@@ -166,14 +569,17 @@ enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *lin
 			break;
 	}
 
-	/* Double-check link status if training successful; gracefully stop
-	 * training of current hop if training failed for any reason other than
-	 * sink unplug.
+	/* Double-check link status if training successful; gracefully abort
+	 * training of current hop if training failed due to message tunneling
+	 * failure; end training of hop if training ended conventionally and
+	 * falling back to lower bandwidth settings possible.
 	 */
 	if (result == LINK_TRAINING_SUCCESS) {
 		msleep(5);
 		result = dp_check_link_loss_status(link, &lt_settings);
-	} else if (result != LINK_TRAINING_ABORT) {
+	} else if (result == LINK_TRAINING_ABORT) {
+		dpia_training_abort(link, repeater_id);
+	} else {
 		dpia_training_end(link, repeater_id);
 	}
 	return result;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
index 1392eb689d1e..76b6b1e23575 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
@@ -31,6 +31,46 @@
 struct dc_link;
 struct dc_link_settings;
 
+/* The approximate time (us) it takes to transmit 9 USB4 DP clock sync packets. */
+#define DPIA_CLK_SYNC_DELAY 16000
+
+/* SET_CONFIG message types sent by driver. */
+enum dpia_set_config_type {
+	DPIA_SET_CFG_SET_LINK = 0x01,
+	DPIA_SET_CFG_SET_PHY_TEST_MODE = 0x05,
+	DPIA_SET_CFG_SET_TRAINING = 0x18,
+	DPIA_SET_CFG_SET_VSPE = 0x19
+};
+
+/* Training stages (TS) in SET_CONFIG(SET_TRAINING) message. */
+enum dpia_set_config_ts {
+	DPIA_TS_DPRX_DONE = 0x00, /* Done training DPRX. */
+	DPIA_TS_TPS1 = 0x01,
+	DPIA_TS_TPS2 = 0x02,
+	DPIA_TS_TPS3 = 0x03,
+	DPIA_TS_TPS4 = 0x07,
+	DPIA_TS_UFP_DONE = 0xff /* Done training DPTX-to-DPIA hop. */
+};
+
+/* SET_CONFIG message data associated with messages sent by driver. */
+union dpia_set_config_data {
+	struct {
+		uint8_t mode : 1;
+		uint8_t reserved : 7;
+	} set_link;
+	struct {
+		uint8_t stage;
+	} set_training;
+	struct {
+		uint8_t swing : 2;
+		uint8_t max_swing_reached : 1;
+		uint8_t pre_emph : 2;
+		uint8_t max_pre_emph_reached : 1;
+		uint8_t reserved : 2;
+	} set_vspe;
+	uint8_t raw;
+};
+
 /* Read tunneling device capability from DPCD and update link capability
  * accordingly.
  */
-- 
2.25.1


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

* [PATCH 12/23] drm/amd/display: Implement DPIA equalisation phase
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (10 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 11/23] drm/amd/display: Implement DPIA clock recovery phase Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 13/23] drm/amd/display: Implement end of training for hop in DPIA display path Wayne Lin
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Equalisation is the mandatory second phase of DisplayPort link training
over a USB4 DP tunnel.

[How]
Implement equalisation phase for DP tunneled over USB4 in DPIA
training module.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 247 +++++++++++++++++-
 1 file changed, 244 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index 9608fd345936..fa7539916c77 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -473,17 +473,258 @@ static enum link_training_result dpia_training_cr_phase(struct dc_link *link,
 	return result;
 }
 
+/* Return status read interval during equalization phase. */
+static uint32_t dpia_get_eq_aux_rd_interval(const struct dc_link *link,
+		const struct link_training_settings *lt_settings,
+		uint32_t hop)
+{
+	uint32_t wait_time_microsec;
+
+	if (hop == DPRX)
+		wait_time_microsec = lt_settings->eq_pattern_time;
+	else
+		wait_time_microsec =
+				dp_translate_training_aux_read_interval(
+					link->dpcd_caps.lttpr_caps.aux_rd_interval[hop - 1]);
+
+	return wait_time_microsec;
+}
+
+/* Execute equalization phase of link training for specified hop in display
+ * path in non-transparent mode:
+ * - driver issues both DPCD and SET_CONFIG transactions.
+ * - TPSx is transmitted for any hops downstream of DPOA.
+ * - Drive (VS/PE) only transmitted for the hop immediately downstream of DPOA.
+ * - EQ for the first hop (DPTX-to-DPIA) is assumed to be successful.
+ * - DPRX EQ only reported successful when both DPRX and DPIA requirements
+ * (clk sync packets sent) fulfilled.
+ *
+ * @param link DPIA link being trained.
+ * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
+ * @param hop Hop in display path. DPRX = 0.
+ */
+static enum link_training_result dpia_training_eq_non_transparent(struct dc_link *link,
+		struct link_training_settings *lt_settings,
+		uint32_t hop)
+{
+	enum link_training_result result = LINK_TRAINING_EQ_FAIL_EQ;
+	uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */
+	uint32_t retries_eq = 0;
+	enum dc_status status;
+	enum dc_dp_training_pattern tr_pattern;
+	uint32_t wait_time_microsec;
+	struct link_training_settings req_settings;
+	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
+	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
+	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
+	uint8_t set_cfg_data;
+	enum dpia_set_config_ts ts;
+
+	/* Training pattern is TPS4 for repeater;
+	 * TPS2/3/4 for DPRX depending on what it supports.
+	 */
+	if (hop == DPRX)
+		tr_pattern = lt_settings->pattern_for_eq;
+	else
+		tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4;
+
+	repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
+
+	for (retries_eq = 0; retries_eq < LINK_TRAINING_MAX_RETRY_COUNT; retries_eq++) {
+		/* DPTX-to-DPIA equalization always successful. */
+		if (hop == repeater_cnt) {
+			result = LINK_TRAINING_SUCCESS;
+			break;
+		}
+
+		/* Instruct DPOA to transmit TPSn then update DPCD. */
+		if (retries_eq == 0) {
+			ts = convert_trng_ptn_to_trng_stg(tr_pattern);
+			status = core_link_send_set_config(link,
+					DPIA_SET_CFG_SET_TRAINING,
+					ts);
+			if (status != DC_OK) {
+				result = LINK_TRAINING_ABORT;
+				break;
+			}
+			status = dpcd_set_lt_pattern(link, tr_pattern, hop);
+			if (status != DC_OK) {
+				result = LINK_TRAINING_ABORT;
+				break;
+			}
+		}
+
+		/* Update DPOA drive settings then DPCD. DPOA only adjusts
+		 * drive settings for hop immediately downstream.
+		 */
+		if (hop == repeater_cnt - 1) {
+			set_cfg_data = dpia_build_set_config_data(DPIA_SET_CFG_SET_VSPE,
+								  link,
+								  lt_settings);
+			status = core_link_send_set_config(link,
+							   DPIA_SET_CFG_SET_VSPE,
+							   set_cfg_data);
+			if (status != DC_OK) {
+				result = LINK_TRAINING_ABORT;
+				break;
+			}
+		}
+		status = dpcd_set_lane_settings(link, lt_settings, hop);
+		if (status != DC_OK) {
+			result = LINK_TRAINING_ABORT;
+			break;
+		}
+
+		/* Extend wait time on second equalisation attempt on final hop to
+		 * ensure clock sync packets have been sent.
+		 */
+		if (hop == DPRX && retries_eq == 1)
+			wait_time_microsec = max(wait_time_microsec, (uint32_t)DPIA_CLK_SYNC_DELAY);
+		else
+			wait_time_microsec = dpia_get_eq_aux_rd_interval(link, lt_settings, hop);
+
+		dp_wait_for_training_aux_rd_interval(link, wait_time_microsec);
+
+		/* Read status and adjustment requests from DPCD. */
+		status = dp_get_lane_status_and_drive_settings(link,
+				lt_settings,
+				dpcd_lane_status,
+				&dpcd_lane_status_updated,
+				&req_settings,
+				hop);
+		if (status != DC_OK) {
+			result = LINK_TRAINING_ABORT;
+			break;
+		}
+
+		/* CR can still fail during EQ phase. Fail training if CR fails. */
+		if (!dp_is_cr_done(lane_count, dpcd_lane_status)) {
+			result = LINK_TRAINING_EQ_FAIL_CR;
+			break;
+		}
+
+		if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) &&
+		    dp_is_symbol_locked(link->cur_link_settings.lane_count, dpcd_lane_status) &&
+		    dp_is_interlane_aligned(dpcd_lane_status_updated)) {
+			result =  LINK_TRAINING_SUCCESS;
+			break;
+		}
+
+		/* Update VS/PE. */
+		dp_update_drive_settings(lt_settings, req_settings);
+	}
+
+	/* Abort link training if equalization failed due to HPD unplug. */
+	if (!link->hpd_status)
+		result = LINK_TRAINING_ABORT;
+
+	DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) equalization\n - hop(%d)\n - result(%d)\n - retries(%d)\n",
+				__func__,
+				link->link_id.enum_id - ENUM_ID_1,
+				hop,
+				result,
+				retries_eq);
+
+	return result;
+}
+
+/* Execute equalization phase of link training for specified hop in display
+ * path in transparent LTTPR mode:
+ * - driver only issues DPCD transactions leaves USB4 tunneling (SET_CONFIG) messages to DPIA.
+ * - driver writes TPSx to DPCD to notify DPIA that is in equalization phase.
+ * - equalization (EQ) for link is handled by DPOA, which reports result to DPIA on completion.
+ * - DPIA communicates result to driver by updating EQ status when driver reads DPCD.
+ *
+ * @param link DPIA link being trained.
+ * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
+ * @param hop Hop in display path. DPRX = 0.
+ */
+static enum link_training_result dpia_training_eq_transparent(struct dc_link *link,
+		struct link_training_settings *lt_settings)
+{
+	enum link_training_result result = LINK_TRAINING_EQ_FAIL_EQ;
+	uint32_t retries_eq = 0;
+	enum dc_status status;
+	enum dc_dp_training_pattern tr_pattern = lt_settings->pattern_for_eq;
+	uint32_t wait_time_microsec;
+	struct link_training_settings req_settings;
+	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
+	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
+	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
+
+	wait_time_microsec = dpia_get_eq_aux_rd_interval(link, lt_settings, DPRX);
+
+	for (retries_eq = 0; retries_eq < LINK_TRAINING_MAX_RETRY_COUNT; retries_eq++) {
+		if (retries_eq == 0) {
+			status = dpcd_set_lt_pattern(link, tr_pattern, DPRX);
+			if (status != DC_OK) {
+				result = LINK_TRAINING_ABORT;
+				break;
+			}
+		}
+
+		dp_wait_for_training_aux_rd_interval(link, wait_time_microsec);
+
+		/* Read status and adjustment requests from DPCD. */
+		status = dp_get_lane_status_and_drive_settings(link,
+				lt_settings,
+				dpcd_lane_status,
+				&dpcd_lane_status_updated,
+				&req_settings,
+				DPRX);
+		if (status != DC_OK) {
+			result = LINK_TRAINING_ABORT;
+			break;
+		}
+
+		/* CR can still fail during EQ phase. Fail training if CR fails. */
+		if (!dp_is_cr_done(lane_count, dpcd_lane_status)) {
+			result = LINK_TRAINING_EQ_FAIL_CR;
+			break;
+		}
+
+		if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) &&
+		    dp_is_symbol_locked(link->cur_link_settings.lane_count, dpcd_lane_status) &&
+		    dp_is_interlane_aligned(dpcd_lane_status_updated)) {
+			result =  LINK_TRAINING_SUCCESS;
+			break;
+		}
+
+		/* Update VS/PE. */
+		dp_update_drive_settings(lt_settings, req_settings);
+	}
+
+	/* Abort link training if equalization failed due to HPD unplug. */
+	if (!link->hpd_status)
+		result = LINK_TRAINING_ABORT;
+
+	DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) equalization\n - hop(%d)\n - result(%d)\n - retries(%d)\n",
+				__func__,
+				link->link_id.enum_id - ENUM_ID_1,
+				DPRX,
+				result,
+				retries_eq);
+
+	return result;
+}
+
 /* Execute equalization phase of link training for specified hop in display
  * path.
+ *
+ * @param link DPIA link being trained.
+ * @param lt_settings link_setting and drive settings (voltage swing and pre-emphasis).
+ * @param hop Hop in display path. DPRX = 0.
  */
 static enum link_training_result dpia_training_eq_phase(struct dc_link *link,
 		struct link_training_settings *lt_settings,
 		uint32_t hop)
 {
-	enum link_training_result result;
+	enum link_training_result result = LINK_TRAINING_EQ_FAIL_EQ;
 
-	/** @todo Fail until implemented. */
-	result = LINK_TRAINING_ABORT;
+	if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
+		result = dpia_training_eq_non_transparent(link, lt_settings, hop);
+	else
+		result = dpia_training_eq_transparent(link, lt_settings);
 
 	return result;
 }
-- 
2.25.1


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

* [PATCH 13/23] drm/amd/display: Implement end of training for hop in DPIA display path
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (11 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 12/23] drm/amd/display: Implement DPIA equalisation phase Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 14/23] drm/amd/display: Support for SET_CONFIG processing with DMUB Wayne Lin
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why & How]
Clear training pattern sequence for hop in display path once clock
recovery and equalization phases of DP tunnel link training completed.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 10 ++-
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 77 ++++++++++++++++++-
 2 files changed, 82 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 7f6fd0a3bf18..bfba1d2c6a18 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2391,14 +2391,20 @@ bool perform_link_training_with_retries(
 			dc_link_dp_perform_link_training_skip_aux(link, &current_setting);
 			return true;
 		} else {
-			if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+			/** @todo Consolidate USB4 DP and DPx.x training. */
+			if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
 				status = dc_link_dpia_perform_link_training(link,
 									    &current_setting,
 									    skip_video_pattern);
-			else
+
+				/* Transmit idle pattern once training successful. */
+				if (status == LINK_TRAINING_SUCCESS)
+					dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
+			} else {
 				status = dc_link_dp_perform_link_training(link,
 									  &current_setting,
 									  skip_video_pattern);
+			}
 
 			if (status == LINK_TRAINING_SUCCESS)
 				return true;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index fa7539916c77..4b1ad057bd1f 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -730,13 +730,84 @@ static enum link_training_result dpia_training_eq_phase(struct dc_link *link,
 }
 
 /* End training of specified hop in display path. */
+static enum dc_status dpcd_clear_lt_pattern(struct dc_link *link, uint32_t hop)
+{
+	union dpcd_training_pattern dpcd_pattern = { {0} };
+	uint32_t dpcd_tps_offset = DP_TRAINING_PATTERN_SET;
+	enum dc_status status;
+
+	if (hop != DPRX)
+		dpcd_tps_offset = DP_TRAINING_PATTERN_SET_PHY_REPEATER1 +
+			((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (hop - 1));
+
+	status = core_link_write_dpcd(link,
+			DP_TRAINING_PATTERN_SET,
+			&dpcd_pattern.raw,
+			sizeof(dpcd_pattern.raw));
+
+	return status;
+}
+
+/* End training of specified hop in display path.
+ *
+ * In transparent LTTPR mode:
+ * - driver clears training pattern for the specified hop in DPCD.
+ * In non-transparent LTTPR mode:
+ * - in addition to clearing training pattern, driver issues USB4 tunneling
+ * (SET_CONFIG) messages to notify DPOA when training is done for first hop
+ * (DPTX-to-DPIA) and last hop (DPRX).
+ *
+ * @param link DPIA link being trained.
+ * @param hop Hop in display path. DPRX = 0.
+ */
 static enum link_training_result dpia_training_end(struct dc_link *link,
 		uint32_t hop)
 {
-	enum link_training_result result;
+	enum link_training_result result = LINK_TRAINING_SUCCESS;
+	uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */
+	enum dc_status status;
 
-	/** @todo Fail until implemented. */
-	result = LINK_TRAINING_ABORT;
+	if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
+		repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
+
+		if (hop == repeater_cnt) { /* DPTX-to-DPIA */
+			/* Send SET_CONFIG(SET_TRAINING:0xff) to notify DPOA that
+			 * DPTX-to-DPIA hop trained. No DPCD write needed for first hop.
+			 */
+			status = core_link_send_set_config(link,
+					DPIA_SET_CFG_SET_TRAINING,
+					DPIA_TS_UFP_DONE);
+			if (status != DC_OK)
+				result = LINK_TRAINING_ABORT;
+		} else { /* DPOA-to-x */
+			/* Write 0x0 to TRAINING_PATTERN_SET */
+			status = dpcd_clear_lt_pattern(link, hop);
+			if (status != DC_OK)
+				result = LINK_TRAINING_ABORT;
+		}
+
+		/* Notify DPOA that non-transparent link training of DPRX done. */
+		if (hop == DPRX && result != LINK_TRAINING_ABORT) {
+			status = core_link_send_set_config(link,
+					DPIA_SET_CFG_SET_TRAINING,
+					DPIA_TS_DPRX_DONE);
+			if (status != DC_OK)
+				result = LINK_TRAINING_ABORT;
+		}
+
+	} else { /* non-LTTPR or transparent LTTPR. */
+		/* Write 0x0 to TRAINING_PATTERN_SET */
+		status = dpcd_clear_lt_pattern(link, hop);
+		if (status != DC_OK)
+			result = LINK_TRAINING_ABORT;
+	}
+
+	DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) end\n - hop(%d)\n - result(%d)\n - LTTPR mode(%d)\n",
+				__func__,
+				link->link_id.enum_id - ENUM_ID_1,
+				hop,
+				result,
+				link->lttpr_mode);
 
 	return result;
 }
-- 
2.25.1


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

* [PATCH 14/23] drm/amd/display: Support for SET_CONFIG processing with DMUB
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (12 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 13/23] drm/amd/display: Implement end of training for hop in DPIA display path Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 15/23] drm/amd/display: Read USB4 DP tunneling data from DPCD Wayne Lin
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jun Lei, Wayne Lin

From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>

[Why]
To process SET_CONFIG transactions with DMUB using inbox1 and
outbox1 mail boxes.

[How]
1) Added inbox1 DPIA command subtype DMUB_CMD__DPIA_SET_CONFIG_ACCESS to
   issue SET_CONFIG command to DMUB in dc_process_dmub_set_config_async().
   DMUB processes the command with DPIA sends reply back immediately or
   in an outbox1 message triggering an outbox1 interrupt to driver.
2) DMUB posts SET_CONFIG reply as an Outbox1 message of type
   DMUB_OUT_CMD__SET_CONFIG_REPLY.
3) The dmub async to sync mechanism for AUX is modified to accommodate
   SET_CONFIG commands for both command issue and reply code paths.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 50 ++++++++++++++
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 16 ++++-
 drivers/gpu/drm/amd/display/dc/core/dc_stat.c |  3 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |  7 ++
 drivers/gpu/drm/amd/display/dc/dm_helpers.h   |  5 ++
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |  2 +
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 65 +++++++++++++++++++
 .../drm/amd/display/dmub/src/dmub_srv_stat.c  |  5 ++
 8 files changed, 149 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 6cdf68ca9048..517a2f0b4ba1 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3678,6 +3678,56 @@ uint8_t get_link_index_from_dpia_port_index(const struct dc *dc,
 	return link_index;
 }
 
+/**
+ *****************************************************************************
+ *  Function: dc_process_dmub_set_config_async
+ *
+ *  @brief
+ *		Submits set_config command to dmub via inbox message
+ *
+ *  @param
+ *		[in] dc: dc structure
+ *		[in] link_index: link index
+ *		[in] payload: aux payload
+ *		[out] notify: set_config immediate reply
+ *
+ *	@return
+ *		True if successful, False if failure
+ *****************************************************************************
+ */
+bool dc_process_dmub_set_config_async(struct dc *dc,
+				uint32_t link_index,
+				struct set_config_cmd_payload *payload,
+				struct dmub_notification *notify)
+{
+	union dmub_rb_cmd cmd = {0};
+	struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv;
+	bool is_cmd_complete = true;
+
+	/* prepare SET_CONFIG command */
+	cmd.set_config_access.header.type = DMUB_CMD__DPIA;
+	cmd.set_config_access.header.sub_type = DMUB_CMD__DPIA_SET_CONFIG_ACCESS;
+
+	cmd.set_config_access.set_config_control.instance = dc->links[link_index]->ddc_hw_inst;
+	cmd.set_config_access.set_config_control.cmd_pkt.msg_type = payload->msg_type;
+	cmd.set_config_access.set_config_control.cmd_pkt.msg_data = payload->msg_data;
+
+	if (!dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd)) {
+		/* command is not processed by dmub */
+		notify->sc_status = SET_CONFIG_UNKNOWN_ERROR;
+		return is_cmd_complete;
+	}
+
+	/* command processed by dmub, if ret_status is 1, it is completed instantly */
+	if (cmd.set_config_access.header.ret_status == 1)
+		notify->sc_status = cmd.set_config_access.set_config_control.immed_status;
+	else
+		/* cmd pending, will receive notification via outbox */
+		is_cmd_complete = false;
+
+	return is_cmd_complete;
+}
+
 /**
  * dc_disable_accelerated_mode - disable accelerated mode
  * @dc: dc structure
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index 4b1ad057bd1f..a7fc60565bda 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -31,6 +31,8 @@
 #include "dpcd_defs.h"
 #include "link_hwss.h"
 #include "inc/link_dpcd.h"
+#include "dm_helpers.h"
+#include "dmub/inc/dmub_cmd.h"
 
 #define DC_LOGGER \
 	link->ctx->logger
@@ -91,10 +93,18 @@ static enum link_training_result dpia_configure_link(struct dc_link *link,
 }
 
 static enum dc_status core_link_send_set_config(struct dc_link *link,
-		uint8_t msg_type, uint8_t msg_data)
+	uint8_t msg_type,
+	uint8_t msg_data)
 {
-	/** @todo Implement */
-	return DC_OK;
+	struct set_config_cmd_payload payload;
+	enum set_config_status set_config_result = SET_CONFIG_PENDING;
+
+	/* prepare set_config payload */
+	payload.msg_type = msg_type;
+	payload.msg_data = msg_data;
+
+	/* set_config should return ACK if successful */
+	return (set_config_result == SET_CONFIG_ACK_RECEIVED) ? DC_OK : DC_ERROR_UNEXPECTED;
 }
 
 /* Build SET_CONFIG message data payload for specified message type. */
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
index 7d4a5dc8fc91..4b372aa52801 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c
@@ -64,7 +64,8 @@ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification
 
 	/* For HPD/HPD RX, convert dpia port index into link index */
 	if (notify->type == DMUB_NOTIFICATION_HPD ||
-	    notify->type == DMUB_NOTIFICATION_HPD_IRQ) {
+	    notify->type == DMUB_NOTIFICATION_HPD_IRQ ||
+	    notify->type == DMUB_NOTIFICATION_SET_CONFIG_REPLY) {
 		notify->link_index =
 			get_link_index_from_dpia_port_index(dc, notify->link_index);
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index d51c7b000eb9..082706c921af 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -44,6 +44,8 @@
 
 /* forward declaration */
 struct aux_payload;
+struct set_config_cmd_payload;
+struct dmub_notification;
 
 #define DC_VER "3.2.156"
 
@@ -1398,6 +1400,11 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc,
 /* Get dc link index from dpia port index */
 uint8_t get_link_index_from_dpia_port_index(const struct dc *dc,
 				uint8_t dpia_port_index);
+
+bool dc_process_dmub_set_config_async(struct dc *dc,
+				uint32_t link_index,
+				struct set_config_cmd_payload *payload,
+				struct dmub_notification *notify);
 /*******************************************************************************
  * DSC Interfaces
  ******************************************************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index 3a905fb667bf..0fe66b080a03 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -179,4 +179,9 @@ int dm_helper_dmub_aux_transfer_sync(
 		const struct dc_link *link,
 		struct aux_payload *payload,
 		enum aux_return_code_type *operation_result);
+enum set_config_status;
+int dm_helpers_dmub_set_config_sync(struct dc_context *ctx,
+		const struct dc_link *link,
+		struct set_config_cmd_payload *payload,
+		enum set_config_status *operation_result);
 #endif /* __DM_HELPERS__ */
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index efb667cf6c98..7a86c97af910 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -119,6 +119,7 @@ enum dmub_notification_type {
 	DMUB_NOTIFICATION_AUX_REPLY,
 	DMUB_NOTIFICATION_HPD,
 	DMUB_NOTIFICATION_HPD_IRQ,
+	DMUB_NOTIFICATION_SET_CONFIG_REPLY,
 	DMUB_NOTIFICATION_MAX
 };
 
@@ -440,6 +441,7 @@ struct dmub_notification {
 	union {
 		struct aux_reply_data aux_reply;
 		enum dp_hpd_status hpd_status;
+		enum set_config_status sc_status;
 	};
 };
 
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 8461442b03a9..4c61e73ceccd 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -684,11 +684,16 @@ enum dmub_out_cmd_type {
 	 * Command type used for DP HPD event notification
 	 */
 	DMUB_OUT_CMD__DP_HPD_NOTIFY = 2,
+	/**
+	 * Command type used for SET_CONFIG Reply notification
+	 */
+	DMUB_OUT_CMD__SET_CONFIG_REPLY = 3,
 };
 
 /* DMUB_CMD__DPIA command sub-types. */
 enum dmub_cmd_dpia_type {
 	DMUB_CMD__DPIA_DIG1_DPIA_CONTROL = 0,
+	DMUB_CMD__DPIA_SET_CONFIG_ACCESS = 1,
 };
 
 #pragma pack(push, 1)
@@ -1038,6 +1043,31 @@ struct dmub_rb_cmd_dig1_dpia_control {
 	struct dmub_cmd_dig_dpia_control_data dpia_control;
 };
 
+/**
+ * SET_CONFIG Command Payload
+ */
+struct set_config_cmd_payload {
+	uint8_t msg_type; /* set config message type */
+	uint8_t msg_data; /* set config message data */
+};
+
+/**
+ * Data passed from driver to FW in a DMUB_CMD__DPIA_SET_CONFIG_ACCESS command.
+ */
+struct dmub_cmd_set_config_control_data {
+	struct set_config_cmd_payload cmd_pkt;
+	uint8_t instance; /* DPIA instance */
+	uint8_t immed_status; /* Immediate status returned in case of error */
+};
+
+/**
+ * DMUB command structure for SET_CONFIG command.
+ */
+struct dmub_rb_cmd_set_config_access {
+	struct dmub_cmd_header header; /* header */
+	struct dmub_cmd_set_config_control_data set_config_control; /* set config data */
+};
+
 /**
  * struct dmub_rb_cmd_dpphy_init - DPPHY init.
  */
@@ -1285,6 +1315,33 @@ struct dmub_rb_cmd_dp_hpd_notify {
 	struct dp_hpd_data hpd_data;
 };
 
+/**
+ * Definition of a SET_CONFIG reply from DPOA.
+ */
+enum set_config_status {
+	SET_CONFIG_PENDING = 0,
+	SET_CONFIG_ACK_RECEIVED,
+	SET_CONFIG_RX_TIMEOUT,
+	SET_CONFIG_UNKNOWN_ERROR,
+};
+
+/**
+ * Definition of a set_config reply
+ */
+struct set_config_reply_control_data {
+	uint8_t instance; /* DPIA Instance */
+	uint8_t status; /* Set Config reply */
+	uint16_t pad; /* Alignment */
+};
+
+/**
+ * Definition of a DMUB_OUT_CMD__SET_CONFIG_REPLY command.
+ */
+struct dmub_rb_cmd_dp_set_config_reply {
+	struct dmub_cmd_header header;
+	struct set_config_reply_control_data set_config_reply_control;
+};
+
 /*
  * Command IDs should be treated as stable ABI.
  * Do not reuse or modify IDs.
@@ -2483,6 +2540,10 @@ union dmub_rb_cmd {
 	 * Definition of a DMUB_CMD__DPIA_DIG1_CONTROL command.
 	 */
 	struct dmub_rb_cmd_dig1_dpia_control dig1_dpia_control;
+	/**
+	 * Definition of a DMUB_CMD__DPIA_SET_CONFIG_ACCESS command.
+	 */
+	struct dmub_rb_cmd_set_config_access set_config_access;
 	/**
 	 * Definition of a DMUB_CMD__EDID_CEA command.
 	 */
@@ -2505,6 +2566,10 @@ union dmub_rb_out_cmd {
 	 * HPD notify command.
 	 */
 	struct dmub_rb_cmd_dp_hpd_notify dp_hpd_notify;
+	/**
+	 * SET_CONFIG reply command.
+	 */
+	struct dmub_rb_cmd_dp_set_config_reply set_config_reply;
 };
 #pragma pack(pop)
 
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c
index d7f66e5285c0..44502ec919a2 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c
@@ -87,6 +87,11 @@ enum dmub_status dmub_srv_stat_get_notification(struct dmub_srv *dmub,
 		notify->link_index = cmd.dp_hpd_notify.hpd_data.instance;
 		notify->result = AUX_RET_SUCCESS;
 		break;
+	case DMUB_OUT_CMD__SET_CONFIG_REPLY:
+		notify->type = DMUB_NOTIFICATION_SET_CONFIG_REPLY;
+		notify->link_index = cmd.set_config_reply.set_config_reply_control.instance;
+		notify->sc_status = cmd.set_config_reply.set_config_reply_control.status;
+		break;
 	default:
 		notify->type = DMUB_NOTIFICATION_NO_DATA;
 		break;
-- 
2.25.1


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

* [PATCH 15/23] drm/amd/display: Read USB4 DP tunneling data from DPCD
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (13 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 14/23] drm/amd/display: Support for SET_CONFIG processing with DMUB Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 16/23] drm/amd/display: Add dpia debug options Wayne Lin
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
We requires information from DPCD in order to identify USB4 DP
tunneling targets.

[How]
Add USB4 DP tunneling fields to DPCD struct and populate these fields
during sink detection.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 29 +++++++++++++++--
 drivers/gpu/drm/amd/display/dc/dc.h           |  1 +
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  | 31 +++++++++++++++++++
 .../gpu/drm/amd/display/dc/inc/dc_link_dpia.h |  7 +++++
 4 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index a7fc60565bda..fb0d8b8a840a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -33,14 +33,39 @@
 #include "inc/link_dpcd.h"
 #include "dm_helpers.h"
 #include "dmub/inc/dmub_cmd.h"
+#include "inc/link_dpcd.h"
 
 #define DC_LOGGER \
 	link->ctx->logger
 
 enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link)
 {
-	/** @todo Read corresponding DPCD region and update link caps. */
-	return DC_OK;
+	enum dc_status status = DC_OK;
+	uint8_t dpcd_dp_tun_data[3] = {0};
+	uint8_t dpcd_topology_data[DPCD_USB4_TOPOLOGY_ID_LEN] = {0};
+	uint8_t i = 0;
+
+	status = core_link_read_dpcd(link,
+			DP_TUNNELING_CAPABILITIES_SUPPORT,
+			dpcd_dp_tun_data,
+			sizeof(dpcd_dp_tun_data));
+
+	status = core_link_read_dpcd(link,
+			DP_USB4_ROUTER_TOPOLOGY_ID,
+			dpcd_topology_data,
+			sizeof(dpcd_topology_data));
+
+	link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.raw =
+			dpcd_dp_tun_data[DP_TUNNELING_CAPABILITIES_SUPPORT - DP_TUNNELING_CAPABILITIES_SUPPORT];
+	link->dpcd_caps.usb4_dp_tun_info.dpia_info.raw =
+			dpcd_dp_tun_data[DP_IN_ADAPTER_INFO - DP_TUNNELING_CAPABILITIES_SUPPORT];
+	link->dpcd_caps.usb4_dp_tun_info.usb4_driver_id =
+			dpcd_dp_tun_data[DP_USB4_DRIVER_ID - DP_TUNNELING_CAPABILITIES_SUPPORT];
+
+	for (i = 0; i < DPCD_USB4_TOPOLOGY_ID_LEN; i++)
+		link->dpcd_caps.usb4_dp_tun_info.usb4_topology_id[i] = dpcd_topology_data[i];
+
+	return status;
 }
 
 /* Configure link as prescribed in link_setting; set LTTPR mode; and
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 082706c921af..c6b5d4535cb4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1187,6 +1187,7 @@ struct dpcd_caps {
 	struct dpcd_dsc_capabilities dsc_caps;
 	struct dc_lttpr_caps lttpr_caps;
 	struct psr_caps psr_caps;
+	struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info;
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
index a5e798b5da79..4f939578c739 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -859,6 +859,37 @@ struct psr_caps {
 	bool psr_exit_link_training_required;
 };
 
+/* Length of router topology ID read from DPCD in bytes. */
+#define DPCD_USB4_TOPOLOGY_ID_LEN 5
+
+/* DPCD[0xE000D] DP_TUNNELING_CAPABILITIES SUPPORT register. */
+union dp_tun_cap_support {
+	struct {
+		uint8_t dp_tunneling :1;
+		uint8_t rsvd :5;
+		uint8_t panel_replay_tun_opt :1;
+		uint8_t dpia_bw_alloc :1;
+	} bits;
+	uint8_t raw;
+};
+
+/* DPCD[0xE000E] DP_IN_ADAPTER_INFO register. */
+union dpia_info {
+	struct {
+		uint8_t dpia_num :5;
+		uint8_t rsvd :3;
+	} bits;
+	uint8_t raw;
+};
+
+/* DP Tunneling over USB4 */
+struct dpcd_usb4_dp_tunneling_info {
+	union dp_tun_cap_support dp_tun_cap;
+	union dpia_info dpia_info;
+	uint8_t usb4_driver_id;
+	uint8_t usb4_topology_id[DPCD_USB4_TOPOLOGY_ID_LEN];
+};
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 #define DP_MAIN_LINK_CHANNEL_CODING_CAP			0x006
 #define DP_SINK_VIDEO_FALLBACK_FORMATS			0x020
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
index 76b6b1e23575..790b904e37e1 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
@@ -34,6 +34,13 @@ struct dc_link_settings;
 /* The approximate time (us) it takes to transmit 9 USB4 DP clock sync packets. */
 #define DPIA_CLK_SYNC_DELAY 16000
 
+/** @note Can remove once DP tunneling registers in upstream include/drm/drm_dp_helper.h */
+/* DPCD DP Tunneling over USB4 */
+#define DP_TUNNELING_CAPABILITIES_SUPPORT 0xe000d
+#define DP_IN_ADAPTER_INFO                0xe000e
+#define DP_USB4_DRIVER_ID                 0xe000f
+#define DP_USB4_ROUTER_TOPOLOGY_ID        0xe001b
+
 /* SET_CONFIG message types sent by driver. */
 enum dpia_set_config_type {
 	DPIA_SET_CFG_SET_LINK = 0x01,
-- 
2.25.1


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

* [PATCH 16/23] drm/amd/display: Add dpia debug options
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (14 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 15/23] drm/amd/display: Read USB4 DP tunneling data from DPCD Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 17/23] drm/amd/display: Support for SET_CONFIG processing with DMUB Wayne Lin
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito,
	Wayne Lin

From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>

[Why & How]
To add support for dpia debug options.

Reviewed-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc.h                   | 9 +++++++++
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 3 ++-
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h           | 1 +
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h       | 3 +--
 drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c     | 1 +
 5 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index c6b5d4535cb4..e3f884942e04 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -496,6 +496,14 @@ union root_clock_optimization_options {
 	uint32_t u32All;
 };
 
+union dpia_debug_options {
+	struct {
+		uint32_t disable_dpia:1;
+		uint32_t reserved:31;
+	} bits;
+	uint32_t raw;
+};
+
 struct dc_debug_data {
 	uint32_t ltFailCount;
 	uint32_t i2cErrorCount;
@@ -668,6 +676,7 @@ struct dc_debug_options {
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	bool disable_z10;
 	bool enable_sw_cntl_psr;
+	union dpia_debug_options dpia_debug;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 2e021f9345c0..7cb7604a35eb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -2428,7 +2428,8 @@ static bool dcn31_resource_construct(
 	}
 
 	if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
-	    dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
+	    dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0 &&
+	    !dc->debug.dpia_debug.bits.disable_dpia) {
 		/* YELLOW CARP B0 has 4 DPIA's */
 		pool->base.usb4_dpia_count = 4;
 	}
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index 7a86c97af910..365fbc4758e1 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -237,6 +237,7 @@ struct dmub_srv_hw_params {
 	bool load_inst_const;
 	bool skip_panel_power_sequence;
 	bool disable_z10;
+	bool disable_dpia;
 };
 
 /**
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 4c61e73ceccd..b37a485fcba5 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -369,8 +369,7 @@ union dmub_fw_boot_options {
 		uint32_t disable_clk_gate: 1; /**< 1 if clock gating should be disabled */
 		uint32_t skip_phy_init_panel_sequence: 1; /**< 1 to skip panel init seq */
 		uint32_t z10_disable: 1; /**< 1 to disable z10 */
-		uint32_t reserved2: 1; /**< reserved for an unreleased feature */
-		uint32_t reserved_unreleased1: 1; /**< reserved for an unreleased feature */
+		uint32_t enable_dpia: 1; /**< 1 if DPIA should be enabled */
 		uint32_t invalid_vbios_data: 1; /**< 1 if VBIOS data table is invalid */
 		uint32_t reserved_unreleased2: 1; /**< reserved for an unreleased feature */
 		uint32_t reserved : 22; /**< reserved */
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
index 6ac370c15dea..3988f65f1ea4 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
@@ -338,6 +338,7 @@ void dmub_dcn31_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmu
 	union dmub_fw_boot_options boot_options = {0};
 
 	boot_options.bits.z10_disable = params->disable_z10;
+	boot_options.bits.enable_dpia = params->disable_dpia ? 0 : 1;
 
 	REG_WRITE(DMCUB_SCRATCH14, boot_options.all);
 }
-- 
2.25.1


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

* [PATCH 17/23] drm/amd/display: Support for SET_CONFIG processing with DMUB
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (15 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 16/23] drm/amd/display: Add dpia debug options Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 18/23] drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints Wayne Lin
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jude Shih,
	Nicholas Kazlauskas, Wayne Lin

From: Jude Shih <shenshih@amd.com>

[Why]
To process SET_CONFIG transactions with DMUB using inbox1 and
outbox1 mail boxes.

[How]
1) DMUB posts SET_CONFIG reply as an Outbox1 message of type
   DMUB_OUT_CMD__SET_CONFIG_REPLY.
2) The dmub async to sync mechanism for AUX is modified to accommodate
   SET_CONFIG commands for both command issue and reply code paths.

Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Signed-off-by: Jude Shih <shenshih@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 +++++++++++++++----
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 17 ++++-
 .../gpu/drm/amd/display/dc/core/dc_link_ddc.c |  6 +-
 .../drm/amd/display/dc/core/dc_link_dpia.c    |  6 ++
 5 files changed, 94 insertions(+), 20 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 3c7a8f869b40..41692ae30822 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -11333,29 +11333,74 @@ uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address,
 	return value;
 }
 
-int amdgpu_dm_process_dmub_aux_transfer_sync(struct dc_context *ctx, unsigned int linkIndex,
-				struct aux_payload *payload, enum aux_return_code_type *operation_result)
+int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, struct dc_context *ctx, uint8_t status_type,
+	uint32_t *operation_result)
+{
+	struct amdgpu_device *adev = ctx->driver_context;
+	int return_status = -1;
+	struct dmub_notification *p_notify = adev->dm.dmub_notify;
+
+	if (is_cmd_aux) {
+		if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS) {
+			return_status = p_notify->aux_reply.length;
+			*operation_result = p_notify->result;
+		} else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT) {
+			*operation_result = AUX_RET_ERROR_TIMEOUT;
+		} else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL) {
+			*operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE;
+		} else {
+			*operation_result = AUX_RET_ERROR_UNKNOWN;
+		}
+	} else {
+		if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS) {
+			return_status = 0;
+			*operation_result = p_notify->sc_status;
+		} else {
+			*operation_result = SET_CONFIG_UNKNOWN_ERROR;
+		}
+	}
+
+	return return_status;
+}
+
+int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context *ctx, unsigned int link_index,
+						void *cmd_payload, void *operation_result)
 {
 	struct amdgpu_device *adev = ctx->driver_context;
 	int ret = 0;
 
-	dc_process_dmub_aux_transfer_async(ctx->dc, linkIndex, payload);
+	if (is_cmd_aux) {
+		dc_process_dmub_aux_transfer_async(ctx->dc,
+			link_index, (struct aux_payload *)cmd_payload);
+	} else if (dc_process_dmub_set_config_async(ctx->dc, link_index,
+					(struct set_config_cmd_payload *)cmd_payload,
+					adev->dm.dmub_notify)) {
+		return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
+					ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS,
+					(uint32_t *)operation_result);
+	}
+
 	ret = wait_for_completion_interruptible_timeout(&adev->dm.dmub_aux_transfer_done, 10*HZ);
 	if (ret == 0) {
-		*operation_result = AUX_RET_ERROR_TIMEOUT;
-		return -1;
+		return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
+				ctx, DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT,
+				(uint32_t *)operation_result);
 	}
-	*operation_result = (enum aux_return_code_type)adev->dm.dmub_notify->result;
 
-	if (adev->dm.dmub_notify->result == AUX_RET_SUCCESS) {
-		(*payload->reply) = adev->dm.dmub_notify->aux_reply.command;
+	if (is_cmd_aux) {
+		if (adev->dm.dmub_notify->result == AUX_RET_SUCCESS) {
+			struct aux_payload *payload = (struct aux_payload *)cmd_payload;
 
-		// For read case, Copy data to payload
-		if (!payload->write && adev->dm.dmub_notify->aux_reply.length &&
-		(*payload->reply == AUX_TRANSACTION_REPLY_AUX_ACK))
-			memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data,
-			adev->dm.dmub_notify->aux_reply.length);
+			payload->reply[0] = adev->dm.dmub_notify->aux_reply.command;
+			if (!payload->write && adev->dm.dmub_notify->aux_reply.length &&
+			    payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK) {
+				memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data,
+				       adev->dm.dmub_notify->aux_reply.length);
+			}
+		}
 	}
 
-	return adev->dm.dmub_notify->aux_reply.length;
+	return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
+			ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS,
+			(uint32_t *)operation_result);
 }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index a85b09986aab..37e61a88d49e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -49,6 +49,13 @@
 #define AMDGPU_DM_MAX_NUM_EDP 2
 
 #define AMDGPU_DMUB_NOTIFICATION_MAX 5
+
+/**
+ * DMUB Async to Sync Mechanism Status
+ **/
+#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
+#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
+#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
 /*
 #include "include/amdgpu_dal_power_if.h"
 #include "amdgpu_dm_irq.h"
@@ -721,6 +728,7 @@ void amdgpu_dm_update_connector_after_detect(
 
 extern const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs;
 
-int amdgpu_dm_process_dmub_aux_transfer_sync(struct dc_context *ctx, unsigned int linkIndex,
-					struct aux_payload *payload, enum aux_return_code_type *operation_result);
+int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux,
+					struct dc_context *ctx, unsigned int link_index,
+					void *payload, void *operation_result);
 #endif /* __AMDGPU_DM_H__ */
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 1aa69dd8e02f..ff0f91c93ba4 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
@@ -683,8 +683,21 @@ int dm_helper_dmub_aux_transfer_sync(
 		struct aux_payload *payload,
 		enum aux_return_code_type *operation_result)
 {
-	return amdgpu_dm_process_dmub_aux_transfer_sync(ctx, link->link_index, payload, operation_result);
+	return amdgpu_dm_process_dmub_aux_transfer_sync(true, ctx,
+			link->link_index, (void *)payload,
+			(void *)operation_result);
 }
+
+int dm_helpers_dmub_set_config_sync(struct dc_context *ctx,
+		const struct dc_link *link,
+		struct set_config_cmd_payload *payload,
+		enum set_config_status *operation_result)
+{
+	return amdgpu_dm_process_dmub_aux_transfer_sync(false, ctx,
+			link->link_index, (void *)payload,
+			(void *)operation_result);
+}
+
 void dm_set_dcn_clocks(struct dc_context *ctx, struct dc_clocks *clks)
 {
 	/* TODO: something */
@@ -799,4 +812,4 @@ void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable)
 {
 	/* TODO: add peridic detection implementation */
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
index dd6c473be072..b0f1cd7268c8 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
@@ -659,10 +659,12 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc,
 		struct aux_payload *payload,
 		enum aux_return_code_type *operation_result)
 {
-	if (dc_enable_dmub_notifications(ddc->ctx->dc))
+	if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc ||
+	    !ddc->ddc_pin) {
 		return dce_aux_transfer_dmub_raw(ddc, payload, operation_result);
-	else
+	} else {
 		return dce_aux_transfer_raw(ddc, payload, operation_result);
+	}
 }
 
 /* dc_link_aux_transfer_with_retries() - Attempt to submit an
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index fb0d8b8a840a..7407c755a73e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -128,6 +128,12 @@ static enum dc_status core_link_send_set_config(struct dc_link *link,
 	payload.msg_type = msg_type;
 	payload.msg_data = msg_data;
 
+	if (!link->ddc->ddc_pin && !link->aux_access_disabled &&
+	    (dm_helpers_dmub_set_config_sync(link->ctx, link,
+					     &payload, &set_config_result) == -1)) {
+		return DC_ERROR_UNEXPECTED;
+	}
+
 	/* set_config should return ACK if successful */
 	return (set_config_result == SET_CONFIG_ACK_RECEIVED) ? DC_OK : DC_ERROR_UNEXPECTED;
 }
-- 
2.25.1


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

* [PATCH 18/23] drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (16 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 17/23] drm/amd/display: Support for SET_CONFIG processing with DMUB Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 19/23] drm/amd/display: Add debug flags for USB4 DP link training Wayne Lin
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
DIB_BE_CNTL<i>.DIG_HPD_SELECT selects the HPD block being used
by the display endpoint assigned to DIG<i>. In the case of USB4
display endpoints, no physical HPD block is assigned.

[How]
Setting DIB_BE_CNTL<i>.DIG_HPD_SELECT to 5 indicates that no HPD
is assigned to a display endpoint. Firmware decrements the
HPD_SELECT value by 1 before writing it to the register.

Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 .../amd/display/dc/dcn31/dcn31_dio_link_encoder.c    | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
index a5266d5999d7..8f8eee475144 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
@@ -388,7 +388,7 @@ static bool link_dpia_control(struct dc_context *dc_ctx,
 	dc_dmub_srv_cmd_execute(dmub);
 	dc_dmub_srv_wait_idle(dmub);
 
-	return false;
+	return true;
 }
 
 static void link_encoder_disable(struct dcn10_link_encoder *enc10)
@@ -424,7 +424,10 @@ void dcn31_link_encoder_enable_dp_output(
 		dpia_control.lanenum = (uint8_t)link_settings->lane_count;
 		dpia_control.symclk_10khz = link_settings->link_rate *
 				LINK_RATE_REF_FREQ_IN_KHZ / 10;
-		dpia_control.hpdsel = 5; /* Unused by DPIA */
+		/* DIG_BE_CNTL.DIG_HPD_SELECT set to 5 (hpdsel - 1) to indicate HPD pin
+		 * unused by DPIA.
+		 */
+		dpia_control.hpdsel = 6;
 
 		if (link) {
 			dpia_control.dpia_id = link->ddc_hw_inst;
@@ -466,7 +469,10 @@ void dcn31_link_encoder_enable_dp_mst_output(
 		dpia_control.lanenum = (uint8_t)link_settings->lane_count;
 		dpia_control.symclk_10khz = link_settings->link_rate *
 				LINK_RATE_REF_FREQ_IN_KHZ / 10;
-		dpia_control.hpdsel = 5; /* Unused by DPIA */
+		/* DIG_BE_CNTL.DIG_HPD_SELECT set to 5 (hpdsel - 1) to indicate HPD pin
+		 * unused by DPIA.
+		 */
+		dpia_control.hpdsel = 6;
 
 		if (link) {
 			dpia_control.dpia_id = link->ddc_hw_inst;
-- 
2.25.1


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

* [PATCH 19/23] drm/amd/display: Add debug flags for USB4 DP link training
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (17 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 18/23] drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 20/23] drm/amd/display: Fix for access for ddc pin and aux engine Wayne Lin
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito, Jun Lei,
	Wayne Lin

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why & How]
Additional debug flags that can be useful for testing USB4 DP
link training.

Add flags:
- 0x2 : Forces USB4 DP link to non-LTTPR mode
- 0x4 : Extends status read intervals to about 60s.

Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   | 6 ++++++
 drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c | 6 ++++++
 drivers/gpu/drm/amd/display/dc/dc.h                | 4 +++-
 drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h  | 3 +++
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index bfba1d2c6a18..423fbd2b9b39 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -4528,6 +4528,12 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
 		else
 			link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
 	}
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	/* Check DP tunnel LTTPR mode debug option. */
+	if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
+	    link->dc->debug.dpia_debug.bits.force_non_lttpr)
+		link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
+#endif
 
 	if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT || link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
 		/* By reading LTTPR capability, RX assumes that we will enable
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index 7407c755a73e..ce15a38c2aea 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -528,6 +528,12 @@ static uint32_t dpia_get_eq_aux_rd_interval(const struct dc_link *link,
 				dp_translate_training_aux_read_interval(
 					link->dpcd_caps.lttpr_caps.aux_rd_interval[hop - 1]);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	/* Check debug option for extending aux read interval. */
+	if (link->dc->debug.dpia_debug.bits.extend_aux_rd_interval)
+		wait_time_microsec = DPIA_DEBUG_EXTENDED_AUX_RD_INTERVAL_US;
+#endif
+
 	return wait_time_microsec;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index e3f884942e04..86fa94a2ef48 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -499,7 +499,9 @@ union root_clock_optimization_options {
 union dpia_debug_options {
 	struct {
 		uint32_t disable_dpia:1;
-		uint32_t reserved:31;
+		uint32_t force_non_lttpr:1;
+		uint32_t extend_aux_rd_interval:1;
+		uint32_t reserved:29;
 	} bits;
 	uint32_t raw;
 };
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
index 790b904e37e1..e3dfe4c89ce0 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
@@ -34,6 +34,9 @@ struct dc_link_settings;
 /* The approximate time (us) it takes to transmit 9 USB4 DP clock sync packets. */
 #define DPIA_CLK_SYNC_DELAY 16000
 
+/* Extend interval between training status checks for manual testing. */
+#define DPIA_DEBUG_EXTENDED_AUX_RD_INTERVAL_US 60000000
+
 /** @note Can remove once DP tunneling registers in upstream include/drm/drm_dp_helper.h */
 /* DPCD DP Tunneling over USB4 */
 #define DP_TUNNELING_CAPABILITIES_SUPPORT 0xe000d
-- 
2.25.1


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

* [PATCH 20/23] drm/amd/display: Fix for access for ddc pin and aux engine
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (18 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 19/23] drm/amd/display: Add debug flags for USB4 DP link training Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 21/23] drm/amd/display: Deadlock/HPD Status/Crash Bug Fix Wayne Lin
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jimmy Kizito,
	Wayne Lin

From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>

[Why & How]
Add codes for commit "b693dfe24d61 drm/amd/display: Fix for null
pointer access for ddc pin and aux engine" to take USB4 feature
into account.

Reviewed-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Acked-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c      | 6 +++---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c | 6 +++---
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c       | 3 +++
 drivers/gpu/drm/amd/display/dc/irq_types.h         | 5 +----
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 6b5ddf0a29c1..ca5dc3c168ec 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1709,9 +1709,9 @@ static bool dc_link_construct_dpia(struct dc_link *link,
 
 	DC_LOGGER_INIT(dc_ctx->logger);
 
-	/* Initialized dummy hpd and hpd rx */
-	link->irq_source_hpd = DC_IRQ_SOURCE_USB4_DMUB_HPD;
-	link->irq_source_hpd_rx = DC_IRQ_SOURCE_USB4_DMUB_HPDRX;
+	/* Initialized irq source for hpd and hpd rx */
+	link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
+	link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
 	link->link_status.dpcd_caps = &link->dpcd_caps;
 
 	link->dc = init_params->dc;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index ce15a38c2aea..b8b1fa0d4ae3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -230,7 +230,7 @@ static enum dc_status dpcd_set_lt_pattern(struct dc_link *link,
 	}
 
 	status = core_link_write_dpcd(link,
-				      DP_TRAINING_PATTERN_SET,
+				      dpcd_tps_offset,
 				      &dpcd_pattern.raw,
 				      sizeof(dpcd_pattern.raw));
 
@@ -788,7 +788,7 @@ static enum dc_status dpcd_clear_lt_pattern(struct dc_link *link, uint32_t hop)
 			((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (hop - 1));
 
 	status = core_link_write_dpcd(link,
-			DP_TRAINING_PATTERN_SET,
+			dpcd_tps_offset,
 			&dpcd_pattern.raw,
 			sizeof(dpcd_pattern.raw));
 
@@ -898,7 +898,7 @@ enum link_training_result dc_link_dpia_perform_link_training(struct dc_link *lin
 	enum link_training_result result;
 	struct link_training_settings lt_settings;
 	uint8_t repeater_cnt = 0; /* Number of hops/repeaters in display path. */
-	uint8_t repeater_id; /* Current hop. */
+	int8_t repeater_id; /* Current hop. */
 
 	/* Configure link as prescribed in link_setting and set LTTPR mode. */
 	result = dpia_configure_link(link, link_setting, &lt_settings);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
index 5666543f095b..95cb4d7cc76a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -627,6 +627,7 @@ int dce_aux_transfer_dmub_raw(struct ddc_service *ddc,
 #define AUX_MAX_I2C_DEFER_RETRIES 7
 #define AUX_MAX_INVALID_REPLY_RETRIES 2
 #define AUX_MAX_TIMEOUT_RETRIES 3
+#define AUX_DEFER_DELAY_FOR_DPIA 4 /*ms*/
 
 static void dce_aux_log_payload(const char *payload_name,
 	unsigned char *payload, uint32_t length, uint32_t max_length_to_log)
@@ -772,6 +773,8 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
 				/* polling_timeout_period is in us */
 				if (aux110)
 					defer_time_in_ms += aux110->polling_timeout_period / 1000;
+				else
+					defer_time_in_ms += AUX_DEFER_DELAY_FOR_DPIA;
 				++aux_defer_retries;
 				fallthrough;
 			case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h
index 7a9f667d5edb..530c2578db40 100644
--- a/drivers/gpu/drm/amd/display/dc/irq_types.h
+++ b/drivers/gpu/drm/amd/display/dc/irq_types.h
@@ -153,10 +153,7 @@ enum dc_irq_source {
 	DC_IRQ_SOURCE_DMCUB_OUTBOX,
 	DC_IRQ_SOURCE_DMCUB_OUTBOX0,
 	DC_IRQ_SOURCE_DMCUB_GENERAL_DATAOUT,
-	DAL_IRQ_SOURCES_NUMBER,
-	/* Dummy interrupt source for USB4 HPD & HPD RX */
-	DC_IRQ_SOURCE_USB4_DMUB_HPD,
-	DC_IRQ_SOURCE_USB4_DMUB_HPDRX,
+	DAL_IRQ_SOURCES_NUMBER
 };
 
 enum irq_type
-- 
2.25.1


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

* [PATCH 21/23] drm/amd/display: Deadlock/HPD Status/Crash Bug Fix
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (19 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 20/23] drm/amd/display: Fix for access for ddc pin and aux engine Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 22/23] drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly Wayne Lin
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jude Shih, Wayne Lin

From: Jude Shih <shenshih@amd.com>

[why]
1. HPD callback function has deadlock problem
2. HPD status is not assigned
3. There is crash due to null pointer
4. link_enc is NULL in DPIA case

[How]
1. Fix deadlock problem by moving it out of the
   drm_modeset_lock
2. Assign HPD status from the notify of outbox
   from dmub FW
3. Fix the crash by checking if pin or enc exists
4. Use link_enc_cfg_get_link_enc_used_by_link to
   dynamically assign

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Signed-off-by: Jude Shih <shenshih@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 +++++++++++++++----
 1 file changed, 24 insertions(+), 6 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 41692ae30822..cbf83a6e56b9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -29,6 +29,7 @@
 #include "dm_services_types.h"
 #include "dc.h"
 #include "dc_link_dp.h"
+#include "link_enc_cfg.h"
 #include "dc/inc/core_types.h"
 #include "dal_asic_id.h"
 #include "dmub/dmub_srv.h"
@@ -648,6 +649,7 @@ void dmub_aux_setconfig_callback(struct amdgpu_device *adev, struct dmub_notific
 void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *notify)
 {
 	struct amdgpu_dm_connector *aconnector;
+	struct amdgpu_dm_connector *hpd_aconnector = NULL;
 	struct drm_connector *connector;
 	struct drm_connector_list_iter iter;
 	struct dc_link *link;
@@ -678,13 +680,15 @@ void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *not
 		aconnector = to_amdgpu_dm_connector(connector);
 		if (link && aconnector->dc_link == link) {
 			DRM_INFO("DMUB HPD callback: link_index=%u\n", link_index);
-			handle_hpd_irq_helper(aconnector);
+			hpd_aconnector = aconnector;
 			break;
 		}
 	}
 	drm_connector_list_iter_end(&iter);
 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
 
+	if (hpd_aconnector)
+		handle_hpd_irq_helper(hpd_aconnector);
 }
 
 /**
@@ -747,7 +751,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
 	struct dmcub_trace_buf_entry entry = { 0 };
 	uint32_t count = 0;
 	struct dmub_hpd_work *dmub_hpd_wrk;
-
+	struct dc_link *plink = NULL;
 	if (dc_enable_dmub_notifications(adev->dm.dc)) {
 		dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC);
 		if (!dmub_hpd_wrk) {
@@ -767,6 +771,11 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
 				if (dm->dmub_thread_offload[notify.type] == true) {
 					dmub_hpd_wrk->dmub_notify = &notify;
 					dmub_hpd_wrk->adev = adev;
+					if (notify.type == DMUB_NOTIFICATION_HPD) {
+						plink = adev->dm.dc->links[notify.link_index];
+						if (plink)
+							plink->hpd_status = notify.hpd_status == DP_HPD_PLUG ? true : false;
+					}
 					queue_work(adev->dm.delayed_hpd_wq, &dmub_hpd_wrk->handle_hpd_work);
 				} else {
 					dm->dmub_callback[notify.type](adev, &notify);
@@ -794,7 +803,8 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
 
 	} while (count <= DMUB_TRACE_MAX_READ);
 
-	ASSERT(count <= DMUB_TRACE_MAX_READ);
+	if (count > DMUB_TRACE_MAX_READ)
+		DRM_DEBUG_DRIVER("Warning : count > DMUB_TRACE_MAX_READ");
 }
 #endif
 
@@ -2913,7 +2923,6 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector)
 	if (aconnector->base.force && new_connection_type == dc_connection_none) {
 		emulated_link_detect(aconnector->dc_link);
 
-
 		drm_modeset_lock_all(dev);
 		dm_restore_drm_connector_state(dev, connector);
 		drm_modeset_unlock_all(dev);
@@ -8101,7 +8110,15 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 		break;
 	case DRM_MODE_CONNECTOR_DisplayPort:
 		aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
-		aconnector->base.ycbcr_420_allowed =
+		if (link->is_dig_mapping_flexible &&
+		    link->dc->res_pool->funcs->link_encs_assign) {
+			link->link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
+			if (!link->link_enc)
+				link->link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
+		}
+
+		if (link->link_enc)
+			aconnector->base.ycbcr_420_allowed =
 			link->link_enc->features.dp_ycbcr420_supported ? true : false;
 		break;
 	case DRM_MODE_CONNECTOR_DVID:
@@ -8216,7 +8233,8 @@ create_i2c(struct ddc_service *ddc_service,
 	snprintf(i2c->base.name, sizeof(i2c->base.name), "AMDGPU DM i2c hw bus %d", link_index);
 	i2c_set_adapdata(&i2c->base, i2c);
 	i2c->ddc_service = ddc_service;
-	i2c->ddc_service->ddc_pin->hw_info.ddc_channel = link_index;
+	if (i2c->ddc_service->ddc_pin)
+		i2c->ddc_service->ddc_pin->hw_info.ddc_channel = link_index;
 
 	return i2c;
 }
-- 
2.25.1


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

* [PATCH 22/23] drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (20 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 21/23] drm/amd/display: Deadlock/HPD Status/Crash Bug Fix Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:40 ` [PATCH 23/23] drm/amd/display: USB4 bring up set correct address Wayne Lin
  2021-10-04 14:48 ` [PATCH 00/23] USB4 DP tunneling Harry Wentland
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jude Shih, Wayne Lin

From: Jude Shih <shenshih@amd.com>

[Why]
Condition variable sometimes terminated unexpectedly

[How]
Use wait_for_completion_timeout to avoid unexpected termination of CV

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Signed-off-by: Jude Shih <shenshih@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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 cbf83a6e56b9..2962123b5f7e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -11398,8 +11398,9 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context
 					(uint32_t *)operation_result);
 	}
 
-	ret = wait_for_completion_interruptible_timeout(&adev->dm.dmub_aux_transfer_done, 10*HZ);
+	ret = wait_for_completion_timeout(&adev->dm.dmub_aux_transfer_done, 10 * HZ);
 	if (ret == 0) {
+		DRM_ERROR("wait_for_completion_timeout timeout!");
 		return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux,
 				ctx, DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT,
 				(uint32_t *)operation_result);
-- 
2.25.1


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

* [PATCH 23/23] drm/amd/display: USB4 bring up set correct address
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (21 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 22/23] drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly Wayne Lin
@ 2021-10-04 14:40 ` Wayne Lin
  2021-10-04 14:48 ` [PATCH 00/23] USB4 DP tunneling Harry Wentland
  23 siblings, 0 replies; 26+ messages in thread
From: Wayne Lin @ 2021-10-04 14:40 UTC (permalink / raw)
  To: amd-gfx
  Cc: alexander.deucher, Harry.Wentland, nicholas.kazlauskas,
	Rodrigo.Siqueira, wayne.lin, stylon.wang, jude.shih,
	jimmy.kizito, meenakshikumar.somasundaram, Jude Shih, Wayne Lin

From: Jude Shih <shenshih@amd.com>

[Why]
YELLOW_CARP_B0 address was not correct

[How]
Set YELLOW_CARP_B0 to 0x1A.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: Wayne Lin <Wayne.Lin@amd.com>
Signed-off-by: Jude Shih <shenshih@amd.com>
---
 drivers/gpu/drm/amd/display/include/dal_asic_id.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
index e4a2dfacab4c..a9974f12f7fb 100644
--- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h
+++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
@@ -228,7 +228,7 @@ enum {
 #define FAMILY_YELLOW_CARP                     146
 
 #define YELLOW_CARP_A0 0x01
-#define YELLOW_CARP_B0 0x20
+#define YELLOW_CARP_B0 0x1A
 #define YELLOW_CARP_UNKNOWN 0xFF
 
 #ifndef ASICREV_IS_YELLOW_CARP
-- 
2.25.1


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

* Re: [PATCH 00/23] USB4 DP tunneling
  2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
                   ` (22 preceding siblings ...)
  2021-10-04 14:40 ` [PATCH 23/23] drm/amd/display: USB4 bring up set correct address Wayne Lin
@ 2021-10-04 14:48 ` Harry Wentland
  2021-10-05  6:30   ` Lin, Wayne
  23 siblings, 1 reply; 26+ messages in thread
From: Harry Wentland @ 2021-10-04 14:48 UTC (permalink / raw)
  To: Wayne Lin, amd-gfx
  Cc: alexander.deucher, nicholas.kazlauskas, Rodrigo.Siqueira,
	stylon.wang, jude.shih, jimmy.kizito,
	meenakshikumar.somasundaram



On 2021-10-04 10:40, Wayne Lin wrote:
> These series patches are for supporting USB4 DP tunneling feature.
> 

Can you provide a description (with or without diagrams) of what
DP4 tunneling is and some of the key parts of how it works?

Does this patchset have dependencies on patches in the USB
subsystem?

Harry

> ---
> 
> Jimmy Kizito (14):
>   drm/amd/display: Update link encoder object creation.
>   drm/amd/display: Support USB4 dynamic link encoder selection.
>   drm/amd/display: Support USB4 for display endpoint control path.
>   drm/amd/display: Support DP tunneling when DPRX detection
>   drm/amd/display: Update training parameters for DPIA links
>   drm/amd/display: Support USB4 when DP link training.
>   drm/amd/display: Implement DPIA training loop
>   drm/amd/display: Implement DPIA link configuration
>   drm/amd/display: Implement DPIA clock recovery phase
>   drm/amd/display: Implement DPIA equalisation phase
>   drm/amd/display: Implement end of training for hop in DPIA display
>     path
>   drm/amd/display: Read USB4 DP tunneling data from DPCD.
>   drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints.
>   drm/amd/display: Add debug flags for USB4 DP link training.
> 
> Jude Shih (4):
>   drm/amd/display: Support for SET_CONFIG processing with DMUB
>   drm/amd/display: Deadlock/HPD Status/Crash Bug Fix
>   drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly
>   drm/amd/display: USB4 bring up set correct address
> 
> Meenakshikumar Somasundaram (5):
>   drm/amd/display: USB4 DPIA enumeration and AUX Tunneling
>   drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling
>   drm/amd/display: Support for SET_CONFIG processing with DMUB
>   drm/amd/display: Add dpia debug options
>   drm/amd/display: Fix for access for ddc pin and aux engine.
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 106 +-
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  12 +-
>  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  17 +-
>  drivers/gpu/drm/amd/display/dc/Makefile       |   2 +-
>  drivers/gpu/drm/amd/display/dc/core/dc.c      | 179 +++-
>  drivers/gpu/drm/amd/display/dc/core/dc_link.c |  81 +-
>  .../gpu/drm/amd/display/dc/core/dc_link_ddc.c |   9 +-
>  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  36 +-
>  .../drm/amd/display/dc/core/dc_link_dpia.c    | 945 ++++++++++++++++++
>  drivers/gpu/drm/amd/display/dc/core/dc_stat.c |   8 +
>  drivers/gpu/drm/amd/display/dc/dc.h           |  22 +
>  drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |  31 +
>  drivers/gpu/drm/amd/display/dc/dc_types.h     |   1 +
>  drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  |   3 +
>  .../display/dc/dcn31/dcn31_dio_link_encoder.c | 126 ++-
>  .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   6 +
>  .../drm/amd/display/dc/dcn31/dcn31_resource.c |   7 +
>  drivers/gpu/drm/amd/display/dc/dm_helpers.h   |   5 +
>  .../gpu/drm/amd/display/dc/inc/core_types.h   |   3 +
>  .../gpu/drm/amd/display/dc/inc/dc_link_ddc.h  |   1 +
>  .../gpu/drm/amd/display/dc/inc/dc_link_dpia.h |  98 ++
>  drivers/gpu/drm/amd/display/dc/inc/resource.h |   1 +
>  drivers/gpu/drm/amd/display/dc/os_types.h     |   1 +
>  drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |   3 +
>  .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 113 ++-
>  .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c |   1 +
>  .../drm/amd/display/dmub/src/dmub_srv_stat.c  |  16 +
>  .../gpu/drm/amd/display/include/dal_asic_id.h |   2 +-
>  28 files changed, 1793 insertions(+), 42 deletions(-)
>  create mode 100644 drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
>  create mode 100644 drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
> 


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

* RE: [PATCH 00/23] USB4 DP tunneling
  2021-10-04 14:48 ` [PATCH 00/23] USB4 DP tunneling Harry Wentland
@ 2021-10-05  6:30   ` Lin, Wayne
  0 siblings, 0 replies; 26+ messages in thread
From: Lin, Wayne @ 2021-10-05  6:30 UTC (permalink / raw)
  To: Wentland, Harry, amd-gfx
  Cc: Deucher, Alexander, Kazlauskas, Nicholas, Siqueira, Rodrigo,
	Wang, Chao-kai (Stylon),
	Shih, Jude, Kizito, Jimmy, Somasundaram, Meenakshikumar

[Public]

> -----Original Message-----
> From: Wentland, Harry <Harry.Wentland@amd.com>
> Sent: Monday, October 4, 2021 10:48 PM
> To: Lin, Wayne <Wayne.Lin@amd.com>; amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Kazlauskas, Nicholas <Nicholas.Kazlauskas@amd.com>; Siqueira, Rodrigo
> <Rodrigo.Siqueira@amd.com>; Wang, Chao-kai (Stylon) <Stylon.Wang@amd.com>; Shih, Jude <Jude.Shih@amd.com>; Kizito, Jimmy
> <Jimmy.Kizito@amd.com>; Somasundaram, Meenakshikumar <Meenakshikumar.Somasundaram@amd.com>
> Subject: Re: [PATCH 00/23] USB4 DP tunneling
>
>
>
> On 2021-10-04 10:40, Wayne Lin wrote:
> > These series patches are for supporting USB4 DP tunneling feature.
> >
>
> Can you provide a description (with or without diagrams) of what
> DP4 tunneling is and some of the key parts of how it works?
Thanks Harry, will give a short description about USB4 DP tunneling.

>
> Does this patchset have dependencies on patches in the USB subsystem?
AFAIK, USB4 relevant patches are already in the USB subsystem. Should have
no dependencies here.

Thanks!
>
> Harry
>
> > ---
> >
> > Jimmy Kizito (14):
> >   drm/amd/display: Update link encoder object creation.
> >   drm/amd/display: Support USB4 dynamic link encoder selection.
> >   drm/amd/display: Support USB4 for display endpoint control path.
> >   drm/amd/display: Support DP tunneling when DPRX detection
> >   drm/amd/display: Update training parameters for DPIA links
> >   drm/amd/display: Support USB4 when DP link training.
> >   drm/amd/display: Implement DPIA training loop
> >   drm/amd/display: Implement DPIA link configuration
> >   drm/amd/display: Implement DPIA clock recovery phase
> >   drm/amd/display: Implement DPIA equalisation phase
> >   drm/amd/display: Implement end of training for hop in DPIA display
> >     path
> >   drm/amd/display: Read USB4 DP tunneling data from DPCD.
> >   drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints.
> >   drm/amd/display: Add debug flags for USB4 DP link training.
> >
> > Jude Shih (4):
> >   drm/amd/display: Support for SET_CONFIG processing with DMUB
> >   drm/amd/display: Deadlock/HPD Status/Crash Bug Fix
> >   drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly
> >   drm/amd/display: USB4 bring up set correct address
> >
> > Meenakshikumar Somasundaram (5):
> >   drm/amd/display: USB4 DPIA enumeration and AUX Tunneling
> >   drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling
> >   drm/amd/display: Support for SET_CONFIG processing with DMUB
> >   drm/amd/display: Add dpia debug options
> >   drm/amd/display: Fix for access for ddc pin and aux engine.
> >
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 106 +-
> > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  12 +-
> > .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  17 +-
> >  drivers/gpu/drm/amd/display/dc/Makefile       |   2 +-
> >  drivers/gpu/drm/amd/display/dc/core/dc.c      | 179 +++-
> >  drivers/gpu/drm/amd/display/dc/core/dc_link.c |  81 +-
> >  .../gpu/drm/amd/display/dc/core/dc_link_ddc.c |   9 +-
> >  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  36 +-
> >  .../drm/amd/display/dc/core/dc_link_dpia.c    | 945 ++++++++++++++++++
> >  drivers/gpu/drm/amd/display/dc/core/dc_stat.c |   8 +
> >  drivers/gpu/drm/amd/display/dc/dc.h           |  22 +
> >  drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |  31 +
> >  drivers/gpu/drm/amd/display/dc/dc_types.h     |   1 +
> >  drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  |   3 +
> >  .../display/dc/dcn31/dcn31_dio_link_encoder.c | 126 ++-
> >  .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   6 +
> >  .../drm/amd/display/dc/dcn31/dcn31_resource.c |   7 +
> >  drivers/gpu/drm/amd/display/dc/dm_helpers.h   |   5 +
> >  .../gpu/drm/amd/display/dc/inc/core_types.h   |   3 +
> >  .../gpu/drm/amd/display/dc/inc/dc_link_ddc.h  |   1 +
> >  .../gpu/drm/amd/display/dc/inc/dc_link_dpia.h |  98 ++
> >  drivers/gpu/drm/amd/display/dc/inc/resource.h |   1 +
> >  drivers/gpu/drm/amd/display/dc/os_types.h     |   1 +
> >  drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |   3 +
> >  .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 113 ++-
> >  .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c |   1 +
> >  .../drm/amd/display/dmub/src/dmub_srv_stat.c  |  16 +
> >  .../gpu/drm/amd/display/include/dal_asic_id.h |   2 +-
> >  28 files changed, 1793 insertions(+), 42 deletions(-)  create mode
> > 100644 drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
> >  create mode 100644 drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h
> >
--
Regards,
Wayne

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

end of thread, other threads:[~2021-10-05  6:30 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-04 14:40 [PATCH 00/23] USB4 DP tunneling Wayne Lin
2021-10-04 14:40 ` [PATCH 01/23] drm/amd/display: Update link encoder object creation Wayne Lin
2021-10-04 14:40 ` [PATCH 02/23] drm/amd/display: USB4 DPIA enumeration and AUX Tunneling Wayne Lin
2021-10-04 14:40 ` [PATCH 03/23] drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling Wayne Lin
2021-10-04 14:40 ` [PATCH 04/23] drm/amd/display: Support USB4 dynamic link encoder selection Wayne Lin
2021-10-04 14:40 ` [PATCH 05/23] drm/amd/display: Support USB4 for display endpoint control path Wayne Lin
2021-10-04 14:40 ` [PATCH 06/23] drm/amd/display: Support DP tunneling when DPRX detection Wayne Lin
2021-10-04 14:40 ` [PATCH 07/23] drm/amd/display: Update training parameters for DPIA links Wayne Lin
2021-10-04 14:40 ` [PATCH 08/23] drm/amd/display: Support USB4 when DP link training Wayne Lin
2021-10-04 14:40 ` [PATCH 09/23] drm/amd/display: Implement DPIA training loop Wayne Lin
2021-10-04 14:40 ` [PATCH 10/23] drm/amd/display: Implement DPIA link configuration Wayne Lin
2021-10-04 14:40 ` [PATCH 11/23] drm/amd/display: Implement DPIA clock recovery phase Wayne Lin
2021-10-04 14:40 ` [PATCH 12/23] drm/amd/display: Implement DPIA equalisation phase Wayne Lin
2021-10-04 14:40 ` [PATCH 13/23] drm/amd/display: Implement end of training for hop in DPIA display path Wayne Lin
2021-10-04 14:40 ` [PATCH 14/23] drm/amd/display: Support for SET_CONFIG processing with DMUB Wayne Lin
2021-10-04 14:40 ` [PATCH 15/23] drm/amd/display: Read USB4 DP tunneling data from DPCD Wayne Lin
2021-10-04 14:40 ` [PATCH 16/23] drm/amd/display: Add dpia debug options Wayne Lin
2021-10-04 14:40 ` [PATCH 17/23] drm/amd/display: Support for SET_CONFIG processing with DMUB Wayne Lin
2021-10-04 14:40 ` [PATCH 18/23] drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints Wayne Lin
2021-10-04 14:40 ` [PATCH 19/23] drm/amd/display: Add debug flags for USB4 DP link training Wayne Lin
2021-10-04 14:40 ` [PATCH 20/23] drm/amd/display: Fix for access for ddc pin and aux engine Wayne Lin
2021-10-04 14:40 ` [PATCH 21/23] drm/amd/display: Deadlock/HPD Status/Crash Bug Fix Wayne Lin
2021-10-04 14:40 ` [PATCH 22/23] drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly Wayne Lin
2021-10-04 14:40 ` [PATCH 23/23] drm/amd/display: USB4 bring up set correct address Wayne Lin
2021-10-04 14:48 ` [PATCH 00/23] USB4 DP tunneling Harry Wentland
2021-10-05  6:30   ` Lin, Wayne

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.