msm: mdss: Add HFP_CALC_CLK way to switch frame rate

Add support to switch non-standard framerate.To achieve this,
first map the fps to standard fps and then tune pixel clock
based non-standard framerate. Panel porches might need update
before pixel clock tuning based on standard framerate mapping.

CRs-fixed: 1032036
Change-Id: I49995875338cd2a3b57e88753cfda1bfa97910dd
Signed-off-by: feifanz <feifanz@codeaurora.org>
Signed-off-by: Krishna Srinivas <krisrini@codeaurora.org>
This commit is contained in:
feifanz 2016-06-17 10:54:03 +08:00 committed by Harsh Sahu
parent b790cce49b
commit 419c2b4a7c
4 changed files with 56 additions and 12 deletions

View file

@ -5493,7 +5493,12 @@ int mdss_mdp_ctl_update_fps(struct mdss_mdp_ctl *ctl)
(pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP) ||
(pinfo->dfps_update ==
DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) ||
(pinfo->dfps_update ==
DFPS_IMMEDIATE_MULTI_MODE_HFP_CALC_CLK) ||
pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
if (pinfo->type == DTV_PANEL)
new_fps = pinfo->lcdc.frame_rate;
else
new_fps = mdss_panel_get_framerate(pinfo);
} else {
new_fps = pinfo->new_fps;

View file

@ -1424,7 +1424,9 @@ static int mdss_mdp_video_config_fps(struct mdss_mdp_ctl *ctl, int new_fps)
pdata->panel_info.dfps_update
== DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP ||
pdata->panel_info.dfps_update
== DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
== DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP ||
pdata->panel_info.dfps_update
== DFPS_IMMEDIATE_MULTI_MODE_HFP_CALC_CLK) {
unsigned long flags;
if (!ctx->timegen_en) {
pr_err("TG is OFF. DFPS mode invalid\n");

View file

@ -2998,14 +2998,21 @@ static void cache_initial_timings(struct mdss_panel_data *pdata)
* This value will change dynamically once the
* actual dfps update happen in hw.
*/
if (pdata->panel_info.type == DTV_PANEL)
pdata->panel_info.current_fps =
pdata->panel_info.lcdc.frame_rate;
else
pdata->panel_info.current_fps =
mdss_panel_get_framerate(&pdata->panel_info);
/*
* Keep the initial fps and porch values for this panel before
* any dfps update happen, this is to prevent losing precision
* in further calculations.
*/
if (pdata->panel_info.type == DTV_PANEL)
pdata->panel_info.default_fps =
pdata->panel_info.lcdc.frame_rate;
else
pdata->panel_info.default_fps =
mdss_panel_get_framerate(&pdata->panel_info);
@ -3019,7 +3026,9 @@ static void cache_initial_timings(struct mdss_panel_data *pdata)
} else if (pdata->panel_info.dfps_update ==
DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP ||
pdata->panel_info.dfps_update ==
DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP ||
pdata->panel_info.dfps_update ==
DFPS_IMMEDIATE_MULTI_MODE_HFP_CALC_CLK) {
pdata->panel_info.saved_total =
mdss_panel_get_htotal(&pdata->panel_info, true);
pdata->panel_info.saved_fporch =
@ -3088,8 +3097,25 @@ static void dfps_update_panel_params(struct mdss_panel_data *pdata,
pdata->panel_info.lcdc.h_pulse_width = data->hpw;
pdata->panel_info.clk_rate = data->clk_rate;
if (pdata->panel_info.type == DTV_PANEL)
pdata->panel_info.clk_rate *= 1000;
dfps_update_fps(&pdata->panel_info, new_fps);
} else if (pdata->panel_info.dfps_update ==
DFPS_IMMEDIATE_MULTI_MODE_HFP_CALC_CLK) {
pr_debug("hfp=%d, hbp=%d, hpw=%d, clk=%d, fps=%d\n",
data->hfp, data->hbp, data->hpw,
data->clk_rate, data->fps);
pdata->panel_info.lcdc.h_front_porch = data->hfp;
pdata->panel_info.lcdc.h_back_porch = data->hbp;
pdata->panel_info.lcdc.h_pulse_width = data->hpw;
pdata->panel_info.clk_rate = data->clk_rate;
dfps_update_fps(&pdata->panel_info, new_fps);
mdss_panel_update_clk_rate(&pdata->panel_info, new_fps);
} else {
dfps_update_fps(&pdata->panel_info, new_fps);
mdss_panel_update_clk_rate(&pdata->panel_info, new_fps);
@ -3164,7 +3190,9 @@ static ssize_t dynamic_fps_sysfs_wta_dfps(struct device *dev,
}
if (pdata->panel_info.dfps_update ==
DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP ||
pdata->panel_info.dfps_update ==
DFPS_IMMEDIATE_MULTI_MODE_HFP_CALC_CLK) {
if (sscanf(buf, "%u %u %u %u %u",
&data.hfp, &data.hbp, &data.hpw,
&data.clk_rate, &data.fps) != 5) {
@ -3179,6 +3207,9 @@ static ssize_t dynamic_fps_sysfs_wta_dfps(struct device *dev,
}
}
if (pdata->panel_info.type == DTV_PANEL)
panel_fps = pdata->panel_info.lcdc.frame_rate;
else
panel_fps = mdss_panel_get_framerate(&pdata->panel_info);
if (data.fps == panel_fps) {

View file

@ -538,6 +538,9 @@ struct dynamic_fps_data {
* @DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP: update fps using horizontal timings
* @DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP: update fps using both horizontal
* timings and clock.
* @DFPS_IMMEDIATE_MULTI_MODE_HFP_CALC_CLK: update fps using both
* horizontal timings, clock need to be caculate base on new clock and
* porches.
* @DFPS_MODE_MAX: defines maximum limit of supported modes.
*/
enum dynamic_fps_update {
@ -546,6 +549,7 @@ enum dynamic_fps_update {
DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP,
DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP,
DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP,
DFPS_IMMEDIATE_MULTI_MODE_HFP_CALC_CLK,
DFPS_MODE_MAX
};
@ -975,7 +979,9 @@ static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info)
break;
case DTV_PANEL:
if (panel_info->dynamic_fps) {
frame_rate = panel_info->lcdc.frame_rate;
frame_rate = panel_info->lcdc.frame_rate / 1000;
if (panel_info->lcdc.frame_rate % 1000)
frame_rate += 1;
break;
}
default: