Blob Blame History Raw
From 17f4931b0185ed47210b12eb1967e026fb963250 Mon Sep 17 00:00:00 2001
From: Po Ting Chen <robin.chen@amd.com>
Date: Tue, 8 Feb 2022 00:20:53 +0800
Subject: drm/amd/display: Refactor PSR DPCD caps detection
Git-commit: 3e6084aee08b108f5cc489be46c68ba56b13e52e
Patch-mainline: v5.18-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225

[Why]
To move the PSR DPCD caps detection into detect_edp_sink_caps()

Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Solomon Chiu <solomon.chiu@amd.com>
Signed-off-by: Po Ting Chen <robin.chen@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |  6 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 58 ++-----------------
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 28 +++++++++
 drivers/gpu/drm/amd/display/dc/dc.h           |  4 +-
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  | 29 ++++++++++
 .../amd/display/include/ddc_service_types.h   |  1 +
 6 files changed, 69 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 0e8c5e6b2a5b..777210811311 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -853,9 +853,9 @@ static int psr_capability_show(struct seq_file *m, void *data)
 	if (!(link->connector_signal & SIGNAL_TYPE_EDP))
 		return -ENODEV;
 
-	seq_printf(m, "Sink support: %s", str_yes_no(link->dpcd_caps.psr_caps.psr_version != 0));
-	if (link->dpcd_caps.psr_caps.psr_version)
-		seq_printf(m, " [0x%02x]", link->dpcd_caps.psr_caps.psr_version);
+	seq_printf(m, "Sink support: %s", str_yes_no(link->dpcd_caps.psr_info.psr_version != 0));
+	if (link->dpcd_caps.psr_info.psr_version)
+		seq_printf(m, " [0x%02x]", link->dpcd_caps.psr_info.psr_version);
 	seq_puts(m, "\n");
 
 	seq_printf(m, "Driver support: %s", str_yes_no(link->psr_settings.psr_feature_enabled));
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
index a009fc654ac9..0c923a90615c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
@@ -28,49 +28,6 @@
 #include "dm_helpers.h"
 #include "amdgpu_dm.h"
 
