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); }