Loading drivers/gpu/drm/msm/dp/dp_debug.c +11 −0 Original line number Diff line number Diff line Loading @@ -1946,6 +1946,17 @@ static int dp_debug_init(struct dp_debug *dp_debug) goto error_remove_dir; } file = debugfs_create_bool("hdcp_wait_sink_sync", 0644, dir, &debug->dp_debug.hdcp_wait_sink_sync); if (IS_ERR_OR_NULL(file)) { rc = PTR_ERR(file); pr_err("[%s] debugfs hdcp_wait_sink_sync failed, rc=%d\n", DEBUG_NAME, rc); goto error_remove_dir; } file = debugfs_create_bool("dsc_feature_enable", 0644, dir, &debug->parser->dsc_feature_enable); if (IS_ERR_OR_NULL(file)) { Loading drivers/gpu/drm/msm/dp/dp_debug.h +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ /** * struct dp_debug * @debug_en: specifies whether debug mode enabled * @hdcp_wait_sink_sync: used to wait for sink synchronization before HDCP auth * @vdisplay: used to filter out vdisplay value * @hdisplay: used to filter out hdisplay value * @vrefresh: used to filter out vrefresh value Loading @@ -37,6 +38,7 @@ struct dp_debug { bool sim_mode; bool psm_enabled; bool hdcp_disabled; bool hdcp_wait_sink_sync; int aspect_ratio; int vdisplay; int hdisplay; Loading drivers/gpu/drm/msm/dp/dp_display.c +40 −17 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ struct dp_display_private { struct mutex session_lock; bool suspended; bool hdcp_delayed_off; bool hdcp_abort; u32 active_stream_cnt; struct dp_mst mst; Loading Loading @@ -339,7 +340,8 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) dp = container_of(dw, struct dp_display_private, hdcp_cb_work); if (!dp->power_on || !dp->is_connected || atomic_read(&dp->aborted)) if (!dp->power_on || !dp->is_connected || atomic_read(&dp->aborted) || dp->hdcp_abort) return; if (dp->suspended) { Loading @@ -355,13 +357,17 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) dp->hdcp_delayed_off = false; } drm_dp_dpcd_readb(dp->aux->drm_aux, DP_SINK_STATUS, &sink_status); sink_status &= (DP_RECEIVE_PORT_0_STATUS | DP_RECEIVE_PORT_1_STATUS); if (dp->debug->hdcp_wait_sink_sync) { drm_dp_dpcd_readb(dp->aux->drm_aux, DP_SINK_STATUS, &sink_status); sink_status &= (DP_RECEIVE_PORT_0_STATUS | DP_RECEIVE_PORT_1_STATUS); if (sink_status < 1) { pr_debug("Sink not synchronized. Queuing again then exiting\n"); queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ); return; } } status = &dp->link->hdcp_status; Loading @@ -375,7 +381,6 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) dp_display_update_hdcp_status(dp, true); return; } status->hdcp_state = HDCP_STATE_AUTHENTICATING; } else { dp_display_update_hdcp_status(dp, true); return; Loading @@ -400,10 +405,12 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) ops->force_encryption(data, dp->debug->force_encryption); switch (status->hdcp_state) { case HDCP_STATE_AUTHENTICATING: case HDCP_STATE_INACTIVE: dp_display_hdcp_register_streams(dp); if (dp->hdcp.ops && dp->hdcp.ops->authenticate) rc = dp->hdcp.ops->authenticate(data); if (!rc) status->hdcp_state = HDCP_STATE_AUTHENTICATING; break; case HDCP_STATE_AUTH_FAIL: if (dp_display_is_ready(dp) && dp->power_on) { Loading Loading @@ -1730,16 +1737,18 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel) goto end; } dp->hdcp_abort = true; cancel_delayed_work_sync(&dp->hdcp_cb_work); if (dp_display_is_hdcp_enabled(dp) && status->hdcp_state != HDCP_STATE_INACTIVE) { bool off = true; if (dp->suspended) { pr_debug("Can't perform HDCP cleanup while suspended. Defer\n"); dp->hdcp_delayed_off = true; goto stream; goto clean; } flush_delayed_work(&dp->hdcp_cb_work); if (dp->mst.mst_active) { dp_display_hdcp_deregister_stream(dp, dp_panel->stream_id); Loading @@ -1747,18 +1756,19 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel) if (i != dp_panel->stream_id && dp->active_panels[i]) { pr_debug("Streams are still active. Skip disabling HDCP\n"); goto stream; off = false; } } } if (off) { if (dp->hdcp.ops->off) dp->hdcp.ops->off(dp->hdcp.data); dp_display_update_hdcp_status(dp, true); } } stream: clean: if (dp_panel->audio_supported) dp_panel->audio->off(dp_panel->audio); Loading @@ -1771,8 +1781,10 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel) static int dp_display_disable(struct dp_display *dp_display, void *panel) { int i; struct dp_display_private *dp = NULL; struct dp_panel *dp_panel = NULL; struct dp_link_hdcp_status *status; if (!dp_display || !panel) { pr_err("invalid input\n"); Loading @@ -1781,6 +1793,7 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel) dp = container_of(dp_display, struct dp_display_private, dp_display); dp_panel = panel; status = &dp->link->hdcp_status; mutex_lock(&dp->session_lock); Loading @@ -1791,6 +1804,16 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel) dp_display_stream_disable(dp, dp_panel); dp_display_update_dsc_resources(dp, dp_panel, false); dp->hdcp_abort = false; for (i = DP_STREAM_0; i < DP_STREAM_MAX; i++) { if (dp->active_panels[i]) { if (status->hdcp_state != HDCP_STATE_AUTHENTICATED) queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ/4); break; } } end: mutex_unlock(&dp->session_lock); return 0; Loading drivers/gpu/drm/msm/dp/dp_parser.c +8 −11 Original line number Diff line number Diff line Loading @@ -205,14 +205,13 @@ static int dp_parser_msm_hdcp_dev(struct dp_parser *parser) static int dp_parser_pinctrl(struct dp_parser *parser) { int rc = 0; struct dp_pinctrl *pinctrl = &parser->pinctrl; pinctrl->pin = devm_pinctrl_get(&parser->pdev->dev); if (IS_ERR_OR_NULL(pinctrl->pin)) { pr_debug("failed to get pinctrl, rc=%d\n", rc); goto error; pr_debug("failed to get pinctrl\n"); return 0; } if (parser->no_aux_switch && parser->lphw_hpd) { Loading @@ -235,20 +234,18 @@ static int dp_parser_pinctrl(struct dp_parser *parser) pinctrl->state_active = pinctrl_lookup_state(pinctrl->pin, "mdss_dp_active"); if (IS_ERR_OR_NULL(pinctrl->state_active)) { rc = PTR_ERR(pinctrl->state_active); pr_err("failed to get pinctrl active state, rc=%d\n", rc); goto error; pinctrl->state_active = NULL; pr_debug("failed to get pinctrl active state\n"); } pinctrl->state_suspend = pinctrl_lookup_state(pinctrl->pin, "mdss_dp_sleep"); if (IS_ERR_OR_NULL(pinctrl->state_suspend)) { rc = PTR_ERR(pinctrl->state_suspend); pr_err("failed to get pinctrl suspend state, rc=%d\n", rc); goto error; pinctrl->state_suspend = NULL; pr_debug("failed to get pinctrl suspend state\n"); } error: return rc; return 0; } static int dp_parser_gpio(struct dp_parser *parser) Loading drivers/gpu/drm/msm/dp/dp_power.c +1 −8 Original line number Diff line number Diff line Loading @@ -117,7 +117,7 @@ static int dp_power_regulator_ctrl(struct dp_power_private *power, bool enable) static int dp_power_pinctrl_set(struct dp_power_private *power, bool active) { int rc = -EFAULT; int rc = 0; struct pinctrl_state *pin_state; struct dp_parser *parser; Loading @@ -140,9 +140,6 @@ static int dp_power_pinctrl_set(struct dp_power_private *power, bool active) } } if (parser->no_aux_switch) return 0; pin_state = active ? parser->pinctrl.state_active : parser->pinctrl.state_suspend; if (!IS_ERR_OR_NULL(pin_state)) { Loading @@ -152,10 +149,6 @@ static int dp_power_pinctrl_set(struct dp_power_private *power, bool active) pr_err("can not set %s pins\n", active ? "dp_active" : "dp_sleep"); } else { pr_err("invalid '%s' pinstate\n", active ? "dp_active" : "dp_sleep"); } return rc; Loading Loading
drivers/gpu/drm/msm/dp/dp_debug.c +11 −0 Original line number Diff line number Diff line Loading @@ -1946,6 +1946,17 @@ static int dp_debug_init(struct dp_debug *dp_debug) goto error_remove_dir; } file = debugfs_create_bool("hdcp_wait_sink_sync", 0644, dir, &debug->dp_debug.hdcp_wait_sink_sync); if (IS_ERR_OR_NULL(file)) { rc = PTR_ERR(file); pr_err("[%s] debugfs hdcp_wait_sink_sync failed, rc=%d\n", DEBUG_NAME, rc); goto error_remove_dir; } file = debugfs_create_bool("dsc_feature_enable", 0644, dir, &debug->parser->dsc_feature_enable); if (IS_ERR_OR_NULL(file)) { Loading
drivers/gpu/drm/msm/dp/dp_debug.h +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ /** * struct dp_debug * @debug_en: specifies whether debug mode enabled * @hdcp_wait_sink_sync: used to wait for sink synchronization before HDCP auth * @vdisplay: used to filter out vdisplay value * @hdisplay: used to filter out hdisplay value * @vrefresh: used to filter out vrefresh value Loading @@ -37,6 +38,7 @@ struct dp_debug { bool sim_mode; bool psm_enabled; bool hdcp_disabled; bool hdcp_wait_sink_sync; int aspect_ratio; int vdisplay; int hdisplay; Loading
drivers/gpu/drm/msm/dp/dp_display.c +40 −17 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ struct dp_display_private { struct mutex session_lock; bool suspended; bool hdcp_delayed_off; bool hdcp_abort; u32 active_stream_cnt; struct dp_mst mst; Loading Loading @@ -339,7 +340,8 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) dp = container_of(dw, struct dp_display_private, hdcp_cb_work); if (!dp->power_on || !dp->is_connected || atomic_read(&dp->aborted)) if (!dp->power_on || !dp->is_connected || atomic_read(&dp->aborted) || dp->hdcp_abort) return; if (dp->suspended) { Loading @@ -355,13 +357,17 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) dp->hdcp_delayed_off = false; } drm_dp_dpcd_readb(dp->aux->drm_aux, DP_SINK_STATUS, &sink_status); sink_status &= (DP_RECEIVE_PORT_0_STATUS | DP_RECEIVE_PORT_1_STATUS); if (dp->debug->hdcp_wait_sink_sync) { drm_dp_dpcd_readb(dp->aux->drm_aux, DP_SINK_STATUS, &sink_status); sink_status &= (DP_RECEIVE_PORT_0_STATUS | DP_RECEIVE_PORT_1_STATUS); if (sink_status < 1) { pr_debug("Sink not synchronized. Queuing again then exiting\n"); queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ); return; } } status = &dp->link->hdcp_status; Loading @@ -375,7 +381,6 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) dp_display_update_hdcp_status(dp, true); return; } status->hdcp_state = HDCP_STATE_AUTHENTICATING; } else { dp_display_update_hdcp_status(dp, true); return; Loading @@ -400,10 +405,12 @@ static void dp_display_hdcp_cb_work(struct work_struct *work) ops->force_encryption(data, dp->debug->force_encryption); switch (status->hdcp_state) { case HDCP_STATE_AUTHENTICATING: case HDCP_STATE_INACTIVE: dp_display_hdcp_register_streams(dp); if (dp->hdcp.ops && dp->hdcp.ops->authenticate) rc = dp->hdcp.ops->authenticate(data); if (!rc) status->hdcp_state = HDCP_STATE_AUTHENTICATING; break; case HDCP_STATE_AUTH_FAIL: if (dp_display_is_ready(dp) && dp->power_on) { Loading Loading @@ -1730,16 +1737,18 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel) goto end; } dp->hdcp_abort = true; cancel_delayed_work_sync(&dp->hdcp_cb_work); if (dp_display_is_hdcp_enabled(dp) && status->hdcp_state != HDCP_STATE_INACTIVE) { bool off = true; if (dp->suspended) { pr_debug("Can't perform HDCP cleanup while suspended. Defer\n"); dp->hdcp_delayed_off = true; goto stream; goto clean; } flush_delayed_work(&dp->hdcp_cb_work); if (dp->mst.mst_active) { dp_display_hdcp_deregister_stream(dp, dp_panel->stream_id); Loading @@ -1747,18 +1756,19 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel) if (i != dp_panel->stream_id && dp->active_panels[i]) { pr_debug("Streams are still active. Skip disabling HDCP\n"); goto stream; off = false; } } } if (off) { if (dp->hdcp.ops->off) dp->hdcp.ops->off(dp->hdcp.data); dp_display_update_hdcp_status(dp, true); } } stream: clean: if (dp_panel->audio_supported) dp_panel->audio->off(dp_panel->audio); Loading @@ -1771,8 +1781,10 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel) static int dp_display_disable(struct dp_display *dp_display, void *panel) { int i; struct dp_display_private *dp = NULL; struct dp_panel *dp_panel = NULL; struct dp_link_hdcp_status *status; if (!dp_display || !panel) { pr_err("invalid input\n"); Loading @@ -1781,6 +1793,7 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel) dp = container_of(dp_display, struct dp_display_private, dp_display); dp_panel = panel; status = &dp->link->hdcp_status; mutex_lock(&dp->session_lock); Loading @@ -1791,6 +1804,16 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel) dp_display_stream_disable(dp, dp_panel); dp_display_update_dsc_resources(dp, dp_panel, false); dp->hdcp_abort = false; for (i = DP_STREAM_0; i < DP_STREAM_MAX; i++) { if (dp->active_panels[i]) { if (status->hdcp_state != HDCP_STATE_AUTHENTICATED) queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ/4); break; } } end: mutex_unlock(&dp->session_lock); return 0; Loading
drivers/gpu/drm/msm/dp/dp_parser.c +8 −11 Original line number Diff line number Diff line Loading @@ -205,14 +205,13 @@ static int dp_parser_msm_hdcp_dev(struct dp_parser *parser) static int dp_parser_pinctrl(struct dp_parser *parser) { int rc = 0; struct dp_pinctrl *pinctrl = &parser->pinctrl; pinctrl->pin = devm_pinctrl_get(&parser->pdev->dev); if (IS_ERR_OR_NULL(pinctrl->pin)) { pr_debug("failed to get pinctrl, rc=%d\n", rc); goto error; pr_debug("failed to get pinctrl\n"); return 0; } if (parser->no_aux_switch && parser->lphw_hpd) { Loading @@ -235,20 +234,18 @@ static int dp_parser_pinctrl(struct dp_parser *parser) pinctrl->state_active = pinctrl_lookup_state(pinctrl->pin, "mdss_dp_active"); if (IS_ERR_OR_NULL(pinctrl->state_active)) { rc = PTR_ERR(pinctrl->state_active); pr_err("failed to get pinctrl active state, rc=%d\n", rc); goto error; pinctrl->state_active = NULL; pr_debug("failed to get pinctrl active state\n"); } pinctrl->state_suspend = pinctrl_lookup_state(pinctrl->pin, "mdss_dp_sleep"); if (IS_ERR_OR_NULL(pinctrl->state_suspend)) { rc = PTR_ERR(pinctrl->state_suspend); pr_err("failed to get pinctrl suspend state, rc=%d\n", rc); goto error; pinctrl->state_suspend = NULL; pr_debug("failed to get pinctrl suspend state\n"); } error: return rc; return 0; } static int dp_parser_gpio(struct dp_parser *parser) Loading
drivers/gpu/drm/msm/dp/dp_power.c +1 −8 Original line number Diff line number Diff line Loading @@ -117,7 +117,7 @@ static int dp_power_regulator_ctrl(struct dp_power_private *power, bool enable) static int dp_power_pinctrl_set(struct dp_power_private *power, bool active) { int rc = -EFAULT; int rc = 0; struct pinctrl_state *pin_state; struct dp_parser *parser; Loading @@ -140,9 +140,6 @@ static int dp_power_pinctrl_set(struct dp_power_private *power, bool active) } } if (parser->no_aux_switch) return 0; pin_state = active ? parser->pinctrl.state_active : parser->pinctrl.state_suspend; if (!IS_ERR_OR_NULL(pin_state)) { Loading @@ -152,10 +149,6 @@ static int dp_power_pinctrl_set(struct dp_power_private *power, bool active) pr_err("can not set %s pins\n", active ? "dp_active" : "dp_sleep"); } else { pr_err("invalid '%s' pinstate\n", active ? "dp_active" : "dp_sleep"); } return rc; Loading