Commit cd9a0d02 authored by Mikita Lipski's avatar Mikita Lipski Committed by Alex Deucher
Browse files

drm/amd/display: parse and check PSR SU caps



[why]
Adding a function to read PSR capabilities
and ALPM capabilities.
Also adding a helper function to validate if
the sink and the driver support PSR SU.
[how]
- isolated all PSR and ALPM reading calls to a separate funciton
- set all required PSR caps
- added a helper function to check if PSR SU is supported by sink
and the driver

Reviewed-by: default avatarRoman Li <Roman.Li@amd.com>
Reviewed-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: default avatarPavle Kotarac <Pavle.Kotarac@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarMikita Lipski <mikita.lipski@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 741fe8a4
Loading
Loading
Loading
Loading
+88 −13
Original line number Diff line number Diff line
@@ -26,6 +26,73 @@
#include "amdgpu_dm_psr.h"
#include "dc.h"
#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)
{
	struct dc *dc = link->ctx->dc;

	if (!dc->caps.dmcub_support)
		return false;

	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)
		return false;

	if (link->dpcd_caps.psr_caps.su_granularity_required &&
	    !link->dpcd_caps.psr_caps.su_y_granularity)
		return false;

	return true;
}
#endif

/*
 * amdgpu_dm_set_psr_caps() - set link psr capabilities
@@ -34,26 +101,34 @@
 */
void amdgpu_dm_set_psr_caps(struct dc_link *link)
{
	uint8_t dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE];

	if (!(link->connector_signal & SIGNAL_TYPE_EDP))
		return;

	if (link->type == dc_connection_none)
		return;
	if (dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT,
					dpcd_data, sizeof(dpcd_data))) {
		link->dpcd_caps.psr_caps.psr_version = dpcd_data[0];

		if (dpcd_data[0] == 0) {
	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) {
		link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
		link->psr_settings.psr_feature_enabled = false;

	} else {
#ifdef CONFIG_DRM_AMD_DC_DCN
		if (link_supports_psrsu(link))
			link->psr_settings.psr_version = DC_PSR_VERSION_SU_1;
		else
#endif
			link->psr_settings.psr_version = DC_PSR_VERSION_1;

		link->psr_settings.psr_feature_enabled = true;
	}

	DRM_INFO("PSR support:%d\n", link->psr_settings.psr_feature_enabled);
	}

}

/*
+9 −0
Original line number Diff line number Diff line
@@ -883,6 +883,15 @@ struct psr_caps {
	unsigned char psr_version;
	unsigned int psr_rfb_setup_time;
	bool psr_exit_link_training_required;
	unsigned char edp_revision;
	unsigned char support_ver;
	bool su_granularity_required;
	bool y_coordinate_required;
	uint8_t su_y_granularity;
	bool alpm_cap;
	bool standby_support;
	uint8_t rate_control_caps;
	unsigned int psr_power_opt_flag;
};

/* Length of router topology ID read from DPCD in bytes. */
+1 −0
Original line number Diff line number Diff line
@@ -951,6 +951,7 @@ enum dc_gpu_mem_alloc_type {

enum dc_psr_version {
	DC_PSR_VERSION_1			= 0,
	DC_PSR_VERSION_SU_1			= 1,
	DC_PSR_VERSION_UNSUPPORTED		= 0xFFFFFFFF,
};