From 35b60f62087b404ad727798286649fdbbce5fec5 Mon Sep 17 00:00:00 2001 From: Chandan Uddaraju Date: Thu, 23 Jul 2020 23:55:35 -0700 Subject: [PATCH] disp: msm: add connector API to disable cont_splash resource votes The panel regulator votes are added by default during dsi probe to make sure sync state driver doesn't disable these regulators for cont_splash use case. These regulator votes need to be removed when cont_splash feature is disabled. Add a new connector API to handle this. CRs-Fixed: 2734419 Change-Id: Ie54c8f246877a042afacddaeae8b90440652116f Signed-off-by: Chandan Uddaraju --- msm/dsi/dsi_display.c | 52 ++++++++++++++++---------------- msm/dsi/dsi_display.h | 8 +++++ msm/sde/sde_connector.h | 7 +++++ msm/sde/sde_kms.c | 66 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 27 deletions(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index ebef95b0a6..ecf44d2505 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -4879,6 +4879,25 @@ static int _dsi_display_dev_deinit(struct dsi_display *display) return rc; } +/** + * dsi_display_cont_splash_res_disable() - Disable resource votes added in probe + * @dsi_display: Pointer to dsi display + * Returns: Zero on success + */ +int dsi_display_cont_splash_res_disable(void *dsi_display) +{ + struct dsi_display *display = dsi_display; + int rc = 0; + + /* Remove the panel vote that was added during dsi display probe */ + rc = dsi_pwr_enable_regulator(&display->panel->power_info, false); + if (rc) + DSI_ERR("[%s] failed to disable vregs, rc=%d\n", + display->panel->name, rc); + + return rc; +} + /** * dsi_display_cont_splash_config() - Initialize resources for continuous splash * @dsi_display: Pointer to dsi display @@ -4924,14 +4943,6 @@ int dsi_display_cont_splash_config(void *dsi_display) goto clk_manager_update; } - /* Vote on panel regulator will be removed during suspend path */ - rc = dsi_pwr_enable_regulator(&display->panel->power_info, true); - if (rc) { - DSI_ERR("[%s] failed to enable vregs, rc=%d\n", - display->panel->name, rc); - goto clks_disabled; - } - mutex_unlock(&display->display_lock); /* Set the current brightness level */ @@ -4939,10 +4950,6 @@ int dsi_display_cont_splash_config(void *dsi_display) return rc; -clks_disabled: - rc = dsi_display_clk_ctrl(display->dsi_clk_handle, - DSI_ALL_CLKS, DSI_CLK_OFF); - clk_manager_update: dsi_display_ctrl_isr_configure(display, false); /* Update splash status for clock manager */ @@ -5274,17 +5281,6 @@ static int dsi_display_bind(struct device *dev, } } - /* Remove the panel vote that was added during dsi display probe */ - if (display->panel) { - rc = dsi_pwr_enable_regulator(&display->panel->power_info, - false); - if (rc) { - DSI_ERR("[%s] failed to disable vregs, rc=%d\n", - display->panel->name, rc); - goto error_host_deinit; - } - } - /* register te irq handler */ dsi_display_register_te_irq(display); @@ -5399,11 +5395,13 @@ static int dsi_display_init(struct dsi_display *display) /* * Vote on panel regulator is added to make sure panel regulators - * are ON until dsi bind is completed for cont-splash enabled usecase. - * This panel regulator vote will be removed after bind is done. + * are ON for cont-splash enabled usecase. + * This panel regulator vote will be removed only in: + * 1) device suspend when cont-splash is enabled. + * 2) cont_splash_res_disable() when cont-splash is disabled. * For GKI, adding this vote will make sure that sync_state - * kernel driver doesn't disable the panel regulators before - * splash_config() function adds vote for these regulators. + * kernel driver doesn't disable the panel regulators after + * dsi probe is complete. */ if (display->panel) { rc = dsi_pwr_enable_regulator(&display->panel->power_info, diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h index 06251aaa0e..5398b4bcf3 100644 --- a/msm/dsi/dsi_display.h +++ b/msm/dsi/dsi_display.h @@ -737,6 +737,14 @@ enum dsi_pixel_format dsi_display_get_dst_format( * Return: Zero on Success */ int dsi_display_cont_splash_config(void *display); + +/** + * dsi_display_cont_splash_res_disable() - Disable resource votes added in probe + * @display: Pointer to dsi display + * Returns: Zero on success + */ +int dsi_display_cont_splash_res_disable(void *display); + /* * dsi_display_get_panel_vfp - get panel vsync * @display: Pointer to private display structure diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index 58a8413319..3881f8106e 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -325,6 +325,13 @@ struct sde_connector_ops { */ int (*cont_splash_config)(void *display); + /** + * cont_splash_res_disable - Remove any splash resources added in probe + * @display: Pointer to private display handle + * Returns: zero for success, negetive for failure + */ + int (*cont_splash_res_disable)(void *display); + /** * get_panel_vfp - returns original panel vfp * @display: Pointer to private display handle diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 34f7b72c27..880fb158f0 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1654,6 +1654,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .enable_event = dsi_conn_enable_event, .cmd_transfer = dsi_display_cmd_transfer, .cont_splash_config = dsi_display_cont_splash_config, + .cont_splash_res_disable = dsi_display_cont_splash_res_disable, .get_panel_vfp = dsi_display_get_panel_vfp, .get_default_lms = dsi_display_get_default_lms, .cmd_receive = dsi_display_cmd_receive, @@ -1671,6 +1672,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .check_status = NULL, .cmd_transfer = NULL, .cont_splash_config = NULL, + .cont_splash_res_disable = NULL, .get_panel_vfp = NULL, .cmd_receive = NULL, }; @@ -1688,6 +1690,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .config_hdr = dp_connector_config_hdr, .cmd_transfer = NULL, .cont_splash_config = NULL, + .cont_splash_res_disable = NULL, .get_panel_vfp = NULL, .update_pps = dp_connector_update_pps, .cmd_receive = NULL, @@ -2784,6 +2787,66 @@ static struct drm_display_mode *_sde_kms_get_splash_mode( return curr_mode; } +static int sde_kms_inform_cont_splash_res_disable(struct msm_kms *kms, + struct dsi_display *dsi_display) +{ + void *display; + struct drm_encoder *encoder = NULL; + struct msm_display_info info; + struct drm_device *dev; + struct sde_kms *sde_kms; + struct drm_connector_list_iter conn_iter; + struct drm_connector *connector = NULL; + struct sde_connector *sde_conn = NULL; + int rc = 0; + + sde_kms = to_sde_kms(kms); + dev = sde_kms->dev; + display = dsi_display; + if (dsi_display) { + if (dsi_display->bridge->base.encoder) { + encoder = dsi_display->bridge->base.encoder; + SDE_DEBUG("encoder name = %s\n", encoder->name); + } + memset(&info, 0x0, sizeof(info)); + rc = dsi_display_get_info(NULL, &info, display); + if (rc) { + SDE_ERROR("%s: dsi get_info failed: %d\n", + rc, __func__); + encoder = NULL; + } + } + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + /** + * Inform cont_splash is disabled to each interface/connector. + * This is currently supported for DSI interface. + */ + sde_conn = to_sde_connector(connector); + if (sde_conn && sde_conn->ops.cont_splash_res_disable) { + if (!dsi_display || !encoder) { + sde_conn->ops.cont_splash_res_disable + (sde_conn->display); + } else if (connector->encoder_ids[0] + == encoder->base.id) { + /** + * This handles dual DSI + * configuration where one DSI + * interface has cont_splash + * enabled and the other doesn't. + */ + sde_conn->ops.cont_splash_res_disable + (sde_conn->display); + break; + } + } + } + drm_connector_list_iter_end(&conn_iter); + + return 0; +} + static int sde_kms_cont_splash_config(struct msm_kms *kms) { void *display; @@ -2817,6 +2880,7 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms) && (!sde_kms->splash_data.num_splash_regions)) || !sde_kms->splash_data.num_splash_displays) { DRM_INFO("cont_splash feature not enabled\n"); + sde_kms_inform_cont_splash_res_disable(kms, NULL); return rc; } @@ -2833,6 +2897,8 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms) if (!splash_display->cont_splash_enabled) { SDE_DEBUG("display->name = %s splash not enabled\n", dsi_display->name); + sde_kms_inform_cont_splash_res_disable(kms, + dsi_display); continue; }