Explorar o código

disp: msm: dp: update mst connector in debugfs data on replug

The debugfs api for mst control is a multi stage process where the
connector id is selected using the mst_con_id node, which is then
used on other commands such as edid_modes_mst for mode switch.
During mode switch control, the mode is set using the current id
for a display and then the switch is initiated through an unplug
and replug. But on an unplug the connector is destroyed and a new
id is assinged for that display on the subsequent plug. This
change detects this scenario and updates the cached connector id
with the id from the newly created connector.

Change-Id: Ib51566ac9e334d4a0b145b6ae549c59c537cb0cd
Signed-off-by: Rajkumar Subbiah <[email protected]>
Rajkumar Subbiah %!s(int64=5) %!d(string=hai) anos
pai
achega
d767013a10
Modificáronse 3 ficheiros con 55 adicións e 6 borrados
  1. 30 4
      msm/dp/dp_debug.c
  2. 2 1
      msm/dp/dp_debug.h
  3. 23 1
      msm/dp/dp_display.c

+ 30 - 4
msm/dp/dp_debug.c

@@ -507,13 +507,24 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file,
 	}
 	mutex_unlock(&debug->dp_debug.dp_mst_connector_list.lock);
 
-	if (!in_list)
+	if (!in_list && status != connector_status_connected) {
 		DP_ERR("invalid connector id %u\n", con_id);
-	else if (status != connector_status_unknown) {
-		debug->dp_debug.mst_hpd_sim = true;
-		debug->hpd->simulate_attention(debug->hpd, vdo);
+		goto end;
+	}
+
+	if (status == connector_status_unknown)
+		goto end;
+
+	debug->dp_debug.mst_hpd_sim = true;
+
+	if (status == connector_status_connected) {
+		DP_INFO("plug mst connector\n", con_id, status);
+		debug->dp_debug.mst_sim_add_con = true;
+	} else {
+		DP_INFO("unplug mst connector %d\n", con_id, status);
 	}
 
+	debug->hpd->simulate_attention(debug->hpd, vdo);
 	goto end;
 clear:
 	DP_DEBUG("clearing mst_con_id\n");
@@ -2362,6 +2373,20 @@ static void dp_debug_abort(struct dp_debug *dp_debug)
 	mutex_unlock(&debug->lock);
 }
 
+static void dp_debug_set_mst_con(struct dp_debug *dp_debug, int con_id)
+{
+	struct dp_debug_private *debug;
+
+	if (!dp_debug)
+		return;
+
+	debug = container_of(dp_debug, struct dp_debug_private, dp_debug);
+	mutex_lock(&debug->lock);
+	debug->mst_con_id = con_id;
+	mutex_unlock(&debug->lock);
+	DP_INFO("Selecting mst connector %d\n", con_id);
+}
+
 struct dp_debug *dp_debug_get(struct dp_debug_in *in)
 {
 	int rc = 0;
@@ -2409,6 +2434,7 @@ struct dp_debug *dp_debug_get(struct dp_debug_in *in)
 	debug->aux->access_lock = &debug->lock;
 	dp_debug->get_edid = dp_debug_get_edid;
 	dp_debug->abort = dp_debug_abort;
+	dp_debug->set_mst_con = dp_debug_set_mst_con;
 
 	INIT_LIST_HEAD(&dp_debug->dp_mst_connector_list.list);
 

+ 2 - 1
msm/dp/dp_debug.h

@@ -85,9 +85,10 @@ struct dp_debug {
 	bool mst_sim_remove_con;
 	int mst_sim_remove_con_id;
 	u32 mst_port_cnt;
-
+	struct dp_mst_connector mst_connector_cache;
 	u8 *(*get_edid)(struct dp_debug *dp_debug);
 	void (*abort)(struct dp_debug *dp_debug);
+	void (*set_mst_con)(struct dp_debug *dp_debug, int con_id);
 };
 
 /**

+ 23 - 1
msm/dp/dp_display.c

@@ -2977,6 +2977,7 @@ static int dp_display_mst_connector_install(struct dp_display *dp_display,
 	struct dp_panel *dp_panel;
 	struct dp_display_private *dp;
 	struct dp_mst_connector *mst_connector;
+	struct dp_mst_connector *cached_connector;
 
 	if (!dp_display || !connector) {
 		DP_ERR("invalid input\n");
@@ -3031,7 +3032,19 @@ static int dp_display_mst_connector_install(struct dp_display *dp_display,
 		return -ENOMEM;
 	}
 
-	mst_connector->debug_en = false;
+	cached_connector = &dp->debug->mst_connector_cache;
+	if (cached_connector->debug_en) {
+		mst_connector->debug_en = true;
+		mst_connector->hdisplay = cached_connector->hdisplay;
+		mst_connector->vdisplay = cached_connector->vdisplay;
+		mst_connector->vrefresh = cached_connector->vrefresh;
+		mst_connector->aspect_ratio = cached_connector->aspect_ratio;
+		memset(cached_connector, 0, sizeof(*cached_connector));
+		dp->debug->set_mst_con(dp->debug, connector->base.id);
+	} else {
+		mst_connector->debug_en = false;
+	}
+
 	mst_connector->conn = connector;
 	mst_connector->con_id = connector->base.id;
 	mst_connector->state = connector_status_unknown;
@@ -3089,6 +3102,15 @@ static int dp_display_mst_connector_uninstall(struct dp_display *dp_display,
 	list_for_each_entry_safe(con_to_remove, temp_con,
 			&dp->debug->dp_mst_connector_list.list, list) {
 		if (con_to_remove->conn == connector) {
+			/*
+			 * cache any debug info if enabled that can be applied
+			 * on new connectors.
+			 */
+			if (con_to_remove->debug_en)
+				memcpy(&dp->debug->mst_connector_cache,
+						con_to_remove,
+						sizeof(*con_to_remove));
+
 			list_del(&con_to_remove->list);
 			kfree(con_to_remove);
 		}