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

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

msm: mdss: add multi-mode support for dynamic fps



In some cases, updating fps need both porch and clock
update. Add support to update both porch and clock settings
for a given resolution to attain required fps.

Change-Id: I8c75ef09121c2d20e04380ead2b805c7b114acad
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent bde3e6ba
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1338,7 +1338,7 @@ int mdss_mdp_secure_display_ctrl(unsigned int enable);

int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
int mdss_mdp_dfps_update_params(struct msm_fb_data_type *mfd,
	struct mdss_panel_data *pdata, int dfps);
	struct mdss_panel_data *pdata, struct dynamic_fps_data *data);
int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd,
	struct file *file, struct mdp_layer_commit_v1 *ov_commit);
int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd,
+2 −0
Original line number Diff line number Diff line
@@ -4800,6 +4800,8 @@ int mdss_mdp_ctl_update_fps(struct mdss_mdp_ctl *ctl)

	if ((pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP) ||
		(pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP) ||
		(pinfo->dfps_update ==
			DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) ||
		pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
		new_fps = mdss_panel_get_framerate(pinfo);
	} else {
+9 −5
Original line number Diff line number Diff line
@@ -827,10 +827,10 @@ static int mdss_mdp_video_fps_update(struct mdss_mdp_video_ctx *ctx,
	int rc;

	if (pdata->panel_info.dfps_update ==
				DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP)
		rc = mdss_mdp_video_hfp_fps_update(ctx, pdata);
	else
				DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP)
		rc = mdss_mdp_video_vfp_fps_update(ctx, pdata);
	else
		rc = mdss_mdp_video_hfp_fps_update(ctx, pdata);

	return rc;
}
@@ -985,7 +985,9 @@ static int mdss_mdp_video_config_fps(struct mdss_mdp_ctl *ctl, int new_fps)
		} else if (pdata->panel_info.dfps_update
				== DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP ||
				pdata->panel_info.dfps_update
				== DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP) {
				== DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP ||
				pdata->panel_info.dfps_update
				== DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
			unsigned long flags;
			if (!ctx->timegen_en) {
				pr_err("TG is OFF. DFPS mode invalid\n");
@@ -1644,6 +1646,7 @@ static void early_wakeup_dfps_update_work(struct work_struct *work)
	struct mdss_panel_info *pinfo;
	struct msm_fb_data_type *mfd;
	struct mdss_mdp_ctl *ctl;
	struct dynamic_fps_data data = {0};
	int ret = 0;
	int dfps;

@@ -1680,7 +1683,8 @@ static void early_wakeup_dfps_update_work(struct work_struct *work)
		goto exit;
	}

	if (mdss_mdp_dfps_update_params(mfd, pdata, dfps))
	data.fps = dfps;
	if (mdss_mdp_dfps_update_params(mfd, pdata, &data))
		pr_err("failed to set dfps params!\n");

	/* update the HW with the new fps */
+44 −15
Original line number Diff line number Diff line
@@ -2755,7 +2755,9 @@ static void cache_initial_timings(struct mdss_panel_data *pdata)
				pdata->panel_info.lcdc.v_front_porch;

		} else if (pdata->panel_info.dfps_update ==
					DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP) {
				DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP ||
			pdata->panel_info.dfps_update ==
				DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
			pdata->panel_info.saved_total =
				mdss_panel_get_htotal(&pdata->panel_info, true);
			pdata->panel_info.saved_fporch =
@@ -2773,8 +2775,10 @@ static inline void dfps_update_fps(struct mdss_panel_info *pinfo, u32 fps)
}

static void dfps_update_panel_params(struct mdss_panel_data *pdata,
	u32 new_fps)
	struct dynamic_fps_data *data)
{
	u32 new_fps = data->fps;

