Loading msm/dp/dp_mst_drm.c +64 −9 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ #include <drm/drm_crtc.h> #include <drm/drm_dp_mst_helper.h> #include <drm/drm_fixed.h> #include <drm/drm_connector.h> #include <drm/drm_dp_helper.h> #include "msm_drv.h" #include "msm_kms.h" Loading Loading @@ -151,6 +153,7 @@ struct dp_mst_private { const struct dp_drm_mst_fw_helper_ops *mst_fw_cbs; struct dp_mst_sim_mode simulator; struct mutex mst_lock; struct mutex edid_lock; enum dp_drv_state state; bool mst_session_state; }; Loading Loading @@ -1379,23 +1382,50 @@ static int dp_mst_connector_get_modes(struct drm_connector *connector, struct sde_connector *c_conn = to_sde_connector(connector); struct dp_display *dp_display = display; struct dp_mst_private *mst = dp_display->dp_mst_prv_info; struct edid *edid; int rc = 0; struct edid *edid = NULL; DP_MST_DEBUG("enter:\n"); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, connector->base.id); edid = mst->mst_fw_cbs->get_edid(connector, &mst->mst_mgr, c_conn->mst_port); mutex_lock(&mst->edid_lock); if (c_conn->cached_edid) goto duplicate_edid; mutex_unlock(&mst->edid_lock); edid = mst->mst_fw_cbs->get_edid(connector, &mst->mst_mgr, c_conn->mst_port); if (!edid) { DP_MST_DEBUG("get edid failed. id: %d\n", connector->base.id); goto end; } mutex_lock(&mst->edid_lock); c_conn->cached_edid = edid; duplicate_edid: edid = drm_edid_duplicate(c_conn->cached_edid); mutex_unlock(&mst->edid_lock); if (IS_ERR(edid)) { rc = PTR_ERR(edid); DP_MST_DEBUG("edid duplication failed. id: %d\n", connector->base.id); goto end; } if (edid) rc = dp_display->mst_connector_update_edid(dp_display, connector, edid); DP_MST_DEBUG("mst connector get modes. id: %d\n", connector->base.id); DP_MST_DEBUG("exit:\n"); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, connector->base.id); end: DP_MST_DEBUG("exit: id: %d rc: %d\n", connector->base.id, rc); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, connector->base.id, rc); return rc; } Loading Loading @@ -1728,6 +1758,9 @@ static void dp_mst_connector_pre_destroy(struct drm_connector *connector, DP_MST_DEBUG("enter:\n"); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, conn_id); kfree(c_conn->cached_edid); c_conn->cached_edid = NULL; drm_dp_mst_put_port_malloc(c_conn->mst_port); dp_display->mst_connector_uninstall(dp_display, connector); Loading Loading @@ -2227,6 +2260,9 @@ static void dp_mst_display_hpd_irq(void *dp_display, u8 esi[14]; unsigned int esi_res = DP_SINK_COUNT_ESI + 1; bool handled; struct drm_connector_list_iter conn_iter; struct drm_connector *conn; struct sde_connector *c_conn; if (info->mst_hpd_sim) { if (mst->simulator.mst_state && (info->mst_sim_add_con || Loading Loading @@ -2269,6 +2305,22 @@ static void dp_mst_display_hpd_irq(void *dp_display, if (handled) { rc = drm_dp_dpcd_write(mst->caps.drm_aux, esi_res, &esi[1], 3); if (esi[1] & DP_UP_REQ_MSG_RDY) { drm_connector_list_iter_begin(dp->drm_dev, &conn_iter); drm_for_each_connector_iter(conn, &conn_iter) { c_conn = to_sde_connector(conn); if (!c_conn->mst_port) continue; mutex_lock(&mst->edid_lock); kfree(c_conn->cached_edid); c_conn->cached_edid = NULL; mutex_unlock(&mst->edid_lock); } drm_connector_list_iter_end(&conn_iter); } if (rc != 3) DP_ERR("dpcd esi_res failed. rlen=%d\n", rc); } Loading Loading @@ -2354,6 +2406,7 @@ int dp_mst_init(struct dp_display *dp_display) dp_mst.dp_display = dp_display; mutex_init(&dp_mst.mst_lock); mutex_init(&dp_mst.edid_lock); ret = drm_dp_mst_topology_mgr_init(&dp_mst.mst_mgr, dev, dp_mst.caps.drm_aux, Loading Loading @@ -2386,6 +2439,7 @@ int dp_mst_init(struct dp_display *dp_display) error: mutex_destroy(&dp_mst.mst_lock); mutex_destroy(&dp_mst.edid_lock); return ret; } Loading @@ -2410,6 +2464,7 @@ void dp_mst_deinit(struct dp_display *dp_display) dp_mst.mst_initialized = false; mutex_destroy(&mst->mst_lock); mutex_destroy(&mst->edid_lock); DP_MST_INFO("dp drm mst topology manager deinit completed\n"); } Loading msm/sde/sde_connector.h +3 −0 Original line number Diff line number Diff line Loading @@ -481,6 +481,7 @@ struct sde_connector_dyn_hdr_metadata { * @hdr_capable: external hdr support present * @cmd_rx_buf: the return buffer of response of command transfer * @rx_len: the length of dcs command received buffer * @cached_edid: cached edid data for the connector */ struct sde_connector { struct drm_connector base; Loading Loading @@ -550,6 +551,8 @@ struct sde_connector { u8 cmd_rx_buf[MAX_CMD_RECEIVE_SIZE]; int rx_len; struct edid *cached_edid; }; /** Loading Loading
msm/dp/dp_mst_drm.c +64 −9 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ #include <drm/drm_crtc.h> #include <drm/drm_dp_mst_helper.h> #include <drm/drm_fixed.h> #include <drm/drm_connector.h> #include <drm/drm_dp_helper.h> #include "msm_drv.h" #include "msm_kms.h" Loading Loading @@ -151,6 +153,7 @@ struct dp_mst_private { const struct dp_drm_mst_fw_helper_ops *mst_fw_cbs; struct dp_mst_sim_mode simulator; struct mutex mst_lock; struct mutex edid_lock; enum dp_drv_state state; bool mst_session_state; }; Loading Loading @@ -1379,23 +1382,50 @@ static int dp_mst_connector_get_modes(struct drm_connector *connector, struct sde_connector *c_conn = to_sde_connector(connector); struct dp_display *dp_display = display; struct dp_mst_private *mst = dp_display->dp_mst_prv_info; struct edid *edid; int rc = 0; struct edid *edid = NULL; DP_MST_DEBUG("enter:\n"); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, connector->base.id); edid = mst->mst_fw_cbs->get_edid(connector, &mst->mst_mgr, c_conn->mst_port); mutex_lock(&mst->edid_lock); if (c_conn->cached_edid) goto duplicate_edid; mutex_unlock(&mst->edid_lock); edid = mst->mst_fw_cbs->get_edid(connector, &mst->mst_mgr, c_conn->mst_port); if (!edid) { DP_MST_DEBUG("get edid failed. id: %d\n", connector->base.id); goto end; } mutex_lock(&mst->edid_lock); c_conn->cached_edid = edid; duplicate_edid: edid = drm_edid_duplicate(c_conn->cached_edid); mutex_unlock(&mst->edid_lock); if (IS_ERR(edid)) { rc = PTR_ERR(edid); DP_MST_DEBUG("edid duplication failed. id: %d\n", connector->base.id); goto end; } if (edid) rc = dp_display->mst_connector_update_edid(dp_display, connector, edid); DP_MST_DEBUG("mst connector get modes. id: %d\n", connector->base.id); DP_MST_DEBUG("exit:\n"); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, connector->base.id); end: DP_MST_DEBUG("exit: id: %d rc: %d\n", connector->base.id, rc); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, connector->base.id, rc); return rc; } Loading Loading @@ -1728,6 +1758,9 @@ static void dp_mst_connector_pre_destroy(struct drm_connector *connector, DP_MST_DEBUG("enter:\n"); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, conn_id); kfree(c_conn->cached_edid); c_conn->cached_edid = NULL; drm_dp_mst_put_port_malloc(c_conn->mst_port); dp_display->mst_connector_uninstall(dp_display, connector); Loading Loading @@ -2227,6 +2260,9 @@ static void dp_mst_display_hpd_irq(void *dp_display, u8 esi[14]; unsigned int esi_res = DP_SINK_COUNT_ESI + 1; bool handled; struct drm_connector_list_iter conn_iter; struct drm_connector *conn; struct sde_connector *c_conn; if (info->mst_hpd_sim) { if (mst->simulator.mst_state && (info->mst_sim_add_con || Loading Loading @@ -2269,6 +2305,22 @@ static void dp_mst_display_hpd_irq(void *dp_display, if (handled) { rc = drm_dp_dpcd_write(mst->caps.drm_aux, esi_res, &esi[1], 3); if (esi[1] & DP_UP_REQ_MSG_RDY) { drm_connector_list_iter_begin(dp->drm_dev, &conn_iter); drm_for_each_connector_iter(conn, &conn_iter) { c_conn = to_sde_connector(conn); if (!c_conn->mst_port) continue; mutex_lock(&mst->edid_lock); kfree(c_conn->cached_edid); c_conn->cached_edid = NULL; mutex_unlock(&mst->edid_lock); } drm_connector_list_iter_end(&conn_iter); } if (rc != 3) DP_ERR("dpcd esi_res failed. rlen=%d\n", rc); } Loading Loading @@ -2354,6 +2406,7 @@ int dp_mst_init(struct dp_display *dp_display) dp_mst.dp_display = dp_display; mutex_init(&dp_mst.mst_lock); mutex_init(&dp_mst.edid_lock); ret = drm_dp_mst_topology_mgr_init(&dp_mst.mst_mgr, dev, dp_mst.caps.drm_aux, Loading Loading @@ -2386,6 +2439,7 @@ int dp_mst_init(struct dp_display *dp_display) error: mutex_destroy(&dp_mst.mst_lock); mutex_destroy(&dp_mst.edid_lock); return ret; } Loading @@ -2410,6 +2464,7 @@ void dp_mst_deinit(struct dp_display *dp_display) dp_mst.mst_initialized = false; mutex_destroy(&mst->mst_lock); mutex_destroy(&mst->edid_lock); DP_MST_INFO("dp drm mst topology manager deinit completed\n"); } Loading
msm/sde/sde_connector.h +3 −0 Original line number Diff line number Diff line Loading @@ -481,6 +481,7 @@ struct sde_connector_dyn_hdr_metadata { * @hdr_capable: external hdr support present * @cmd_rx_buf: the return buffer of response of command transfer * @rx_len: the length of dcs command received buffer * @cached_edid: cached edid data for the connector */ struct sde_connector { struct drm_connector base; Loading Loading @@ -550,6 +551,8 @@ struct sde_connector { u8 cmd_rx_buf[MAX_CMD_RECEIVE_SIZE]; int rx_len; struct edid *cached_edid; }; /** Loading