diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2015-07-01 15:13:51 +0200 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2015-07-02 09:21:12 +0200 |
commit | 8f30ee5981b6cc2014c0eb9e4506192db7918f29 (patch) | |
tree | a1eae5a9b2035fe2842b134b45fc8e84ea32b47e | |
parent | c6b151cc662e291bcd1cc9861349ebb445493492 (diff) |
video: fsl-dcu-fb: consider initial yoffset
Initial Y-offset has not been considered, which could lead to
unexpected behavior when initializing with a yoffset other than 0.
-rw-r--r-- | drivers/video/fbdev/fsl-dcu-fb.c | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/drivers/video/fbdev/fsl-dcu-fb.c b/drivers/video/fbdev/fsl-dcu-fb.c index 844c6d4efa51..a350b034e7a0 100644 --- a/drivers/video/fbdev/fsl-dcu-fb.c +++ b/drivers/video/fbdev/fsl-dcu-fb.c @@ -231,12 +231,23 @@ static struct mfb_info mfb_template[] = { }, }; +static inline unsigned int fsl_dcu_get_offset(struct fb_info *info) +{ + struct fb_var_screeninfo *var = &info->var; + int pixel_offset; + + pixel_offset = (var->yoffset * var->xres_virtual) + var->xoffset; + return info->fix.smem_start + + (pixel_offset * (var->bits_per_pixel >> 3)); +} + static int enable_panel(struct fb_info *info) { struct fb_var_screeninfo *var = &info->var; struct mfb_info *mfbi = info->par; struct dcu_fb_data *dcufb = mfbi->parent; unsigned int bpp; + unsigned int addr; writel(DCU_CTRLDESCLN_1_HEIGHT(var->yres) | DCU_CTRLDESCLN_1_WIDTH(var->xres), @@ -245,8 +256,8 @@ static int enable_panel(struct fb_info *info) DCU_CTRLDESCLN_2_POSX(mfbi->x_layer_d), dcufb->reg_base + DCU_CTRLDESCLN_2(mfbi->index)); - writel(info->fix.smem_start, - dcufb->reg_base + DCU_CTRLDESCLN_3(mfbi->index)); + addr = fsl_dcu_get_offset(info); + writel(addr, dcufb->reg_base + DCU_CTRLDESCLN_3(mfbi->index)); switch (var->bits_per_pixel) { case 16: @@ -529,24 +540,6 @@ static void unmap_video_memory(struct fb_info *info) info->fix.smem_len = 0; } -static int fsl_dcu_set_layer(struct fb_info *info) -{ - struct mfb_info *mfbi = info->par; - struct fb_var_screeninfo *var = &info->var; - struct dcu_fb_data *dcufb = mfbi->parent; - int pixel_offset; - unsigned long addr; - - pixel_offset = (var->yoffset * var->xres_virtual) + var->xoffset; - addr = info->fix.smem_start + - (pixel_offset * (var->bits_per_pixel >> 3)); - - writel(addr, dcufb->reg_base + DCU_CTRLDESCLN_3(mfbi->index)); - writel(DCU_UPDATE_MODE_READREG, dcufb->reg_base + DCU_UPDATE_MODE); - - return 0; -} - static int fsl_dcu_set_par(struct fb_info *info) { unsigned long len; @@ -635,6 +628,10 @@ static int fsl_dcu_setcolreg(unsigned regno, unsigned red, unsigned green, static int fsl_dcu_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { + struct mfb_info *mfbi = info->par; + struct dcu_fb_data *dcufb = mfbi->parent; + unsigned int addr; + if ((info->var.xoffset == var->xoffset) && (info->var.yoffset == var->yoffset)) return 0; @@ -651,7 +648,9 @@ static int fsl_dcu_pan_display(struct fb_var_screeninfo *var, else info->var.vmode &= ~FB_VMODE_YWRAP; - fsl_dcu_set_layer(info); + addr = fsl_dcu_get_offset(info); + writel(addr, dcufb->reg_base + DCU_CTRLDESCLN_3(mfbi->index)); + writel(DCU_UPDATE_MODE_READREG, dcufb->reg_base + DCU_UPDATE_MODE); return 0; } |