Parcourir la source

disp: msm: dp: enhance dpcd debugfs to parse extended capability information

Add support to pass extended capability information to the DPCD
debugfs node. This will help to validate features like VSC support
using debugfs node.

Usage will be the same as before and the change will automatically
detect the presence of extended capability field and expect
additional bytes of information.

Change-Id: If541fd8837aac4794c3db0fa3badeab4143ff9c3
Signed-off-by: Abhinav Kumar <[email protected]>
Abhinav Kumar il y a 6 ans
Parent
commit
1286b854ae
3 fichiers modifiés avec 30 ajouts et 7 suppressions
  1. 18 2
      msm/dp/dp_debug.c
  2. 8 3
      msm/dp/dp_panel.c
  3. 4 2
      msm/dp/dp_panel.h

+ 18 - 2
msm/dp/dp_debug.c

@@ -178,6 +178,7 @@ static ssize_t dp_debug_write_dpcd(struct file *file,
 	ssize_t rc = count;
 	char offset_ch[5];
 	u32 offset, data_len;
+	u32 extended_capability_bytes = 0;
 	const u32 dp_receiver_cap_size = 16;
 
 	if (!debug)
@@ -249,11 +250,23 @@ static ssize_t dp_debug_write_dpcd(struct file *file,
 bail:
 	kfree(buf);
 
+	/*
+	 * If extension bit is set then increase the length
+	 * of user input to account for the extra bytes
+	 */
+	if (dpcd && (dpcd_buf_index > DP_RECEIVER_CAP_SIZE) &&
+			(dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
+			 DP_EXT_REC_CAP_FIELD))
+		extended_capability_bytes = 4;
+
 	/*
 	 * Reset panel's dpcd in case of any failure. Also, set the
 	 * panel's dpcd only if a full dpcd is provided with offset as 0.
 	 */
-	if (!dpcd || (!offset && (data_len == dp_receiver_cap_size))) {
+	if (!dpcd || (!offset &&
+			(data_len == (dp_receiver_cap_size +
+			extended_capability_bytes))) ||
+			(offset == 0xffff)) {
 		debug->panel->set_dpcd(debug->panel, dpcd);
 
 		/*
@@ -261,7 +274,10 @@ bail:
 		 * only while running in debug mode which is manually
 		 * triggered by a tester or a script.
 		 */
-		DP_INFO("[%s]\n", dpcd ? "SET" : "CLEAR");
+		if (!dpcd || (offset == 0xffff))
+			DP_INFO("[%s]\n", "CLEAR");
+		else
+			DP_INFO("[%s]\n", "SET");
 	} else
 		debug->aux->dpcd_updated(debug->aux);
 

+ 8 - 3
msm/dp/dp_panel.c

@@ -1763,8 +1763,13 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel, bool multi_func)
 		DPRX_FEATURE_ENUMERATION_LIST, &rx_feature, 1);
 	if (rlen != 1) {
 		DP_DEBUG("failed to read DPRX_FEATURE_ENUMERATION_LIST\n");
-		goto skip_dpcd_read;
+		rx_feature = 0;
 	}
+
+skip_dpcd_read:
+	if (panel->custom_dpcd)
+		rx_feature = dp_panel->dpcd[DP_RECEIVER_CAP_SIZE + 1];
+
 	panel->vsc_supported = !!(rx_feature &
 		VSC_SDP_EXTENSION_FOR_COLORIMETRY_SUPPORTED);
 	panel->vscext_supported = !!(rx_feature & VSC_EXT_VESA_SDP_SUPPORTED);
@@ -1775,7 +1780,6 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel, bool multi_func)
 		panel->vsc_supported, panel->vscext_supported,
 		panel->vscext_chaining_supported);
 
-skip_dpcd_read:
 	link_info->revision = dpcd[DP_DPCD_REV];
 	panel->major = (link_info->revision >> 4) & 0x0f;
 	panel->minor = link_info->revision & 0x0f;
@@ -1876,7 +1880,8 @@ static int dp_panel_set_dpcd(struct dp_panel *dp_panel, u8 *dpcd)
 	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
 
 	if (dpcd) {
-		memcpy(dp_dpcd, dpcd, DP_RECEIVER_CAP_SIZE + 1);
+		memcpy(dp_dpcd, dpcd, DP_RECEIVER_CAP_SIZE +
+				DP_RECEIVER_EXT_CAP_SIZE + 1);
 		panel->custom_dpcd = true;
 	} else {
 		panel->custom_dpcd = false;

+ 4 - 2
msm/dp/dp_panel.h

@@ -17,7 +17,7 @@
 
 #define DP_RECEIVER_DSC_CAP_SIZE    15
 #define DP_RECEIVER_FEC_STATUS_SIZE 3
-
+#define DP_RECEIVER_EXT_CAP_SIZE 4
 /*
  * A source initiated power down flag is set
  * when the DP is powered off while physical
@@ -28,6 +28,8 @@
  */
 #define DP_PANEL_SRC_INITIATED_POWER_DOWN BIT(0)
 
+#define DP_EXT_REC_CAP_FIELD BIT(7)
+
 enum dp_lane_count {
 	DP_LANE_COUNT_1	= 1,
 	DP_LANE_COUNT_2	= 2,
@@ -87,7 +89,7 @@ struct dp_audio;
 
 struct dp_panel {
 	/* dpcd raw data */
-	u8 dpcd[DP_RECEIVER_CAP_SIZE + 1];
+	u8 dpcd[DP_RECEIVER_CAP_SIZE + DP_RECEIVER_EXT_CAP_SIZE + 1];
 	u8 ds_ports[DP_MAX_DOWNSTREAM_PORTS];
 	u8 dsc_dpcd[DP_RECEIVER_DSC_CAP_SIZE + 1];
 	u8 fec_dpcd;