drm/amd/display: fix read errors pertaining to dp_lttpr_status_show()
Currently, it is likely that we will read the relevant LTTPR caps after link training has completed (which can cause garbage data to be read), however according to the DP 2.0 spec that should be done before link training has commenced. So, instead of reading the registers on demand, use the values provided to us by DC. Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
ad1cebb6f0
commit
642f1b4052
@ -36,6 +36,7 @@
|
|||||||
#include "dsc.h"
|
#include "dsc.h"
|
||||||
#include "link_hwss.h"
|
#include "link_hwss.h"
|
||||||
#include "dc/dc_dmub_srv.h"
|
#include "dc/dc_dmub_srv.h"
|
||||||
|
#include "link/protocols/link_dp_capability.h"
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||||
#include "amdgpu_dm_psr.h"
|
#include "amdgpu_dm_psr.h"
|
||||||
@ -418,67 +419,38 @@ static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dp_lttpr_status_show(struct seq_file *m, void *d)
|
static int dp_lttpr_status_show(struct seq_file *m, void *unused)
|
||||||
{
|
{
|
||||||
char *data;
|
struct drm_connector *connector = m->private;
|
||||||
struct amdgpu_dm_connector *connector = file_inode(m->file)->i_private;
|
struct amdgpu_dm_connector *aconnector =
|
||||||
struct dc_link *link = connector->dc_link;
|
to_amdgpu_dm_connector(connector);
|
||||||
uint32_t read_size = 1;
|
struct dc_lttpr_caps caps = aconnector->dc_link->dpcd_caps.lttpr_caps;
|
||||||
uint8_t repeater_count = 0;
|
|
||||||
|
|
||||||
data = kzalloc(read_size, GFP_KERNEL);
|
if (connector->status != connector_status_connected)
|
||||||
if (!data)
|
return -ENODEV;
|
||||||
return 0;
|
|
||||||
|
|
||||||
dm_helpers_dp_read_dpcd(link->ctx, link, 0xF0002, data, read_size);
|
seq_printf(m, "phy repeater count: %u (raw: 0x%x)\n",
|
||||||
|
dp_parse_lttpr_repeater_count(caps.phy_repeater_cnt),
|
||||||
|
caps.phy_repeater_cnt);
|
||||||
|
|
||||||
switch ((uint8_t)*data) {
|
seq_puts(m, "phy repeater mode: ");
|
||||||
case 0x80:
|
|
||||||
repeater_count = 1;
|
switch (caps.mode) {
|
||||||
|
case DP_PHY_REPEATER_MODE_TRANSPARENT:
|
||||||
|
seq_puts(m, "transparent");
|
||||||
break;
|
break;
|
||||||
case 0x40:
|
case DP_PHY_REPEATER_MODE_NON_TRANSPARENT:
|
||||||
repeater_count = 2;
|
seq_puts(m, "non-transparent");
|
||||||
break;
|
break;
|
||||||
case 0x20:
|
case 0x00:
|
||||||
repeater_count = 3;
|
seq_puts(m, "non lttpr");
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
repeater_count = 4;
|
|
||||||
break;
|
|
||||||
case 0x8:
|
|
||||||
repeater_count = 5;
|
|
||||||
break;
|
|
||||||
case 0x4:
|
|
||||||
repeater_count = 6;
|
|
||||||
break;
|
|
||||||
case 0x2:
|
|
||||||
repeater_count = 7;
|
|
||||||
break;
|
|
||||||
case 0x1:
|
|
||||||
repeater_count = 8;
|
|
||||||
break;
|
|
||||||
case 0x0:
|
|
||||||
repeater_count = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
repeater_count = (uint8_t)*data;
|
seq_printf(m, "read error (raw: 0x%x)", caps.mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
seq_printf(m, "phy repeater count: %d\n", repeater_count);
|
seq_puts(m, "\n");
|
||||||
|
|
||||||
dm_helpers_dp_read_dpcd(link->ctx, link, 0xF0003, data, read_size);
|
|
||||||
|
|
||||||
if ((uint8_t)*data == 0x55)
|
|
||||||
seq_printf(m, "phy repeater mode: transparent\n");
|
|
||||||
else if ((uint8_t)*data == 0xAA)
|
|
||||||
seq_printf(m, "phy repeater mode: non-transparent\n");
|
|
||||||
else if ((uint8_t)*data == 0x00)
|
|
||||||
seq_printf(m, "phy repeater mode: non lttpr\n");
|
|
||||||
else
|
|
||||||
seq_printf(m, "phy repeater mode: read error\n");
|
|
||||||
|
|
||||||
kfree(data);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user