Loading msm/dp/dp_display.c +68 −70 Original line number Diff line number Diff line Loading @@ -807,7 +807,7 @@ static const struct component_ops dp_display_comp_ops = { .unbind = dp_display_unbind, }; static void dp_display_send_hpd_event(struct dp_display_private *dp) static bool dp_display_send_hpd_event(struct dp_display_private *dp) { struct drm_device *dev = NULL; struct drm_connector *connector; Loading @@ -816,24 +816,18 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp) char *envp[5]; int rc = 0; if (dp->mst.mst_active) { DP_DEBUG("skip notification for mst mode\n"); dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED); return; } connector = dp->dp_display.base_connector; if (!connector) { DP_ERR("connector not set\n"); return; return false; } connector->status = connector->funcs->detect(connector, false); if (dp->cached_connector_status == connector->status) { DP_DEBUG("connector status (%d) unchanged, skipping uevent\n", dp->cached_connector_status); return; return false; } dp->cached_connector_status = connector->status; Loading @@ -842,7 +836,7 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp) if (dp->debug->skip_uevent) { DP_INFO("skipping uevent\n"); goto update_state; return false; } snprintf(name, HPD_STRING_SIZE, "name=%s", connector->name); Loading @@ -864,14 +858,7 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp) rc = kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); DP_INFO("uevent %s: %d\n", rc ? "failure" : "success", rc); update_state: if (connector->status == connector_status_connected) { dp_display_state_add(DP_STATE_CONNECT_NOTIFIED); dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED); } else { dp_display_state_add(DP_STATE_DISCONNECT_NOTIFIED); dp_display_state_remove(DP_STATE_CONNECT_NOTIFIED); } return true; } static int dp_display_send_hpd_notification(struct dp_display_private *dp) Loading Loading @@ -900,13 +887,29 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp) dp->aux->state |= DP_STATE_NOTIFICATION_SENT; if (!dp->mst.mst_active) reinit_completion(&dp->notification_comp); if (!dp->mst.mst_active) { dp->dp_display.is_sst_connected = hpd; else if (!dp_display_send_hpd_event(dp)) goto skip_wait; } else { dp->dp_display.is_sst_connected = false; reinit_completion(&dp->notification_comp); dp_display_send_hpd_event(dp); if (!dp->mst.cbs.hpd) goto skip_wait; dp->mst.cbs.hpd(&dp->dp_display, true); } if (hpd) { dp_display_state_add(DP_STATE_CONNECT_NOTIFIED); dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED); } else { dp_display_state_add(DP_STATE_DISCONNECT_NOTIFIED); dp_display_state_remove(DP_STATE_CONNECT_NOTIFIED); } /* * Skip the wait if TUI is active considering that the user mode will Loading Loading @@ -942,11 +945,9 @@ static void dp_display_update_mst_state(struct dp_display_private *dp, dp->panel->mst_state = state; } static void dp_display_process_mst_hpd_high(struct dp_display_private *dp, bool mst_probe) static void dp_display_mst_init(struct dp_display_private *dp) { bool is_mst_receiver; struct dp_mst_hpd_info info; const unsigned long clear_mstm_ctrl_timeout_us = 100000; u8 old_mstm_ctrl; int ret; Loading @@ -957,9 +958,6 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp, return; } DP_MST_DEBUG("mst_hpd_high work. mst_probe:%d\n", mst_probe); if (!dp->mst.mst_active) { is_mst_receiver = dp->panel->read_mst_cap(dp->panel); if (!is_mst_receiver) { Loading @@ -968,8 +966,7 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp, } /* clear sink mst state */ drm_dp_dpcd_readb(dp->aux->drm_aux, DP_MSTM_CTRL, &old_mstm_ctrl); drm_dp_dpcd_readb(dp->aux->drm_aux, DP_MSTM_CTRL, &old_mstm_ctrl); drm_dp_dpcd_writeb(dp->aux->drm_aux, DP_MSTM_CTRL, 0); /* add extra delay if MST state is not cleared */ Loading @@ -988,19 +985,26 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp, } dp_display_update_mst_state(dp, true); } else if (dp->mst.mst_active && mst_probe) { } static void dp_display_set_mst_mgr_state(struct dp_display_private *dp, bool state) { struct dp_mst_hpd_info info = {0}; if (!dp->mst.mst_active) return; info.mst_protocol = dp->parser->has_mst_sideband; if (state) { info.mst_port_cnt = dp->debug->mst_port_cnt; info.edid = dp->debug->get_edid(dp->debug); } if (dp->mst.cbs.set_mgr_state) dp->mst.cbs.set_mgr_state(&dp->dp_display, true, &info); if (dp->mst.cbs.hpd) dp->mst.cbs.hpd(&dp->dp_display, true); } dp->mst.cbs.set_mgr_state(&dp->dp_display, state, &info); DP_MST_DEBUG("mst_hpd_high. mst_active:%d\n", dp->mst.mst_active); DP_MST_DEBUG("mst_mgr_state: %d\n", state); } static int dp_display_host_init(struct dp_display_private *dp) Loading Loading @@ -1210,7 +1214,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp->link->process_request(dp->link); dp->panel->handle_sink_request(dp->panel); dp_display_process_mst_hpd_high(dp, false); dp_display_mst_init(dp); rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp->panel->fec_en, dp->panel->dsc_en, false); Loading @@ -1221,7 +1225,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp->process_hpd_connect = false; dp_display_process_mst_hpd_high(dp, true); dp_display_set_mst_mgr_state(dp, true); end: mutex_unlock(&dp->session_lock); Loading Loading @@ -1270,7 +1274,6 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) static void dp_display_process_mst_hpd_low(struct dp_display_private *dp) { int rc = 0; struct dp_mst_hpd_info info = {0}; if (dp->mst.mst_active) { DP_MST_DEBUG("mst_hpd_low work\n"); Loading @@ -1286,17 +1289,12 @@ static void dp_display_process_mst_hpd_low(struct dp_display_private *dp) if (dp->mst.cbs.hpd) dp->mst.cbs.hpd(&dp->dp_display, false); dp_display_update_mst_state(dp, false); if ((dp_display_state_is(DP_STATE_CONNECT_NOTIFIED) || dp_display_state_is(DP_STATE_ENABLED))) rc = dp_display_send_hpd_notification(dp); if (dp->mst.cbs.set_mgr_state) { info.mst_protocol = dp->parser->has_mst_sideband; dp->mst.cbs.set_mgr_state(&dp->dp_display, false, &info); } dp_display_update_mst_state(dp, false); dp_display_set_mst_mgr_state(dp, false); } DP_MST_DEBUG("mst_hpd_low. mst_active:%d\n", dp->mst.mst_active); Loading Loading
msm/dp/dp_display.c +68 −70 Original line number Diff line number Diff line Loading @@ -807,7 +807,7 @@ static const struct component_ops dp_display_comp_ops = { .unbind = dp_display_unbind, }; static void dp_display_send_hpd_event(struct dp_display_private *dp) static bool dp_display_send_hpd_event(struct dp_display_private *dp) { struct drm_device *dev = NULL; struct drm_connector *connector; Loading @@ -816,24 +816,18 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp) char *envp[5]; int rc = 0; if (dp->mst.mst_active) { DP_DEBUG("skip notification for mst mode\n"); dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED); return; } connector = dp->dp_display.base_connector; if (!connector) { DP_ERR("connector not set\n"); return; return false; } connector->status = connector->funcs->detect(connector, false); if (dp->cached_connector_status == connector->status) { DP_DEBUG("connector status (%d) unchanged, skipping uevent\n", dp->cached_connector_status); return; return false; } dp->cached_connector_status = connector->status; Loading @@ -842,7 +836,7 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp) if (dp->debug->skip_uevent) { DP_INFO("skipping uevent\n"); goto update_state; return false; } snprintf(name, HPD_STRING_SIZE, "name=%s", connector->name); Loading @@ -864,14 +858,7 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp) rc = kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); DP_INFO("uevent %s: %d\n", rc ? "failure" : "success", rc); update_state: if (connector->status == connector_status_connected) { dp_display_state_add(DP_STATE_CONNECT_NOTIFIED); dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED); } else { dp_display_state_add(DP_STATE_DISCONNECT_NOTIFIED); dp_display_state_remove(DP_STATE_CONNECT_NOTIFIED); } return true; } static int dp_display_send_hpd_notification(struct dp_display_private *dp) Loading Loading @@ -900,13 +887,29 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp) dp->aux->state |= DP_STATE_NOTIFICATION_SENT; if (!dp->mst.mst_active) reinit_completion(&dp->notification_comp); if (!dp->mst.mst_active) { dp->dp_display.is_sst_connected = hpd; else if (!dp_display_send_hpd_event(dp)) goto skip_wait; } else { dp->dp_display.is_sst_connected = false; reinit_completion(&dp->notification_comp); dp_display_send_hpd_event(dp); if (!dp->mst.cbs.hpd) goto skip_wait; dp->mst.cbs.hpd(&dp->dp_display, true); } if (hpd) { dp_display_state_add(DP_STATE_CONNECT_NOTIFIED); dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED); } else { dp_display_state_add(DP_STATE_DISCONNECT_NOTIFIED); dp_display_state_remove(DP_STATE_CONNECT_NOTIFIED); } /* * Skip the wait if TUI is active considering that the user mode will Loading Loading @@ -942,11 +945,9 @@ static void dp_display_update_mst_state(struct dp_display_private *dp, dp->panel->mst_state = state; } static void dp_display_process_mst_hpd_high(struct dp_display_private *dp, bool mst_probe) static void dp_display_mst_init(struct dp_display_private *dp) { bool is_mst_receiver; struct dp_mst_hpd_info info; const unsigned long clear_mstm_ctrl_timeout_us = 100000; u8 old_mstm_ctrl; int ret; Loading @@ -957,9 +958,6 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp, return; } DP_MST_DEBUG("mst_hpd_high work. mst_probe:%d\n", mst_probe); if (!dp->mst.mst_active) { is_mst_receiver = dp->panel->read_mst_cap(dp->panel); if (!is_mst_receiver) { Loading @@ -968,8 +966,7 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp, } /* clear sink mst state */ drm_dp_dpcd_readb(dp->aux->drm_aux, DP_MSTM_CTRL, &old_mstm_ctrl); drm_dp_dpcd_readb(dp->aux->drm_aux, DP_MSTM_CTRL, &old_mstm_ctrl); drm_dp_dpcd_writeb(dp->aux->drm_aux, DP_MSTM_CTRL, 0); /* add extra delay if MST state is not cleared */ Loading @@ -988,19 +985,26 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp, } dp_display_update_mst_state(dp, true); } else if (dp->mst.mst_active && mst_probe) { } static void dp_display_set_mst_mgr_state(struct dp_display_private *dp, bool state) { struct dp_mst_hpd_info info = {0}; if (!dp->mst.mst_active) return; info.mst_protocol = dp->parser->has_mst_sideband; if (state) { info.mst_port_cnt = dp->debug->mst_port_cnt; info.edid = dp->debug->get_edid(dp->debug); } if (dp->mst.cbs.set_mgr_state) dp->mst.cbs.set_mgr_state(&dp->dp_display, true, &info); if (dp->mst.cbs.hpd) dp->mst.cbs.hpd(&dp->dp_display, true); } dp->mst.cbs.set_mgr_state(&dp->dp_display, state, &info); DP_MST_DEBUG("mst_hpd_high. mst_active:%d\n", dp->mst.mst_active); DP_MST_DEBUG("mst_mgr_state: %d\n", state); } static int dp_display_host_init(struct dp_display_private *dp) Loading Loading @@ -1210,7 +1214,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp->link->process_request(dp->link); dp->panel->handle_sink_request(dp->panel); dp_display_process_mst_hpd_high(dp, false); dp_display_mst_init(dp); rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp->panel->fec_en, dp->panel->dsc_en, false); Loading @@ -1221,7 +1225,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) dp->process_hpd_connect = false; dp_display_process_mst_hpd_high(dp, true); dp_display_set_mst_mgr_state(dp, true); end: mutex_unlock(&dp->session_lock); Loading Loading @@ -1270,7 +1274,6 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) static void dp_display_process_mst_hpd_low(struct dp_display_private *dp) { int rc = 0; struct dp_mst_hpd_info info = {0}; if (dp->mst.mst_active) { DP_MST_DEBUG("mst_hpd_low work\n"); Loading @@ -1286,17 +1289,12 @@ static void dp_display_process_mst_hpd_low(struct dp_display_private *dp) if (dp->mst.cbs.hpd) dp->mst.cbs.hpd(&dp->dp_display, false); dp_display_update_mst_state(dp, false); if ((dp_display_state_is(DP_STATE_CONNECT_NOTIFIED) || dp_display_state_is(DP_STATE_ENABLED))) rc = dp_display_send_hpd_notification(dp); if (dp->mst.cbs.set_mgr_state) { info.mst_protocol = dp->parser->has_mst_sideband; dp->mst.cbs.set_mgr_state(&dp->dp_display, false, &info); } dp_display_update_mst_state(dp, false); dp_display_set_mst_mgr_state(dp, false); } DP_MST_DEBUG("mst_hpd_low. mst_active:%d\n", dp->mst.mst_active); Loading