diff options
| author | Ajay Singh Parmar <aparmar@codeaurora.org> | 2016-03-22 11:56:42 -0700 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-04-28 16:42:53 -0700 |
| commit | 43270c072ec5cb25e378367c2be34d2a5d3a2f84 (patch) | |
| tree | 83aec4bc9d9004d83e4241ffe668c08fa3bbd7c5 /drivers | |
| parent | a43565e79dcd9d85ac93453a6e0efde0193eb8ea (diff) | |
msm: mdss: add dynamic fps support for hdmi
Add support for dynamic fps up to three decimal values for
hdmi. The new fps is provided in multiple of 1000. eg. for
60 fps, 60000 is provided and for 59.94fps, 59940 is provided.
Change-Id: Ib16bf546721ba204f8a47733327e7be77b76b821
Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 38 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_panel.h | 31 |
2 files changed, 60 insertions, 9 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index e813c8b1bfcd..69dc5fe06898 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -2705,7 +2705,7 @@ static int calc_extra_blanking(struct mdss_panel_data *pdata, u32 new_fps) int add_porches, diff; /* calculate extra: lines for vfp-method, pixels for hfp-method */ - diff = pdata->panel_info.default_fps - new_fps; + diff = abs(pdata->panel_info.default_fps - new_fps); add_porches = mult_frac(pdata->panel_info.saved_total, diff, new_fps); @@ -2748,6 +2748,14 @@ static void cache_initial_timings(struct mdss_panel_data *pdata) } } +static inline void dfps_update_fps(struct mdss_panel_info *pinfo, u32 fps) +{ + if (pinfo->type == DTV_PANEL) + pinfo->lcdc.frame_rate = fps; + else + pinfo->mipi.frame_rate = fps; +} + static void dfps_update_panel_params(struct mdss_panel_data *pdata, u32 new_fps) { @@ -2764,7 +2772,9 @@ static void dfps_update_panel_params(struct mdss_panel_data *pdata, /* update panel info with new values */ pdata->panel_info.lcdc.v_front_porch = pdata->panel_info.saved_fporch + add_v_lines; - pdata->panel_info.mipi.frame_rate = new_fps; + + dfps_update_fps(&pdata->panel_info, new_fps); + pdata->panel_info.prg_fet = mdss_mdp_get_prefetch_lines(&pdata->panel_info); @@ -2776,11 +2786,18 @@ static void dfps_update_panel_params(struct mdss_panel_data *pdata, add_h_pixels = calc_extra_blanking(pdata, new_fps); /* update panel info */ - pdata->panel_info.lcdc.h_front_porch = - pdata->panel_info.saved_fporch + add_h_pixels; - pdata->panel_info.mipi.frame_rate = new_fps; + if (pdata->panel_info.default_fps > new_fps) + pdata->panel_info.lcdc.h_front_porch = + pdata->panel_info.saved_fporch + add_h_pixels; + else + pdata->panel_info.lcdc.h_front_porch = + pdata->panel_info.saved_fporch - add_h_pixels; + + dfps_update_fps(&pdata->panel_info, new_fps); + } else { - pdata->panel_info.mipi.frame_rate = new_fps; + dfps_update_fps(&pdata->panel_info, new_fps); + mdss_panel_update_clk_rate(&pdata->panel_info, new_fps); } } @@ -2826,7 +2843,7 @@ int mdss_mdp_dfps_update_params(struct msm_fb_data_type *mfd, static ssize_t dynamic_fps_sysfs_wta_dfps(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int dfps, rc = 0; + int dfps, panel_fps, rc = 0; struct mdss_panel_data *pdata; struct fb_info *fbi = dev_get_drvdata(dev); struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par; @@ -2855,7 +2872,9 @@ static ssize_t dynamic_fps_sysfs_wta_dfps(struct device *dev, return -EINVAL; } - if (dfps == pdata->panel_info.mipi.frame_rate) { + panel_fps = mdss_panel_get_framerate(&pdata->panel_info); + + if (dfps == panel_fps) { pr_debug("%s: FPS is already %d\n", __func__, dfps); return count; @@ -5493,7 +5512,8 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd) if (rc) pr_warn("problem creating link to mdss_fb sysfs\n"); - if (mfd->panel_info->type == MIPI_VIDEO_PANEL) { + if (mfd->panel_info->type == MIPI_VIDEO_PANEL || + mfd->panel_info->type == DTV_PANEL) { rc = sysfs_create_group(&dev->kobj, &dynamic_fps_fs_attrs_group); if (rc) { diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 205a14cf8285..7c3e2cea58ef 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -282,6 +282,7 @@ struct lcd_panel_info { u32 xres_pad; /* Pad height */ u32 yres_pad; + u32 frame_rate; }; @@ -772,6 +773,11 @@ static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info) case WRITEBACK_PANEL: frame_rate = DEFAULT_FRAME_RATE; break; + case DTV_PANEL: + if (panel_info->dynamic_fps) { + frame_rate = panel_info->lcdc.frame_rate; + break; + } default: pixel_total = (panel_info->lcdc.h_back_porch + panel_info->lcdc.h_front_porch + @@ -917,6 +923,31 @@ static inline bool mdss_panel_is_power_on_ulp(int panel_power_state) } /** + * mdss_panel_update_clk_rate() - update the clock rate based on panel timing + * information. + * @panel_info: Pointer to panel info containing all panel information + * @fps: frame rate of the panel + */ +static inline void mdss_panel_update_clk_rate(struct mdss_panel_info *pinfo, + u32 fps) +{ + struct lcd_panel_info *lcdc = &pinfo->lcdc; + u32 htotal, vtotal; + + if (pinfo->type == DTV_PANEL) { + htotal = pinfo->xres + lcdc->h_front_porch + + lcdc->h_back_porch + lcdc->h_pulse_width; + vtotal = pinfo->yres + lcdc->v_front_porch + + lcdc->v_back_porch + lcdc->v_pulse_width; + + pinfo->clk_rate = mult_frac(htotal * vtotal, fps, 1000); + + pr_debug("vtotal %d, htotal %d, rate %llu\n", + vtotal, htotal, pinfo->clk_rate); + } +} + +/** * mdss_panel_calc_frame_rate() - calculate panel frame rate based on panel timing * information. * @panel_info: Pointer to panel info containing all panel information |
