Loading drivers/gpu/drm/msm/dp/dp_display.c +56 −25 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ struct dp_display_private { struct workqueue_struct *hdcp_workqueue; struct delayed_work hdcp_cb_work; struct mutex hdcp_mutex; struct mutex session_lock; int hdcp_status; }; Loading Loading @@ -500,6 +501,8 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, if (!wait_for_completion_timeout(&dp->notification_comp, HZ * 5)) { pr_warn("%s timeout\n", hpd ? "connect" : "disconnect"); /* cancel any pending request */ dp->ctrl->abort(dp->ctrl); return -EINVAL; } Loading Loading @@ -634,6 +637,7 @@ static void dp_display_clean(struct dp_display_private *dp) dp->ctrl->push_idle(dp->ctrl); dp->ctrl->off(dp->ctrl); dp->power_on = false; } static int dp_display_usbpd_disconnect_cb(struct device *dev) Loading Loading @@ -662,6 +666,8 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev) rc = dp_display_send_hpd_notification(dp, false); mutex_lock(&dp->session_lock); /* if cable is disconnected, reset psm_enabled flag */ if (!dp->usbpd->alt_mode_cfg_done) dp->link->psm_enabled = false; Loading @@ -670,6 +676,8 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev) dp_display_clean(dp); dp_display_host_deinit(dp); mutex_unlock(&dp->session_lock); end: return rc; } Loading Loading @@ -760,6 +768,7 @@ static void dp_display_deinit_sub_modules(struct dp_display_private *dp) dp_catalog_put(dp->catalog); dp_parser_put(dp->parser); dp_usbpd_put(dp->usbpd); mutex_destroy(&dp->session_lock); dp_debug_put(dp->debug); } Loading Loading @@ -787,6 +796,8 @@ static int dp_init_sub_modules(struct dp_display_private *dp) goto error; } mutex_init(&dp->session_lock); dp->parser = dp_parser_get(dp->pdev); if (IS_ERR(dp->parser)) { rc = PTR_ERR(dp->parser); Loading Loading @@ -890,6 +901,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp) dp_parser_put(dp->parser); error_parser: dp_usbpd_put(dp->usbpd); mutex_destroy(&dp->session_lock); error: return rc; } Loading @@ -897,20 +909,20 @@ static int dp_init_sub_modules(struct dp_display_private *dp) static int dp_display_set_mode(struct dp_display *dp_display, struct dp_display_mode *mode) { int rc = 0; struct dp_display_private *dp; if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto error; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); dp->panel->pinfo = mode->timing; dp->panel->init_info(dp->panel); error: return rc; mutex_unlock(&dp->session_lock); return 0; } static int dp_display_prepare(struct dp_display *dp) Loading @@ -925,37 +937,44 @@ static int dp_display_enable(struct dp_display *dp_display) if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto error; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); if (dp->power_on) { pr_debug("Link already setup, return\n"); return 0; goto end; } rc = dp->ctrl->on(dp->ctrl); if (!rc) dp->power_on = true; error: end: mutex_unlock(&dp->session_lock); return rc; } static int dp_display_post_enable(struct dp_display *dp_display) { int rc = 0; struct dp_display_private *dp; if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto end; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); if (!dp->power_on) { pr_debug("Link not setup, return\n"); goto end; } if (dp->audio_supported) { dp->audio->bw_code = dp->link->link_params.bw_code; dp->audio->lane_count = dp->link->link_params.lane_count; Loading @@ -973,23 +992,30 @@ static int dp_display_post_enable(struct dp_display *dp_display) queue_delayed_work(dp->hdcp_workqueue, &dp->hdcp_cb_work, HZ / 2); } end: return rc; mutex_unlock(&dp->session_lock); return 0; } static int dp_display_pre_disable(struct dp_display *dp_display) { int rc = 0; struct dp_display_private *dp; if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto error; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); if (!dp->power_on) { pr_debug("Link already powered off, return\n"); goto end; } if (dp_display_is_hdcp_enabled(dp)) { dp->hdcp_status = HDCP_STATE_INACTIVE; Loading @@ -1003,33 +1029,38 @@ static int dp_display_pre_disable(struct dp_display *dp_display) dp->link->psm_config(dp->link, &dp->panel->link_info, true); dp->ctrl->push_idle(dp->ctrl); error: return rc; end: mutex_unlock(&dp->session_lock); return 0; } static int dp_display_disable(struct dp_display *dp_display) { int rc = 0; struct dp_display_private *dp; if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto error; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); if (!dp->power_on || !dp->core_initialized) goto error; mutex_lock(&dp->session_lock); if (!dp->power_on || !dp->core_initialized) { pr_debug("Link already powered off, return\n"); goto end; } dp->ctrl->off(dp->ctrl); dp->power_on = false; end: complete_all(&dp->notification_comp); error: return rc; mutex_unlock(&dp->session_lock); return 0; } static int dp_request_irq(struct dp_display *dp_display) Loading drivers/gpu/drm/msm/dp/dp_power.c +9 −0 Original line number Diff line number Diff line Loading @@ -562,6 +562,15 @@ static int dp_power_deinit(struct dp_power *dp_power) power = container_of(dp_power, struct dp_power_private, dp_power); dp_power_clk_enable(dp_power, DP_CORE_PM, false); /* * If the display power on event was not successful, for example if * there was a link training failure, then the link clocks could * possibly still be on. In this scenario, we need to turn off the * link clocks as soon as the cable is disconnected so that the clock * state is cleaned up before subsequent connection events. */ if (power->link_clks_on) dp_power_clk_enable(dp_power, DP_CTRL_PM, false); rc = sde_power_resource_enable(power->phandle, power->dp_core_client, false); if (rc) { Loading Loading
drivers/gpu/drm/msm/dp/dp_display.c +56 −25 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ struct dp_display_private { struct workqueue_struct *hdcp_workqueue; struct delayed_work hdcp_cb_work; struct mutex hdcp_mutex; struct mutex session_lock; int hdcp_status; }; Loading Loading @@ -500,6 +501,8 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, if (!wait_for_completion_timeout(&dp->notification_comp, HZ * 5)) { pr_warn("%s timeout\n", hpd ? "connect" : "disconnect"); /* cancel any pending request */ dp->ctrl->abort(dp->ctrl); return -EINVAL; } Loading Loading @@ -634,6 +637,7 @@ static void dp_display_clean(struct dp_display_private *dp) dp->ctrl->push_idle(dp->ctrl); dp->ctrl->off(dp->ctrl); dp->power_on = false; } static int dp_display_usbpd_disconnect_cb(struct device *dev) Loading Loading @@ -662,6 +666,8 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev) rc = dp_display_send_hpd_notification(dp, false); mutex_lock(&dp->session_lock); /* if cable is disconnected, reset psm_enabled flag */ if (!dp->usbpd->alt_mode_cfg_done) dp->link->psm_enabled = false; Loading @@ -670,6 +676,8 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev) dp_display_clean(dp); dp_display_host_deinit(dp); mutex_unlock(&dp->session_lock); end: return rc; } Loading Loading @@ -760,6 +768,7 @@ static void dp_display_deinit_sub_modules(struct dp_display_private *dp) dp_catalog_put(dp->catalog); dp_parser_put(dp->parser); dp_usbpd_put(dp->usbpd); mutex_destroy(&dp->session_lock); dp_debug_put(dp->debug); } Loading Loading @@ -787,6 +796,8 @@ static int dp_init_sub_modules(struct dp_display_private *dp) goto error; } mutex_init(&dp->session_lock); dp->parser = dp_parser_get(dp->pdev); if (IS_ERR(dp->parser)) { rc = PTR_ERR(dp->parser); Loading Loading @@ -890,6 +901,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp) dp_parser_put(dp->parser); error_parser: dp_usbpd_put(dp->usbpd); mutex_destroy(&dp->session_lock); error: return rc; } Loading @@ -897,20 +909,20 @@ static int dp_init_sub_modules(struct dp_display_private *dp) static int dp_display_set_mode(struct dp_display *dp_display, struct dp_display_mode *mode) { int rc = 0; struct dp_display_private *dp; if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto error; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); dp->panel->pinfo = mode->timing; dp->panel->init_info(dp->panel); error: return rc; mutex_unlock(&dp->session_lock); return 0; } static int dp_display_prepare(struct dp_display *dp) Loading @@ -925,37 +937,44 @@ static int dp_display_enable(struct dp_display *dp_display) if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto error; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); if (dp->power_on) { pr_debug("Link already setup, return\n"); return 0; goto end; } rc = dp->ctrl->on(dp->ctrl); if (!rc) dp->power_on = true; error: end: mutex_unlock(&dp->session_lock); return rc; } static int dp_display_post_enable(struct dp_display *dp_display) { int rc = 0; struct dp_display_private *dp; if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto end; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); if (!dp->power_on) { pr_debug("Link not setup, return\n"); goto end; } if (dp->audio_supported) { dp->audio->bw_code = dp->link->link_params.bw_code; dp->audio->lane_count = dp->link->link_params.lane_count; Loading @@ -973,23 +992,30 @@ static int dp_display_post_enable(struct dp_display *dp_display) queue_delayed_work(dp->hdcp_workqueue, &dp->hdcp_cb_work, HZ / 2); } end: return rc; mutex_unlock(&dp->session_lock); return 0; } static int dp_display_pre_disable(struct dp_display *dp_display) { int rc = 0; struct dp_display_private *dp; if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto error; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); if (!dp->power_on) { pr_debug("Link already powered off, return\n"); goto end; } if (dp_display_is_hdcp_enabled(dp)) { dp->hdcp_status = HDCP_STATE_INACTIVE; Loading @@ -1003,33 +1029,38 @@ static int dp_display_pre_disable(struct dp_display *dp_display) dp->link->psm_config(dp->link, &dp->panel->link_info, true); dp->ctrl->push_idle(dp->ctrl); error: return rc; end: mutex_unlock(&dp->session_lock); return 0; } static int dp_display_disable(struct dp_display *dp_display) { int rc = 0; struct dp_display_private *dp; if (!dp_display) { pr_err("invalid input\n"); rc = -EINVAL; goto error; return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); if (!dp->power_on || !dp->core_initialized) goto error; mutex_lock(&dp->session_lock); if (!dp->power_on || !dp->core_initialized) { pr_debug("Link already powered off, return\n"); goto end; } dp->ctrl->off(dp->ctrl); dp->power_on = false; end: complete_all(&dp->notification_comp); error: return rc; mutex_unlock(&dp->session_lock); return 0; } static int dp_request_irq(struct dp_display *dp_display) Loading
drivers/gpu/drm/msm/dp/dp_power.c +9 −0 Original line number Diff line number Diff line Loading @@ -562,6 +562,15 @@ static int dp_power_deinit(struct dp_power *dp_power) power = container_of(dp_power, struct dp_power_private, dp_power); dp_power_clk_enable(dp_power, DP_CORE_PM, false); /* * If the display power on event was not successful, for example if * there was a link training failure, then the link clocks could * possibly still be on. In this scenario, we need to turn off the * link clocks as soon as the cable is disconnected so that the clock * state is cleaned up before subsequent connection events. */ if (power->link_clks_on) dp_power_clk_enable(dp_power, DP_CTRL_PM, false); rc = sde_power_resource_enable(power->phandle, power->dp_core_client, false); if (rc) { Loading