	/* Keep initial values before any dfps update */
	cache_initial_timings(pdata);

@@ -2810,7 +2814,20 @@ static void dfps_update_panel_params(struct mdss_panel_data *pdata,
				pdata->panel_info.saved_fporch - add_h_pixels;

		dfps_update_fps(&pdata->panel_info, new_fps);
	} else if (pdata->panel_info.dfps_update ==
		DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {

		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);
	} else {
		dfps_update_fps(&pdata->panel_info, new_fps);
		mdss_panel_update_clk_rate(&pdata->panel_info, new_fps);
@@ -2818,10 +2835,11 @@ static void dfps_update_panel_params(struct mdss_panel_data *pdata,
}

int mdss_mdp_dfps_update_params(struct msm_fb_data_type *mfd,
	struct mdss_panel_data *pdata, int dfps)
	struct mdss_panel_data *pdata, struct dynamic_fps_data *dfps_data)
{
	struct fb_var_screeninfo *var = &mfd->fbi->var;
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
	u32 dfps = dfps_data->fps;

	mutex_lock(&mdp5_data->dfps_lock);

@@ -2838,9 +2856,9 @@ int mdss_mdp_dfps_update_params(struct msm_fb_data_type *mfd,
		dfps = pdata->panel_info.max_fps;
	}

	dfps_update_panel_params(pdata, dfps);
	dfps_update_panel_params(pdata, dfps_data);
	if (pdata->next)
		dfps_update_panel_params(pdata->next, dfps);
		dfps_update_panel_params(pdata->next, dfps_data);

	/*
	 * Update the panel info in the upstream
@@ -2859,17 +2877,12 @@ 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, panel_fps, rc = 0;
	int 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;
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);

	rc = kstrtoint(buf, 10, &dfps);
	if (rc) {
		pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc);
		return rc;
	}
	struct dynamic_fps_data data = {0};

	if (!mdp5_data->ctl || !mdss_mdp_ctl_is_power_on(mdp5_data->ctl)) {
		pr_debug("panel is off\n");
@@ -2888,15 +2901,31 @@ static ssize_t dynamic_fps_sysfs_wta_dfps(struct device *dev,
		return -EINVAL;
	}

	if (pdata->panel_info.dfps_update ==
		DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
		if (sscanf(buf, "%d %d %d %d %d",
		    &data.hfp, &data.hbp, &data.hpw,
		    &data.clk_rate, &data.fps) != 5) {
			pr_err("could not read input\n");
			return -EINVAL;
		}
	} else {
		rc = kstrtoint(buf, 10, &data.fps);
		if (rc) {
			pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc);
			return rc;
		}
	}

	panel_fps = mdss_panel_get_framerate(&pdata->panel_info);

	if (dfps == panel_fps) {
	if (data.fps == panel_fps) {
		pr_debug("%s: FPS is already %d\n",
			__func__, dfps);
			__func__, data.fps);
		return count;
	}

	rc = mdss_mdp_dfps_update_params(mfd, pdata, dfps);
	rc = mdss_mdp_dfps_update_params(mfd, pdata, &data);
	if (rc) {
		pr_err("failed to set dfps params\n");
		return rc;
+27 −0
Original line number Diff line number Diff line
@@ -414,11 +414,38 @@ struct edp_panel_info {
	char frame_rate;	/* fps */
};

/**
 * struct dynamic_fps_data - defines dynamic fps related data
 * @hfp: horizontal front porch
 * @hbp: horizontal back porch
 * @hpw: horizontal pulse width
 * @clk_rate: panel clock rate in HZ
 * @fps: frames per second
 */
struct dynamic_fps_data {
	u32 hfp;
	u32 hbp;
	u32 hpw;
	u32 clk_rate;
	u32 fps;
};

/**
 * enum dynamic_fps_update - defines fps update modes
 * @DFPS_SUSPEND_RESUME_MODE: suspend/resume mode
 * @DFPS_IMMEDIATE_CLK_UPDATE_MODE: update fps using clock
 * @DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP: update fps using vertical timings
 * @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_MODE_MAX: defines maximum limit of supported modes.
 */
enum dynamic_fps_update {
	DFPS_SUSPEND_RESUME_MODE,
	DFPS_IMMEDIATE_CLK_UPDATE_MODE,
	DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP,
	DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP,
	DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP,
	DFPS_MODE_MAX
};