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

Commit 1de5f8c4 authored by Jeykumar Sankaran's avatar Jeykumar Sankaran
Browse files

mdss: mdp: Add support for partial panel updates



This change programs MDP only for the output resolution (ROI)
set by the client. All staged pipes are cropped to fetch data
only for the resolution programmed.

Change-Id: I1e113fd051a01d8fc1247a74d363a26cd9a0cd61
Signed-off-by: default avatarJeykumar Sankaran <jsanka@codeaurora.org>
parent 179b553f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -742,7 +742,8 @@ static int mdp3_overlay_play(struct msm_fb_data_type *mfd,
	return rc;
}

static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd)
static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,
					struct mdp_display_commit *cmt_data)
{
	struct mdp3_session_data *mdp3_session;
	struct mdp3_img_data *data;
+2 −1
Original line number Diff line number Diff line
@@ -1452,7 +1452,8 @@ static void mdss_fb_commit_wq_handler(struct work_struct *work)
		MDP_DISPLAY_COMMIT_OVERLAY) {
		mdss_fb_wait_for_fence(&mfd->mdp_sync_pt_data);
		if (mfd->mdp.kickoff_fnc)
			ret = mfd->mdp.kickoff_fnc(mfd);
			ret = mfd->mdp.kickoff_fnc(mfd,
					  &fb_backup->disp_commit);
		if (!ret)
			mdss_fb_update_backlight(mfd);
		mdss_fb_signal_timeline(&mfd->mdp_sync_pt_data);
+2 −1
Original line number Diff line number Diff line
@@ -79,7 +79,8 @@ struct msm_mdp_interface {
	int (*off_fnc)(struct msm_fb_data_type *mfd);
	/* called to release resources associated to the process */
	int (*release_fnc)(struct msm_fb_data_type *mfd);
	int (*kickoff_fnc)(struct msm_fb_data_type *mfd);
	int (*kickoff_fnc)(struct msm_fb_data_type *mfd,
					struct mdp_display_commit *data);
	int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
	void (*dma_fnc)(struct msm_fb_data_type *mfd);
	int (*cursor_update)(struct msm_fb_data_type *mfd,
+18 −8
Original line number Diff line number Diff line
@@ -119,6 +119,13 @@ enum mdss_mdp_csc_type {
struct mdss_mdp_ctl;
typedef void (*mdp_vsync_handler_t)(struct mdss_mdp_ctl *, ktime_t);

struct mdss_mdp_img_rect {
	u16 x;
	u16 y;
	u16 w;
	u16 h;
};

struct mdss_mdp_vsync_handler {
	bool enabled;
	bool cmd_post_flush;
@@ -170,6 +177,9 @@ struct mdss_mdp_ctl {
	struct mdss_panel_data *panel_data;
	struct mdss_mdp_vsync_handler vsync_handler;

	struct mdss_mdp_img_rect roi;
	u8 roi_changed;

	int (*start_fnc) (struct mdss_mdp_ctl *ctl);
	int (*stop_fnc) (struct mdss_mdp_ctl *ctl);
	int (*prepare_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
@@ -196,6 +206,7 @@ struct mdss_mdp_mixer {
	u8 params_changed;
	u16 width;
	u16 height;
	struct mdss_mdp_img_rect roi;
	u8 cursor_enabled;
	u8 rotator_mode;

@@ -203,13 +214,6 @@ struct mdss_mdp_mixer {
	struct mdss_mdp_pipe *stage_pipe[MDSS_MDP_MAX_STAGE];
};

struct mdss_mdp_img_rect {
	u16 x;
	u16 y;
	u16 w;
	u16 h;
};

struct mdss_mdp_format_params {
	u32 format;
	u8 is_yuv;
@@ -467,7 +471,8 @@ int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata,
int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl);
int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl);
int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl);
int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd);
int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
		struct mdp_display_commit *data);

struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
					struct msm_fb_data_type *mfd);
@@ -577,6 +582,9 @@ int mdss_mdp_put_img(struct mdss_mdp_img_data *data);
int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data);
u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd);
int mdss_mdp_calc_phase_step(u32 src, u32 dst, u32 *out_phase);
void mdss_mdp_intersect_rect(struct mdss_mdp_img_rect *res_rect,
	const struct mdss_mdp_img_rect *dst_rect,
	const struct mdss_mdp_img_rect *sci_rect);

int mdss_mdp_wb_kickoff(struct msm_fb_data_type *mfd);
int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
@@ -594,6 +602,8 @@ int mdss_mdp_pipe_is_staged(struct mdss_mdp_pipe *pipe);
int mdss_mdp_writeback_display_commit(struct mdss_mdp_ctl *ctl, void *arg);
struct mdss_mdp_ctl *mdss_mdp_ctl_mixer_switch(struct mdss_mdp_ctl *ctl,
					       u32 return_type);
void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
					struct mdp_display_commit *data);

