Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bde3e6ba authored by Ajay Singh Parmar's avatar Ajay Singh Parmar
Browse files

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: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent 25f64653
Loading
Loading
Loading
Loading
+29 −9
Original line number Diff line number Diff line
@@ -2721,7 +2721,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);

@@ -2764,6 +2764,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)
{
@@ -2780,7 +2788,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);

@@ -2792,11 +2802,18 @@ static void dfps_update_panel_params(struct mdss_panel_data *pdata,
		add_h_pixels = calc_extra_blanking(pdata, new_fps);

		/* update panel info */
		if (pdata->panel_info.default_fps > new_fps)
			pdata->panel_info.lcdc.h_front_porch =
				pdata->panel_info.saved_fporch + add_h_pixels;
		pdata->panel_info.mipi.frame_rate = new_fps;
		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);
	}
}

@@ -2842,7 +2859,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;
@@ -2871,7 +2888,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;
@@ -5512,7 +5531,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) {
+31 −0
Original line number Diff line number Diff line
@@ -280,6 +280,7 @@ struct lcd_panel_info {
	u32 xres_pad;
	/* Pad height */
	u32 yres_pad;
	u32 frame_rate;
};


@@ -770,6 +771,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 +
@@ -914,6 +920,31 @@ static inline bool mdss_panel_is_power_on_ulp(int panel_power_state)
	return panel_power_state == MDSS_PANEL_POWER_LP2;
}

/**
 * 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.