diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 69b9149cd750..695db66d8c26 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -2370,6 +2370,49 @@ end_update: return rc; } +static int mdss_dsi_dynamic_bitclk_config(struct mdss_panel_data *pdata) +{ + int rc = 0; + struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + struct mdss_panel_info *pinfo; + + pr_debug("%s+:\n", __func__); + + if (pdata == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return -EINVAL; + } + + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, + panel_data); + + if (!ctrl_pdata->panel_data.panel_info.dynamic_bitclk) { + pr_err("Dynamic bitclk not enabled for this panel\n"); + return -EINVAL; + } + + pinfo = &pdata->panel_info; + + if (!pinfo->new_clk_rate || (pinfo->clk_rate == pinfo->new_clk_rate)) { + pr_debug("Bit clock update is not needed\n"); + return 0; + } + + rc = __mdss_dsi_dynamic_clock_switch(&ctrl_pdata->panel_data, + pinfo->new_clk_rate); + if (!rc && mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) { + struct mdss_dsi_ctrl_pdata *octrl = + mdss_dsi_get_other_ctrl(ctrl_pdata); + rc = __mdss_dsi_dynamic_clock_switch(&octrl->panel_data, + pinfo->new_clk_rate); + if (rc) + pr_err("failed to switch DSI bitclk for sctrl\n"); + } else if (rc) { + pr_err("failed to switch DSI bitclk\n"); + } + return rc; +} + static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) { int rc = 0; @@ -2821,19 +2864,14 @@ static ssize_t dynamic_bitclk_sysfs_wta(struct device *dev, return -EINVAL; } - rc = __mdss_dsi_dynamic_clock_switch(&ctrl_pdata->panel_data, - clk_rate); - if (!rc && mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) { + pinfo->new_clk_rate = clk_rate; + if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) { struct mdss_dsi_ctrl_pdata *octrl = mdss_dsi_get_other_ctrl(ctrl_pdata); - rc = __mdss_dsi_dynamic_clock_switch(&octrl->panel_data, - clk_rate); - if (rc) - pr_err("failed to switch DSI bitclk for sctrl\n"); - } else if (rc) { - pr_err("failed to switch DSI bitclk\n"); - } + struct mdss_panel_info *opinfo = &octrl->panel_data.panel_info; + opinfo->new_clk_rate = clk_rate; + } return count; } /* dynamic_bitclk_sysfs_wta */ @@ -3061,6 +3099,14 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, case MDSS_EVENT_AVR_MODE: mdss_dsi_avr_config(ctrl_pdata, (int)(unsigned long) arg); break; + case MDSS_EVENT_DSI_DYNAMIC_BITCLK: + if (ctrl_pdata->panel_data.panel_info.dynamic_bitclk) { + rc = mdss_dsi_dynamic_bitclk_config(pdata); + if (rc) + pr_err("unable to change bitclk error-%d\n", + rc); + } + break; default: pr_debug("%s: unhandled event=%d\n", __func__, event); break; diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 676bbfa89211..81218319d58b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -2659,6 +2659,13 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, goto commit_fail; } + ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_DSI_DYNAMIC_BITCLK, + NULL, CTL_INTF_EVENT_FLAG_SKIP_BROADCAST); + if (IS_ERR_VALUE(ret)) { + pr_err("failed to update dynamic bit clk!\n"); + goto commit_fail; + } + mutex_lock(&mdp5_data->ov_lock); /* Disable secure display/camera for video mode panels */ diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index de3ff0c77625..f8993f3774e6 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -308,6 +308,7 @@ enum mdss_intf_events { MDSS_EVENT_DSI_TIMING_DB_CTRL, MDSS_EVENT_AVR_MODE, MDSS_EVENT_REGISTER_CLAMP_HANDLER, + MDSS_EVENT_DSI_DYNAMIC_BITCLK, MDSS_EVENT_MAX, }; @@ -814,6 +815,8 @@ struct mdss_panel_info { bool esd_check_enabled; bool allow_phy_power_off; char dfps_update; + /* new requested bitclk before it is updated in hw */ + int new_clk_rate; /* new requested fps before it is updated in hw */ int new_fps; /* stores initial fps after boot */