int mdss_mdp_wb_set_format(struct msm_fb_data_type *mfd, u32 dst_format);
int mdss_mdp_wb_get_format(struct msm_fb_data_type *mfd,
+50 −0
Original line number Diff line number Diff line
@@ -719,6 +719,7 @@ int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl)

	ctl->width = width;
	ctl->height = height;
	ctl->roi = (struct mdss_mdp_img_rect) {0, 0, width, height};

	if (!ctl->mixer_left) {
		ctl->mixer_left =
@@ -737,6 +738,7 @@ int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl)

	ctl->mixer_left->width = width;
	ctl->mixer_left->height = height;
	ctl->mixer_left->roi = (struct mdss_mdp_img_rect) {0, 0, width, height};

	if (split_ctl) {
		pr_debug("split display detected\n");
@@ -759,6 +761,8 @@ int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl)
		}
		ctl->mixer_right->width = width;
		ctl->mixer_right->height = height;
		ctl->mixer_right->roi = (struct mdss_mdp_img_rect)
						{0, 0, width, height};
	} else if (ctl->mixer_right) {
		mdss_mdp_mixer_free(ctl->mixer_right);
		ctl->mixer_right = NULL;
@@ -1249,6 +1253,48 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl)
	return 0;
}

void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
		struct mdp_display_commit *data)
{
	struct mdss_mdp_img_rect temp_roi, mixer_roi;

	temp_roi.x = data->roi.x;
	temp_roi.y = data->roi.y;
	temp_roi.w = data->roi.w;
	temp_roi.h = data->roi.h;

	/*
	 * No Partial Update for:
	 * 1) dual DSI panels
	 * 2) non-cmd mode panels
	*/
	if (!temp_roi.w || !temp_roi.h || ctl->mixer_right ||
			(ctl->panel_data->panel_info.type != MIPI_CMD_PANEL) ||
			!ctl->panel_data->panel_info.partial_update_enabled) {
		temp_roi = (struct mdss_mdp_img_rect)
				{0, 0, ctl->mixer_left->width,
					ctl->mixer_left->height};
	}

	ctl->roi_changed = 0;
	if (((temp_roi.x != ctl->roi.x) ||
			(temp_roi.y != ctl->roi.y)) ||
			((temp_roi.w != ctl->roi.w) ||
			 (temp_roi.h != ctl->roi.h))) {
		ctl->roi = temp_roi;
		ctl->roi_changed++;

		mixer_roi = ctl->mixer_left->roi;
		if ((mixer_roi.w != temp_roi.w) ||
			(mixer_roi.h != temp_roi.h)) {
			ctl->mixer_left->roi = temp_roi;
			ctl->mixer_left->params_changed++;
		}
	}
	pr_debug("ROI requested: [%d, %d, %d, %d]\n",
			ctl->roi.x, ctl->roi.y, ctl->roi.w, ctl->roi.h);
}

static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl,
				struct mdss_mdp_mixer *mixer)
{
@@ -1258,6 +1304,7 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl,
	u32 fg_alpha = 0, bg_alpha = 0;
	int stage, secure = 0;
	int screen_state;
	int outsize = 0;

	screen_state = ctl->force_screen_state;

@@ -1266,6 +1313,9 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl,

	pr_debug("setup mixer=%d\n", mixer->num);

	outsize = (mixer->roi.h << 16) | mixer->roi.w;
	mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, outsize);

	if (screen_state == MDSS_SCREEN_FORCE_BLANK) {
		mixercfg = MDSS_MDP_LM_BORDER_COLOR;
		goto update_mixer;
Loading