Skip to content

Commit acea108

Browse files
Fangzhi Zuoalexdeucher
authored andcommitted
drm/amd/display: Ignore First MST Sideband Message Return Error
[why] First MST sideband message returns AUX_RET_ERROR_HPD_DISCON on certain intel platform. Aux transaction considered failure if HPD unexpected pulled low. The actual aux transaction success in such case, hence do not return error. [how] Not returning error when AUX_RET_ERROR_HPD_DISCON detected on the first sideband message. v2: squash in additional DMI entries v3: squash in static fix Signed-off-by: Fangzhi Zuo <[email protected]> Acked-by: Solomon Chiu <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Cc: [email protected]
1 parent 3590b44 commit acea108

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
#include <linux/pci.h>
7373
#include <linux/firmware.h>
7474
#include <linux/component.h>
75+
#include <linux/dmi.h>
7576

7677
#include <drm/display/drm_dp_mst_helper.h>
7778
#include <drm/display/drm_hdmi_helper.h>
@@ -1382,6 +1383,41 @@ static bool dm_should_disable_stutter(struct pci_dev *pdev)
13821383
return false;
13831384
}
13841385

1386+
static const struct dmi_system_id hpd_disconnect_quirk_table[] = {
1387+
{
1388+
.matches = {
1389+
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1390+
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3660"),
1391+
},
1392+
},
1393+
{
1394+
.matches = {
1395+
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1396+
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3260"),
1397+
},
1398+
},
1399+
{
1400+
.matches = {
1401+
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1402+
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"),
1403+
},
1404+
},
1405+
{}
1406+
};
1407+
1408+
static void retrieve_dmi_info(struct amdgpu_display_manager *dm)
1409+
{
1410+
const struct dmi_system_id *dmi_id;
1411+
1412+
dm->aux_hpd_discon_quirk = false;
1413+
1414+
dmi_id = dmi_first_match(hpd_disconnect_quirk_table);
1415+
if (dmi_id) {
1416+
dm->aux_hpd_discon_quirk = true;
1417+
DRM_INFO("aux_hpd_discon_quirk attached\n");
1418+
}
1419+
}
1420+
13851421
static int amdgpu_dm_init(struct amdgpu_device *adev)
13861422
{
13871423
struct dc_init_data init_data;
@@ -1508,6 +1544,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
15081544
}
15091545

15101546
INIT_LIST_HEAD(&adev->dm.da_list);
1547+
1548+
retrieve_dmi_info(&adev->dm);
1549+
15111550
/* Display Core create. */
15121551
adev->dm.dc = dc_create(&init_data);
15131552

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,14 @@ struct amdgpu_display_manager {
540540
* last successfully applied backlight values.
541541
*/
542542
u32 actual_brightness[AMDGPU_DM_MAX_NUM_EDP];
543+
544+
/**
545+
* @aux_hpd_discon_quirk:
546+
*
547+
* quirk for hpd discon while aux is on-going.
548+
* occurred on certain intel platform
549+
*/
550+
bool aux_hpd_discon_quirk;
543551
};
544552

545553
enum dsc_clock_force_state {

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
5656
ssize_t result = 0;
5757
struct aux_payload payload;
5858
enum aux_return_code_type operation_result;
59+
struct amdgpu_device *adev;
60+
struct ddc_service *ddc;
5961

6062
if (WARN_ON(msg->size > 16))
6163
return -E2BIG;
@@ -74,6 +76,21 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
7476
result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload,
7577
&operation_result);
7678

79+
/*
80+
* w/a on certain intel platform where hpd is unexpected to pull low during
81+
* 1st sideband message transaction by return AUX_RET_ERROR_HPD_DISCON
82+
* aux transaction is succuess in such case, therefore bypass the error
83+
*/
84+
ddc = TO_DM_AUX(aux)->ddc_service;
85+
adev = ddc->ctx->driver_context;
86+
if (adev->dm.aux_hpd_discon_quirk) {
87+
if (msg->address == DP_SIDEBAND_MSG_DOWN_REQ_BASE &&
88+
operation_result == AUX_RET_ERROR_HPD_DISCON) {
89+
result = 0;
90+
operation_result = AUX_RET_SUCCESS;
91+
}
92+
}
93+
7794
if (payload.write && result >= 0)
7895
result = msg->size;
7996

0 commit comments

Comments
 (0)