Skip to content

Commit 566db37

Browse files
Tom Chunggregkh
authored andcommitted
drm/amd/display: Fix refresh rate range for some panel
[ Upstream commit 9ef1548 ] [Why] Some of the panels does not have the refresh rate range info in base EDID and only have the refresh rate range info in DisplayID block. It will cause the max/min freesync refresh rate set to 0. [How] Try to parse the refresh rate range info from DisplayID if the max/min refresh rate is 0. Reviewed-by: Sun peng Li <sunpeng.li@amd.com> Signed-off-by: Jerry Zuo <jerry.zuo@amd.com> Signed-off-by: Tom Chung <chiahsuan.chung@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 4f9467d commit 566db37

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11161,6 +11161,49 @@ static bool parse_edid_cea(struct amdgpu_dm_connector *aconnector,
1116111161
return ret;
1116211162
}
1116311163

11164+
static void parse_edid_displayid_vrr(struct drm_connector *connector,
11165+
struct edid *edid)
11166+
{
11167+
u8 *edid_ext = NULL;
11168+
int i;
11169+
int j = 0;
11170+
u16 min_vfreq;
11171+
u16 max_vfreq;
11172+
11173+
if (edid == NULL || edid->extensions == 0)
11174+
return;
11175+
11176+
/* Find DisplayID extension */
11177+
for (i = 0; i < edid->extensions; i++) {
11178+
edid_ext = (void *)(edid + (i + 1));
11179+
if (edid_ext[0] == DISPLAYID_EXT)
11180+
break;
11181+
}
11182+
11183+
if (edid_ext == NULL)
11184+
return;
11185+
11186+
while (j < EDID_LENGTH) {
11187+
/* Get dynamic video timing range from DisplayID if available */
11188+
if (EDID_LENGTH - j > 13 && edid_ext[j] == 0x25 &&
11189+
(edid_ext[j+1] & 0xFE) == 0 && (edid_ext[j+2] == 9)) {
11190+
min_vfreq = edid_ext[j+9];
11191+
if (edid_ext[j+1] & 7)
11192+
max_vfreq = edid_ext[j+10] + ((edid_ext[j+11] & 3) << 8);
11193+
else
11194+
max_vfreq = edid_ext[j+10];
11195+
11196+
if (max_vfreq && min_vfreq) {
11197+
connector->display_info.monitor_range.max_vfreq = max_vfreq;
11198+
connector->display_info.monitor_range.min_vfreq = min_vfreq;
11199+
11200+
return;
11201+
}
11202+
}
11203+
j++;
11204+
}
11205+
}
11206+
1116411207
static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector,
1116511208
struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info)
1116611209
{
@@ -11282,6 +11325,11 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
1128211325
if (!adev->dm.freesync_module)
1128311326
goto update;
1128411327

11328+
/* Some eDP panels only have the refresh rate range info in DisplayID */
11329+
if ((connector->display_info.monitor_range.min_vfreq == 0 ||
11330+
connector->display_info.monitor_range.max_vfreq == 0))
11331+
parse_edid_displayid_vrr(connector, edid);
11332+
1128511333
if (edid && (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT ||
1128611334
sink->sink_signal == SIGNAL_TYPE_EDP)) {
1128711335
bool edid_check_required = false;

0 commit comments

Comments
 (0)