drm/amd/display: Get replay info from VSDB
We need to make sure that the panel supports replay. This info is inside the amd vsdb (vendor specific data block). Create a function to parse the block and read the replay_mode bit. Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
7957ec80ef
commit
ec8e59cb4e
@ -10490,6 +10490,41 @@ static bool parse_edid_cea(struct amdgpu_dm_connector *aconnector,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector,
|
||||||
|
struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info)
|
||||||
|
{
|
||||||
|
u8 *edid_ext = NULL;
|
||||||
|
int i;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
if (edid == NULL || edid->extensions == 0)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* Find DisplayID extension */
|
||||||
|
for (i = 0; i < edid->extensions; i++) {
|
||||||
|
edid_ext = (void *)(edid + (i + 1));
|
||||||
|
if (edid_ext[0] == DISPLAYID_EXT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (j < EDID_LENGTH) {
|
||||||
|
struct amd_vsdb_block *amd_vsdb = (struct amd_vsdb_block *)&edid_ext[j];
|
||||||
|
unsigned int ieeeId = (amd_vsdb->ieee_id[2] << 16) | (amd_vsdb->ieee_id[1] << 8) | (amd_vsdb->ieee_id[0]);
|
||||||
|
|
||||||
|
if (ieeeId == HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID &&
|
||||||
|
amd_vsdb->version == HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_VERSION_3) {
|
||||||
|
vsdb_info->replay_mode = (amd_vsdb->feature_caps & AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE) ? true : false;
|
||||||
|
vsdb_info->amd_vsdb_version = HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_VERSION_3;
|
||||||
|
DRM_DEBUG_KMS("Panel supports Replay Mode: %d\n", vsdb_info->replay_mode);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector,
|
static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector,
|
||||||
struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info)
|
struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info)
|
||||||
{
|
{
|
||||||
@ -10625,6 +10660,14 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
|
|||||||
freesync_capable = true;
|
freesync_capable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
parse_amd_vsdb(amdgpu_dm_connector, edid, &vsdb_info);
|
||||||
|
|
||||||
|
if (vsdb_info.replay_mode) {
|
||||||
|
amdgpu_dm_connector->vsdb_info.replay_mode = vsdb_info.replay_mode;
|
||||||
|
amdgpu_dm_connector->vsdb_info.amd_vsdb_version = vsdb_info.amd_vsdb_version;
|
||||||
|
amdgpu_dm_connector->as_type = ADAPTIVE_SYNC_TYPE_EDP;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (edid && sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) {
|
} else if (edid && sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) {
|
||||||
i = parse_hdmi_amd_vsdb(amdgpu_dm_connector, edid, &vsdb_info);
|
i = parse_hdmi_amd_vsdb(amdgpu_dm_connector, edid, &vsdb_info);
|
||||||
if (i >= 0 && vsdb_info.freesync_supported) {
|
if (i >= 0 && vsdb_info.freesync_supported) {
|
||||||
|
@ -51,6 +51,9 @@
|
|||||||
|
|
||||||
#define AMDGPU_DMUB_NOTIFICATION_MAX 5
|
#define AMDGPU_DMUB_NOTIFICATION_MAX 5
|
||||||
|
|
||||||
|
#define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID 0x00001A
|
||||||
|
#define AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40
|
||||||
|
#define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_VERSION_3 0x3
|
||||||
/*
|
/*
|
||||||
#include "include/amdgpu_dal_power_if.h"
|
#include "include/amdgpu_dal_power_if.h"
|
||||||
#include "amdgpu_dm_irq.h"
|
#include "amdgpu_dm_irq.h"
|
||||||
@ -75,6 +78,12 @@ struct dmub_srv;
|
|||||||
struct dc_plane_state;
|
struct dc_plane_state;
|
||||||
struct dmub_notification;
|
struct dmub_notification;
|
||||||
|
|
||||||
|
struct amd_vsdb_block {
|
||||||
|
unsigned char ieee_id[3];
|
||||||
|
unsigned char version;
|
||||||
|
unsigned char feature_caps;
|
||||||
|
};
|
||||||
|
|
||||||
struct common_irq_params {
|
struct common_irq_params {
|
||||||
struct amdgpu_device *adev;
|
struct amdgpu_device *adev;
|
||||||
enum dc_irq_source irq_src;
|
enum dc_irq_source irq_src;
|
||||||
@ -609,6 +618,11 @@ struct amdgpu_hdmi_vsdb_info {
|
|||||||
* @max_refresh_rate_hz: FreeSync Maximum Refresh Rate in Hz
|
* @max_refresh_rate_hz: FreeSync Maximum Refresh Rate in Hz
|
||||||
*/
|
*/
|
||||||
unsigned int max_refresh_rate_hz;
|
unsigned int max_refresh_rate_hz;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @replay mode: Replay supported
|
||||||
|
*/
|
||||||
|
bool replay_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amdgpu_dm_connector {
|
struct amdgpu_dm_connector {
|
||||||
|
@ -46,6 +46,9 @@ static bool link_supports_replay(struct dc_link *link, struct amdgpu_dm_connecto
|
|||||||
if (!state->freesync_capable)
|
if (!state->freesync_capable)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!aconnector->vsdb_info.replay_mode)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Check the eDP version
|
// Check the eDP version
|
||||||
if (dpcd_caps->edp_rev < EDP_REVISION_13)
|
if (dpcd_caps->edp_rev < EDP_REVISION_13)
|
||||||
return false;
|
return false;
|
||||||
@ -71,6 +74,10 @@ bool amdgpu_dm_setup_replay(struct dc_link *link, struct amdgpu_dm_connector *ac
|
|||||||
struct replay_config pr_config;
|
struct replay_config pr_config;
|
||||||
union replay_debug_flags *debug_flags = NULL;
|
union replay_debug_flags *debug_flags = NULL;
|
||||||
|
|
||||||
|
// For eDP, if Replay is supported, return true to skip checks
|
||||||
|
if (link->replay_settings.config.replay_supported)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (!dc_is_embedded_signal(link->connector_signal))
|
if (!dc_is_embedded_signal(link->connector_signal))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user