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

Commit f76c937e authored by Xiaoming Zhou's avatar Xiaoming Zhou Committed by Terence Hampson
Browse files

msm: mdss: fix overlay set issue on 8x10



The driver was assuming the color format and resolution
of the overlay to be the same as frame buffer.  This
causes page fault and corruption if the client is using
a different color format or resolution.   The change is
to re-configure the dma pipe if the overlay configuration
is different from the default.

Change-Id: Ic7558811a3015a416b2428fb0d626bf13663e528
Signed-off-by: default avatarXiaoming Zhou <zhoux@codeaurora.org>
parent e57a1bb9
Loading
Loading
Loading
Loading
+30 −11
Original line number Original line Diff line number Diff line
@@ -366,10 +366,10 @@ static int mdp3_ctrl_get_intf_type(struct msm_fb_data_type *mfd)
	return type;
	return type;
}
}


static int mdp3_ctrl_get_source_format(struct msm_fb_data_type *mfd)
static int mdp3_ctrl_get_source_format(u32 imgType)
{
{
	int format;
	int format;
	switch (mfd->fb_imgType) {
	switch (imgType) {
	case MDP_RGB_565:
	case MDP_RGB_565:
		format = MDP3_DMA_IBUF_FORMAT_RGB565;
		format = MDP3_DMA_IBUF_FORMAT_RGB565;
		break;
		break;
@@ -474,7 +474,7 @@ static int mdp3_ctrl_dma_init(struct msm_fb_data_type *mfd,
	fix = &fbi->fix;
	fix = &fbi->fix;
	var = &fbi->var;
	var = &fbi->var;


	sourceConfig.format = mdp3_ctrl_get_source_format(mfd);
	sourceConfig.format = mdp3_ctrl_get_source_format(mfd->fb_imgType);
	sourceConfig.width = panel_info->xres;
	sourceConfig.width = panel_info->xres;
	sourceConfig.height = panel_info->yres;
	sourceConfig.height = panel_info->yres;
	sourceConfig.x = 0;
	sourceConfig.x = 0;
@@ -836,14 +836,15 @@ static int mdp3_overlay_set(struct msm_fb_data_type *mfd,
{
{
	int rc = 0;
	int rc = 0;
	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
	struct fb_var_screeninfo *var;
	struct mdp3_dma *dma = mdp3_session->dma;
	struct fb_fix_screeninfo *fix;
	struct fb_fix_screeninfo *fix;
	struct fb_info *fbi = mfd->fbi;
	struct fb_info *fbi = mfd->fbi;
	int stride;
	int stride;
	int format;


	fix = &fbi->fix;
	fix = &fbi->fix;
	var = &fbi->var;
	stride = req->src.width * ppp_bpp(req->src.format);
	stride = req->src.width * var->bits_per_pixel/8;
	format = mdp3_ctrl_get_source_format(req->src.format);


	mutex_lock(&mdp3_session->lock);
	mutex_lock(&mdp3_session->lock);


@@ -852,9 +853,18 @@ static int mdp3_overlay_set(struct msm_fb_data_type *mfd,


	mdp3_session->overlay = *req;
	mdp3_session->overlay = *req;
	if (req->id == MSMFB_NEW_REQUEST) {
	if (req->id == MSMFB_NEW_REQUEST) {
		if (fix->line_length != stride)
		if (dma->source_config.stride != stride ||
			mdp3_session->dma->config_stride(
				dma->source_config.width != req->src.width ||
						mdp3_session->dma, stride);
				dma->source_config.height != req->src.height ||
				dma->source_config.format != format) {
			dma->source_config.width = req->src.width;
			dma->source_config.height = req->src.height,
			dma->source_config.format = format;
			dma->source_config.stride = stride;
			mdp3_clk_enable(1, 0);
			mdp3_session->dma->dma_config_source(dma);
			mdp3_clk_enable(0, 0);
		}
		mdp3_session->overlay.id = 1;
		mdp3_session->overlay.id = 1;
		req->id = 1;
		req->id = 1;
	}
	}
@@ -870,13 +880,22 @@ static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx)
	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
	struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
	struct fb_info *fbi = mfd->fbi;
	struct fb_info *fbi = mfd->fbi;
	struct fb_fix_screeninfo *fix;
	struct fb_fix_screeninfo *fix;
	struct mdss_panel_info *panel_info = mfd->panel_info;
	int format;


	fix = &fbi->fix;
	fix = &fbi->fix;
	format = mdp3_ctrl_get_source_format(mfd->fb_imgType);
	mutex_lock(&mdp3_session->lock);
	mutex_lock(&mdp3_session->lock);


	if (mdp3_session->overlay.id == ndx && ndx == 1) {
	if (mdp3_session->overlay.id == ndx && ndx == 1) {
		mdp3_session->dma->config_stride(mdp3_session->dma,
		struct mdp3_dma *dma = mdp3_session->dma;
							fix->line_length);
		dma->source_config.width = panel_info->xres,
		dma->source_config.height = panel_info->yres,
		dma->source_config.format = format;
		dma->source_config.stride = fix->line_length;
		mdp3_clk_enable(1, 0);
		mdp3_session->dma->dma_config_source(dma);
		mdp3_clk_enable(0, 0);
		mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
		mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
		mdp3_bufq_deinit(&mdp3_session->bufq_in);
		mdp3_bufq_deinit(&mdp3_session->bufq_in);
	} else {
	} else {
+34 −19
Original line number Original line Diff line number Diff line
@@ -274,23 +274,6 @@ static int mdp3_dma_sync_config(struct mdp3_dma *dma,
	return 0;
	return 0;
}
}


static void mdp3_dma_stride_config(struct mdp3_dma *dma, int stride)
{
	struct mdp3_dma_source *source_config;
	u32 dma_stride_offset;

	if (dma->dma_sel == MDP3_DMA_P)
		dma_stride_offset = MDP3_REG_DMA_P_IBUF_Y_STRIDE;
	else
		dma_stride_offset = MDP3_REG_DMA_S_IBUF_Y_STRIDE;

	source_config = &dma->source_config;
	source_config->stride = stride;
	pr_debug("%s: Update the fb stride for DMA to %d", __func__,
						(u32)source_config->stride);
	MDP3_REG_WRITE(dma_stride_offset, source_config->stride);
}

static int mdp3_dmap_config(struct mdp3_dma *dma,
static int mdp3_dmap_config(struct mdp3_dma *dma,
			struct mdp3_dma_source *source_config,
			struct mdp3_dma_source *source_config,
			struct mdp3_dma_output_config *output_config)
			struct mdp3_dma_output_config *output_config)
@@ -327,6 +310,22 @@ static int mdp3_dmap_config(struct mdp3_dma *dma,
	return 0;
	return 0;
}
}


static void mdp3_dmap_config_source(struct mdp3_dma *dma)
{
	struct mdp3_dma_source *source_config = &dma->source_config;
	u32 dma_p_cfg_reg, dma_p_size;

	dma_p_cfg_reg = MDP3_REG_READ(MDP3_REG_DMA_P_CONFIG);
	dma_p_cfg_reg &= ~MDP3_DMA_IBUF_FORMAT_MASK;
	dma_p_cfg_reg |= source_config->format << 25;

	dma_p_size = source_config->width | (source_config->height << 16);

	MDP3_REG_WRITE(MDP3_REG_DMA_P_CONFIG, dma_p_cfg_reg);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_SIZE, dma_p_size);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_Y_STRIDE, source_config->stride);
}

static int mdp3_dmas_config(struct mdp3_dma *dma,
static int mdp3_dmas_config(struct mdp3_dma *dma,
			struct mdp3_dma_source *source_config,
			struct mdp3_dma_source *source_config,
			struct mdp3_dma_output_config *output_config)
			struct mdp3_dma_output_config *output_config)
@@ -362,6 +361,22 @@ static int mdp3_dmas_config(struct mdp3_dma *dma,
	return 0;
	return 0;
}
}


static void mdp3_dmas_config_source(struct mdp3_dma *dma)
{
	struct mdp3_dma_source *source_config = &dma->source_config;
	u32 dma_s_cfg_reg, dma_s_size;

	dma_s_cfg_reg = MDP3_REG_READ(MDP3_REG_DMA_S_CONFIG);
	dma_s_cfg_reg &= ~MDP3_DMA_IBUF_FORMAT_MASK;
	dma_s_cfg_reg |= source_config->format << 25;

	dma_s_size = source_config->width | (source_config->height << 16);

	MDP3_REG_WRITE(MDP3_REG_DMA_S_CONFIG, dma_s_cfg_reg);
	MDP3_REG_WRITE(MDP3_REG_DMA_S_SIZE, dma_s_size);
	MDP3_REG_WRITE(MDP3_REG_DMA_S_IBUF_Y_STRIDE, source_config->stride);
}

static int mdp3_dmap_cursor_config(struct mdp3_dma *dma,
static int mdp3_dmap_cursor_config(struct mdp3_dma *dma,
				struct mdp3_dma_cursor *cursor)
				struct mdp3_dma_cursor *cursor)
{
{
@@ -869,6 +884,7 @@ int mdp3_dma_init(struct mdp3_dma *dma)
	switch (dma->dma_sel) {
	switch (dma->dma_sel) {
	case MDP3_DMA_P:
	case MDP3_DMA_P:
		dma->dma_config = mdp3_dmap_config;
		dma->dma_config = mdp3_dmap_config;
		dma->dma_config_source = mdp3_dmap_config_source;
		dma->config_cursor = mdp3_dmap_cursor_config;
		dma->config_cursor = mdp3_dmap_cursor_config;
		dma->config_ccs = mdp3_dmap_ccs_config;
		dma->config_ccs = mdp3_dmap_ccs_config;
		dma->config_histo = mdp3_dmap_histo_config;
		dma->config_histo = mdp3_dmap_histo_config;
@@ -880,10 +896,10 @@ int mdp3_dma_init(struct mdp3_dma *dma)
		dma->vsync_enable = mdp3_dma_vsync_enable;
		dma->vsync_enable = mdp3_dma_vsync_enable;
		dma->start = mdp3_dma_start;
		dma->start = mdp3_dma_start;
		dma->stop = mdp3_dma_stop;
		dma->stop = mdp3_dma_stop;
		dma->config_stride = mdp3_dma_stride_config;
		break;
		break;
	case MDP3_DMA_S:
	case MDP3_DMA_S:
		dma->dma_config = mdp3_dmas_config;
		dma->dma_config = mdp3_dmas_config;
		dma->dma_config_source = mdp3_dmas_config_source;
		dma->config_cursor = NULL;
		dma->config_cursor = NULL;
		dma->config_ccs = NULL;
		dma->config_ccs = NULL;
		dma->config_histo = NULL;
		dma->config_histo = NULL;
@@ -895,7 +911,6 @@ int mdp3_dma_init(struct mdp3_dma *dma)
		dma->vsync_enable = mdp3_dma_vsync_enable;
		dma->vsync_enable = mdp3_dma_vsync_enable;
		dma->start = mdp3_dma_start;
		dma->start = mdp3_dma_start;
		dma->stop = mdp3_dma_stop;
		dma->stop = mdp3_dma_stop;
		dma->config_stride = mdp3_dma_stride_config;
		break;
		break;
	case MDP3_DMA_E:
	case MDP3_DMA_E:
	default:
	default:
+2 −2
Original line number Original line Diff line number Diff line
@@ -262,6 +262,8 @@ struct mdp3_dma {
			struct mdp3_dma_source *source_config,
			struct mdp3_dma_source *source_config,
			struct mdp3_dma_output_config *output_config);
			struct mdp3_dma_output_config *output_config);


	void (*dma_config_source)(struct mdp3_dma *dma);

	int (*start)(struct mdp3_dma *dma, struct mdp3_intf *intf);
	int (*start)(struct mdp3_dma *dma, struct mdp3_intf *intf);


	int (*stop)(struct mdp3_dma *dma, struct mdp3_intf *intf);
	int (*stop)(struct mdp3_dma *dma, struct mdp3_intf *intf);
@@ -288,8 +290,6 @@ struct mdp3_dma {


	int (*histo_op)(struct mdp3_dma *dma, u32 op);
	int (*histo_op)(struct mdp3_dma *dma, u32 op);


	void (*config_stride)(struct mdp3_dma *dma, int stride);

	void (*vsync_enable)(struct mdp3_dma *dma,
	void (*vsync_enable)(struct mdp3_dma *dma,
			struct mdp3_vsync_notification *vsync_client);
			struct mdp3_vsync_notification *vsync_client);
};
};
+3 −0
Original line number Original line Diff line number Diff line
@@ -118,6 +118,9 @@
#define MDP3_REG_DMA_S_IBUF_Y_STRIDE			0xA000C
#define MDP3_REG_DMA_S_IBUF_Y_STRIDE			0xA000C
#define MDP3_REG_DMA_S_OUT_XY				0xA0010
#define MDP3_REG_DMA_S_OUT_XY				0xA0010


/*DMA MASK*/
#define MDP3_DMA_IBUF_FORMAT_MASK 0x06000000

/*MISR*/
/*MISR*/
#define MDP3_REG_MODE_CLK				0x000D0000
#define MDP3_REG_MODE_CLK				0x000D0000
#define MDP3_REG_MISR_RESET_CLK			0x000D0004
#define MDP3_REG_MISR_RESET_CLK			0x000D0004