From d767013a106a8c489c0f2f952fbc301130d6fe54 Mon Sep 17 00:00:00 2001 From: Rajkumar Subbiah Date: Thu, 23 Jul 2020 12:56:35 -0400 Subject: [PATCH] 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 --- msm/dp/dp_debug.c | 34 ++++++++++++++++++++++++++++++---- msm/dp/dp_debug.h | 3 ++- msm/dp/dp_display.c | 24 +++++++++++++++++++++++- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/msm/dp/dp_debug.c b/msm/dp/dp_debug.c index cf9efabc9259..0f156ad95f6f 100644 --- a/msm/dp/dp_debug.c +++ b/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); diff --git a/msm/dp/dp_debug.h b/msm/dp/dp_debug.h index 65874f2132bd..0a5ee89ba272 100644 --- a/msm/dp/dp_debug.h +++ b/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); }; /** diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index 2c9e323b2fbc..caeba8da53d2 100644 --- a/msm/dp/dp_display.c +++ b/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); }