disp: msm: dp: add debug node to capture source and sink crc
This change adds a debug node named 'crc' to drm_dp to read the frame CRC values for DP controller and DP Sink. In order to facilitate the immediate read of the CRC values when accessed, it enables the CRC calculation on the controller and sink automatically when the stream is enabled. In addition to the frame CRC values it also reads the MISR values from controller and PHY to validate the data flow from controller to PHY. Change-Id: I1acee2dba931e4635caf4a400e336a72c86e88bf Signed-off-by: Rajkumar Subbiah <quic_rsubbia@quicinc.com>
This commit is contained in:

committad av
Gerrit - the friendly Code Review server

förälder
51775dd093
incheckning
7eef92843d
@@ -333,7 +333,7 @@ static ssize_t dp_debug_read_dpcd(struct file *file,
|
||||
}
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len , buf_size - len, "%04x: ", debug->dpcd_offset);
|
||||
len += scnprintf(buf + len, buf_size - len, "%04x: ", debug->dpcd_offset);
|
||||
|
||||
while (offset < debug->dpcd_size)
|
||||
len += scnprintf(buf + len, buf_size - len, "%02x ", dpcd[offset++]);
|
||||
@@ -351,6 +351,90 @@ bail:
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t dp_debug_read_crc(struct file *file, char __user *user_buff, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct dp_debug_private *debug = file->private_data;
|
||||
char *buf;
|
||||
int const buf_size = SZ_4K;
|
||||
u32 len = 0;
|
||||
u16 src_crc[3] = {0};
|
||||
u16 sink_crc[3] = {0};
|
||||
struct dp_misr40_data misr40 = {0};
|
||||
u32 retries = 2;
|
||||
struct drm_connector *drm_conn;
|
||||
struct sde_connector *sde_conn;
|
||||
struct dp_panel *panel;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
if (!debug || !debug->aux)
|
||||
return -ENODEV;
|
||||
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
buf = kzalloc(buf_size, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&debug->lock);
|
||||
|
||||
if (!debug->panel || !debug->ctrl)
|
||||
goto bail;
|
||||
|
||||
if (debug->panel->mst_state) {
|
||||
drm_conn = drm_connector_lookup((*debug->connector)->dev, NULL, debug->mst_con_id);
|
||||
if (!drm_conn) {
|
||||
DP_ERR("connector %u not in mst list\n", debug->mst_con_id);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
sde_conn = to_sde_connector(drm_conn);
|
||||
panel = sde_conn->drv_panel;
|
||||
} else {
|
||||
panel = debug->panel;
|
||||
}
|
||||
|
||||
panel->get_src_crc(panel, src_crc);
|
||||
panel->get_sink_crc(panel, sink_crc);
|
||||
|
||||
len += scnprintf(buf + len, buf_size - len, "FRAME_CRC:\nSource vs Sink\n");
|
||||
|
||||
len += scnprintf(buf + len, buf_size - len, "CRC_R: %04X %04X\n", src_crc[0], sink_crc[0]);
|
||||
len += scnprintf(buf + len, buf_size - len, "CRC_G: %04X %04X\n", src_crc[1], sink_crc[1]);
|
||||
len += scnprintf(buf + len, buf_size - len, "CRC_B: %04X %04X\n", src_crc[2], sink_crc[2]);
|
||||
|
||||
debug->ctrl->setup_misr(debug->ctrl);
|
||||
|
||||
while (retries--) {
|
||||
mutex_unlock(&debug->lock);
|
||||
msleep(30);
|
||||
mutex_lock(&debug->lock);
|
||||
|
||||
rc = debug->ctrl->read_misr(debug->ctrl, &misr40);
|
||||
if (rc != -EAGAIN)
|
||||
break;
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len, buf_size - len, "\nMISR40:\nCTLR vs PHY\n");
|
||||
for (i = 0; i < 4; i++) {
|
||||
len += scnprintf(buf + len, buf_size - len, "Lane%d %08X%08X %08X%08X\n", i,
|
||||
misr40.ctrl_misr[2 * i], misr40.ctrl_misr[(2 * i) + 1],
|
||||
misr40.phy_misr[2 * i], misr40.phy_misr[(2 * i) + 1]);
|
||||
}
|
||||
|
||||
len = min_t(size_t, count, len);
|
||||
if (!copy_to_user(user_buff, buf, len))
|
||||
*ppos += len;
|
||||
|
||||
bail:
|
||||
mutex_unlock(&debug->lock);
|
||||
kfree(buf);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t dp_debug_write_hpd(struct file *file,
|
||||
const char __user *user_buff, size_t count, loff_t *ppos)
|
||||
{
|
||||
@@ -1871,6 +1955,11 @@ static const struct file_operations dpcd_fops = {
|
||||
.read = dp_debug_read_dpcd,
|
||||
};
|
||||
|
||||
static const struct file_operations crc_fops = {
|
||||
.open = simple_open,
|
||||
.read = dp_debug_read_crc,
|
||||
};
|
||||
|
||||
static const struct file_operations connected_fops = {
|
||||
.open = simple_open,
|
||||
.read = dp_debug_read_connected,
|
||||
@@ -2104,6 +2193,13 @@ static int dp_debug_init_sink_caps(struct dp_debug_private *debug,
|
||||
return rc;
|
||||
}
|
||||
|
||||
file = debugfs_create_file("crc", 0644, dir, debug, &crc_fops);
|
||||
if (IS_ERR_OR_NULL(file)) {
|
||||
rc = PTR_ERR(file);
|
||||
DP_ERR("[%s] debugfs crc failed, rc=%d\n", DEBUG_NAME, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Referens i nytt ärende
Block a user