-static bool link_get_psr_caps(struct dc_link *link)
-{
-	uint8_t psr_dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE];
-	uint8_t edp_rev_dpcd_data;
-
-
-
-	if (!dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT,
-				    psr_dpcd_data, sizeof(psr_dpcd_data)))
-		return false;
-
-	if (!dm_helpers_dp_read_dpcd(NULL, link, DP_EDP_DPCD_REV,
-				    &edp_rev_dpcd_data, sizeof(edp_rev_dpcd_data)))
-		return false;
-
-	link->dpcd_caps.psr_caps.psr_version = psr_dpcd_data[0];
-	link->dpcd_caps.psr_caps.edp_revision = edp_rev_dpcd_data;
-
-#ifdef CONFIG_DRM_AMD_DC_DCN
-	if (link->dpcd_caps.psr_caps.psr_version > 0x1) {
-		uint8_t alpm_dpcd_data;
-		uint8_t su_granularity_dpcd_data;
-
-		if (!dm_helpers_dp_read_dpcd(NULL, link, DP_RECEIVER_ALPM_CAP,
-						&alpm_dpcd_data, sizeof(alpm_dpcd_data)))
-			return false;
-
-		if (!dm_helpers_dp_read_dpcd(NULL, link, DP_PSR2_SU_Y_GRANULARITY,
-						&su_granularity_dpcd_data, sizeof(su_granularity_dpcd_data)))
-			return false;
-
-		link->dpcd_caps.psr_caps.y_coordinate_required = psr_dpcd_data[1] & DP_PSR2_SU_Y_COORDINATE_REQUIRED;
-		link->dpcd_caps.psr_caps.su_granularity_required = psr_dpcd_data[1] & DP_PSR2_SU_GRANULARITY_REQUIRED;
-
-		link->dpcd_caps.psr_caps.alpm_cap = alpm_dpcd_data & DP_ALPM_CAP;
-		link->dpcd_caps.psr_caps.standby_support = alpm_dpcd_data & (1 << 1);
-
-		link->dpcd_caps.psr_caps.su_y_granularity = su_granularity_dpcd_data;
-	}
-#endif
-	return true;
-}
-
 #ifdef CONFIG_DRM_AMD_DC_DCN
 static bool link_supports_psrsu(struct dc_link *link)
 {
@@ -82,12 +39,12 @@ static bool link_supports_psrsu(struct dc_link *link)
 	if (dc->ctx->dce_version < DCN_VERSION_3_1)
 		return false;
 
-	if (!link->dpcd_caps.psr_caps.alpm_cap ||
-	    !link->dpcd_caps.psr_caps.y_coordinate_required)
+	if (!link->dpcd_caps.alpm_caps.bits.AUX_WAKE_ALPM_CAP ||
+	    !link->dpcd_caps.psr_info.psr_dpcd_caps.bits.Y_COORDINATE_REQUIRED)
 		return false;
 
-	if (link->dpcd_caps.psr_caps.su_granularity_required &&
-	    !link->dpcd_caps.psr_caps.su_y_granularity)
+	if (link->dpcd_caps.psr_info.psr_dpcd_caps.bits.SU_GRANULARITY_REQUIRED &&
+	    !link->dpcd_caps.psr_info.psr2_su_y_granularity_cap)
 		return false;
 
 	return true;
@@ -107,12 +64,7 @@ void amdgpu_dm_set_psr_caps(struct dc_link *link)
 	if (link->type == dc_connection_none)
 		return;
 
-	if (!link_get_psr_caps(link)) {
-		DRM_ERROR("amdgpu: Failed to read PSR Caps!\n");
-		return;
-	}
-
-	if (link->dpcd_caps.psr_caps.psr_version == 0) {
+	if (link->dpcd_caps.psr_info.psr_version == 0) {
 		link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
 		link->psr_settings.psr_feature_enabled = false;
 
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 d62b59d52ba8..bc6161f52bfa 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
@@ -5565,6 +5565,34 @@ void detect_edp_sink_caps(struct dc_link *link)
 				(backlight_adj_cap & DP_EDP_DYNAMIC_BACKLIGHT_CAP) ? true:false;
 
 	dc_link_set_default_brightness_aux(link);
+
+	core_link_read_dpcd(link, DP_EDP_DPCD_REV,
+		&link->dpcd_caps.edp_rev,
+		sizeof(link->dpcd_caps.edp_rev));
+	/*
+	 * PSR is only valid for eDP v1.3 or higher.
+	 */
+	if (link->dpcd_caps.edp_rev >= DP_EDP_13) {
+		core_link_read_dpcd(link, DP_PSR_SUPPORT,
+			&link->dpcd_caps.psr_info.psr_version,
+			sizeof(link->dpcd_caps.psr_info.psr_version));
+		core_link_read_dpcd(link, DP_PSR_CAPS,
+			&link->dpcd_caps.psr_info.psr_dpcd_caps.raw,
+			sizeof(link->dpcd_caps.psr_info.psr_dpcd_caps.raw));
+		if (link->dpcd_caps.psr_info.psr_dpcd_caps.bits.Y_COORDINATE_REQUIRED) {
+			core_link_read_dpcd(link, DP_PSR2_SU_Y_GRANULARITY,
+				&link->dpcd_caps.psr_info.psr2_su_y_granularity_cap,
+				sizeof(link->dpcd_caps.psr_info.psr2_su_y_granularity_cap));
+		}
+	}
+
+	/*
+	 * ALPM is only valid for eDP v1.4 or higher.
+	 */
+	if (link->dpcd_caps.dpcd_rev.raw >= DP_EDP_14)
+		core_link_read_dpcd(link, DP_RECEIVER_ALPM_CAP,
+			&link->dpcd_caps.alpm_caps.raw,
+			sizeof(link->dpcd_caps.alpm_caps.raw));
 }
 
 void dc_link_dp_enable_hpd(const struct dc_link *link)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index e2b3ad70635b..6176904e22fc 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1230,7 +1230,6 @@ struct dpcd_caps {
 	union dpcd_fec_capability fec_cap;
 	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;
 
 	union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
@@ -1238,6 +1237,9 @@ struct dpcd_caps {
 	union dp_sink_video_fallback_formats fallback_formats;
 	union dp_fec_capability1 fec_cap1;
 	union dp_cable_attributes cable_attributes;
+	uint8_t edp_rev;
+	union edp_alpm_caps alpm_caps;
+	struct edp_psr_info psr_info;
 };
 
 union dpcd_sink_ext_caps {
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 772084406795..aa35cf008b73 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -1068,4 +1068,33 @@ union dp_128b_132b_training_aux_rd_interval {
 	uint8_t raw;
 };
 
+union edp_alpm_caps {
+	struct {
+		uint8_t AUX_WAKE_ALPM_CAP       :1;
+		uint8_t PM_STATE_2A_SUPPORT     :1;
+		uint8_t AUX_LESS_ALPM_CAP       :1;
+		uint8_t RESERVED                :5;
+	} bits;
+	uint8_t raw;
+};
+
+union edp_psr_dpcd_caps {
+	struct {
+		uint8_t LINK_TRAINING_ON_EXIT_NOT_REQUIRED      :1;
+		uint8_t PSR_SETUP_TIME  :3;
+		uint8_t Y_COORDINATE_REQUIRED   :1;
+		uint8_t SU_GRANULARITY_REQUIRED :1;
+		uint8_t FRAME_SYNC_IS_NOT_NEEDED_FOR_SU :1;
+		uint8_t RESERVED                :1;
+	} bits;
+	uint8_t raw;
+};
+
+struct edp_psr_info {
+	uint8_t psr_version;
+	union edp_psr_dpcd_caps psr_dpcd_caps;
+	uint8_t psr2_su_y_granularity_cap;
+	uint8_t force_psrsu_cap;
+};
+
 #endif /* DC_DP_TYPES_H */
diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
index fb289a5c873a..f561e213bf98 100644
--- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
@@ -34,6 +34,7 @@
 #define DP_BRANCH_DEVICE_ID_90CC24 0x90CC24
 #define DP_BRANCH_DEVICE_ID_00E04C 0x00E04C
 #define DP_BRANCH_DEVICE_ID_006037 0x006037
+#define DP_BRANCH_DEVICE_ID_001CF8 0x001CF8
 #define DP_BRANCH_HW_REV_10 0x10
 #define DP_BRANCH_HW_REV_20 0x20
 
-- 
2.38.1