diff options
| author | Xiaoming Zhou <zhoux@codeaurora.org> | 2013-12-17 13:20:23 -0500 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:24:41 -0700 |
| commit | 32af8d04f9fa9ed9051d540b557bd0dda5a2f7db (patch) | |
| tree | 8eb3a4625f953cc958d47b79ccb436d08760bc8e | |
| parent | b60e39cb232d1398aa8c417703d15c7ff89680d3 (diff) | |
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: Xiaoming Zhou <zhoux@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3_ctrl.c | 41 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3_dma.c | 53 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3_dma.h | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3_hwio.h | 3 |
4 files changed, 69 insertions, 32 deletions
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c index fa65f11d540a..c5e86930c6d1 100644 --- a/drivers/video/fbdev/msm/mdp3_ctrl.c +++ b/drivers/video/fbdev/msm/mdp3_ctrl.c @@ -402,10 +402,10 @@ static int mdp3_ctrl_get_intf_type(struct msm_fb_data_type *mfd) 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; - switch (mfd->fb_imgType) { + switch (imgType) { case MDP_RGB_565: format = MDP3_DMA_IBUF_FORMAT_RGB565; break; @@ -511,7 +511,7 @@ static int mdp3_ctrl_dma_init(struct msm_fb_data_type *mfd, fix = &fbi->fix; 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.height = panel_info->yres; sourceConfig.x = 0; @@ -884,14 +884,15 @@ static int mdp3_overlay_set(struct msm_fb_data_type *mfd, { int rc = 0; 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_info *fbi = mfd->fbi; int stride; + int format; fix = &fbi->fix; - var = &fbi->var; - stride = req->src.width * var->bits_per_pixel/8; + stride = req->src.width * ppp_bpp(req->src.format); + format = mdp3_ctrl_get_source_format(req->src.format); mutex_lock(&mdp3_session->lock); @@ -900,9 +901,18 @@ static int mdp3_overlay_set(struct msm_fb_data_type *mfd, mdp3_session->overlay = *req; if (req->id == MSMFB_NEW_REQUEST) { - if (fix->line_length != stride) - mdp3_session->dma->config_stride( - mdp3_session->dma, stride); + if (dma->source_config.stride != stride || + dma->source_config.width != req->src.width || + 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; req->id = 1; } @@ -918,13 +928,22 @@ static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx) struct mdp3_session_data *mdp3_session = mfd->mdp.private1; struct fb_info *fbi = mfd->fbi; struct fb_fix_screeninfo *fix; + struct mdss_panel_info *panel_info = mfd->panel_info; + int format; fix = &fbi->fix; + format = mdp3_ctrl_get_source_format(mfd->fb_imgType); mutex_lock(&mdp3_session->lock); if (mdp3_session->overlay.id == ndx && ndx == 1) { - mdp3_session->dma->config_stride(mdp3_session->dma, - fix->line_length); + struct mdp3_dma *dma = mdp3_session->dma; + 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_bufq_deinit(&mdp3_session->bufq_in); } else { diff --git a/drivers/video/fbdev/msm/mdp3_dma.c b/drivers/video/fbdev/msm/mdp3_dma.c index 13a453e01bbf..b2e97ca4f3d4 100644 --- a/drivers/video/fbdev/msm/mdp3_dma.c +++ b/drivers/video/fbdev/msm/mdp3_dma.c @@ -295,23 +295,6 @@ static int mdp3_dma_sync_config(struct mdp3_dma *dma, 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, struct mdp3_dma_source *source_config, struct mdp3_dma_output_config *output_config) @@ -348,6 +331,22 @@ static int mdp3_dmap_config(struct mdp3_dma *dma, 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, struct mdp3_dma_source *source_config, struct mdp3_dma_output_config *output_config) @@ -383,6 +382,22 @@ static int mdp3_dmas_config(struct mdp3_dma *dma, 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, struct mdp3_dma_cursor *cursor) { @@ -901,6 +916,7 @@ int mdp3_dma_init(struct mdp3_dma *dma) switch (dma->dma_sel) { case MDP3_DMA_P: dma->dma_config = mdp3_dmap_config; + dma->dma_config_source = mdp3_dmap_config_source; dma->config_cursor = mdp3_dmap_cursor_config; dma->config_ccs = mdp3_dmap_ccs_config; dma->config_histo = mdp3_dmap_histo_config; @@ -913,10 +929,10 @@ int mdp3_dma_init(struct mdp3_dma *dma) dma->dma_done_notifier = mdp3_dma_done_notifier; dma->start = mdp3_dma_start; dma->stop = mdp3_dma_stop; - dma->config_stride = mdp3_dma_stride_config; break; case MDP3_DMA_S: dma->dma_config = mdp3_dmas_config; + dma->dma_config_source = mdp3_dmas_config_source; dma->config_cursor = NULL; dma->config_ccs = NULL; dma->config_histo = NULL; @@ -928,7 +944,6 @@ int mdp3_dma_init(struct mdp3_dma *dma) dma->vsync_enable = mdp3_dma_vsync_enable; dma->start = mdp3_dma_start; dma->stop = mdp3_dma_stop; - dma->config_stride = mdp3_dma_stride_config; break; case MDP3_DMA_E: default: diff --git a/drivers/video/fbdev/msm/mdp3_dma.h b/drivers/video/fbdev/msm/mdp3_dma.h index d914c712ef72..a5bf654cd82d 100644 --- a/drivers/video/fbdev/msm/mdp3_dma.h +++ b/drivers/video/fbdev/msm/mdp3_dma.h @@ -264,6 +264,8 @@ struct mdp3_dma { struct mdp3_dma_source *source_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 (*stop)(struct mdp3_dma *dma, struct mdp3_intf *intf); @@ -290,8 +292,6 @@ struct mdp3_dma { 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, struct mdp3_notification *vsync_client); diff --git a/drivers/video/fbdev/msm/mdp3_hwio.h b/drivers/video/fbdev/msm/mdp3_hwio.h index b457c10560cd..5205b425ef7c 100644 --- a/drivers/video/fbdev/msm/mdp3_hwio.h +++ b/drivers/video/fbdev/msm/mdp3_hwio.h @@ -118,6 +118,9 @@ #define MDP3_REG_DMA_S_IBUF_Y_STRIDE 0xA000C #define MDP3_REG_DMA_S_OUT_XY 0xA0010 +/*DMA MASK*/ +#define MDP3_DMA_IBUF_FORMAT_MASK 0x06000000 + /*MISR*/ #define MDP3_REG_MODE_CLK 0x000D0000 #define MDP3_REG_MISR_RESET_CLK 0x000D0004 |
