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>
这个提交包含在:
Rajkumar Subbiah
2022-04-12 11:13:55 -04:00
提交者 Gerrit - the friendly Code Review server
父节点 51775dd093
当前提交 7eef92843d
修改 9 个文件,包含 332 行新增1 行删除

查看文件

@@ -1682,6 +1682,10 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel, bool multi_func)
if (drm_dp_enhanced_frame_cap(dpcd))
link_info->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DP_TEST_SINK_MISC, &temp, 1);
if ((rlen == 1) && (temp & DP_TEST_CRC_SUPPORTED))
link_info->capabilities |= DP_LINK_CAP_CRC;
dfp_count = dpcd[DP_DOWN_STREAM_PORT_COUNT] &
DP_DOWN_STREAM_PORT_COUNT;
@@ -3050,6 +3054,70 @@ static void dp_panel_update_pps(struct dp_panel *dp_panel, char *pps_cmd)
catalog->pps_flush(catalog);
}
int dp_panel_get_src_crc(struct dp_panel *dp_panel, u16 *crc)
{
struct dp_catalog_panel *catalog;
struct dp_panel_private *panel;
panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
catalog = panel->catalog;
return catalog->get_src_crc(catalog, crc);
}
int dp_panel_get_sink_crc(struct dp_panel *dp_panel, u16 *crc)
{
int rc = 0;
struct dp_panel_private *panel;
struct drm_dp_aux *drm_aux;
u8 crc_bytes[6];
panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
drm_aux = panel->aux->drm_aux;
/*
* At DP_TEST_CRC_R_CR, there's 6 bytes containing CRC data, 2 bytes
* per component (RGB or CrYCb).
*/
rc = drm_dp_dpcd_read(drm_aux, DP_TEST_CRC_R_CR, crc_bytes, 6);
if (rc < 0)
return rc;
rc = 0;
crc[0] = crc_bytes[0] | crc_bytes[1] << 8;
crc[1] = crc_bytes[2] | crc_bytes[3] << 8;
crc[2] = crc_bytes[4] | crc_bytes[5] << 8;
return rc;
}
int dp_panel_sink_crc_enable(struct dp_panel *dp_panel, bool enable)
{
int rc = 0;
struct dp_panel_private *panel;
struct drm_dp_aux *drm_aux;
ssize_t ret;
u8 buf;
panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
drm_aux = panel->aux->drm_aux;
if (dp_panel->link_info.capabilities & DP_LINK_CAP_CRC) {
ret = drm_dp_dpcd_readb(drm_aux, DP_TEST_SINK, &buf);
if (ret < 0)
return ret;
ret = drm_dp_dpcd_writeb(drm_aux, DP_TEST_SINK, buf | DP_TEST_SINK_START);
if (ret < 0)
return ret;
drm_dp_dpcd_readb(drm_aux, DP_TEST_SINK, &buf);
DP_DEBUG("Enabled CRC: %x\n", buf);
}
return rc;
}
struct dp_panel *dp_panel_get(struct dp_panel_in *in)
{
int rc = 0;
@@ -3122,6 +3190,9 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in)
dp_panel->read_mst_cap = dp_panel_read_mst_cap;
dp_panel->convert_to_dp_mode = dp_panel_convert_to_dp_mode;
dp_panel->update_pps = dp_panel_update_pps;
dp_panel->get_src_crc = dp_panel_get_src_crc;
dp_panel->get_sink_crc = dp_panel_get_sink_crc;
dp_panel->sink_crc_enable = dp_panel_sink_crc_enable;
sde_conn = to_sde_connector(dp_panel->connector);
sde_conn->drv_panel = dp_panel;