diff options
Diffstat (limited to 'drivers/video/mmp')
-rw-r--r-- | drivers/video/mmp/fb/mmpfb.c | 34 | ||||
-rw-r--r-- | drivers/video/mmp/hw/mmp_ctrl.c | 71 | ||||
-rw-r--r-- | drivers/video/mmp/hw/mmp_ctrl.h | 5 |
3 files changed, 68 insertions, 42 deletions
diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/mmp/fb/mmpfb.c index 4ab95b8daed..7ab31eb76a8 100644 --- a/drivers/video/mmp/fb/mmpfb.c +++ b/drivers/video/mmp/fb/mmpfb.c @@ -392,12 +392,29 @@ static int var_update(struct fb_info *info) return 0; } +static void mmpfb_set_win(struct fb_info *info) +{ + struct mmpfb_info *fbi = info->par; + struct fb_var_screeninfo *var = &info->var; + struct mmp_win win; + u32 stride; + + memset(&win, 0, sizeof(win)); + win.xsrc = win.xdst = fbi->mode.xres; + win.ysrc = win.ydst = fbi->mode.yres; + win.pix_fmt = fbi->pix_fmt; + stride = pixfmt_to_stride(win.pix_fmt); + win.pitch[0] = var->xres_virtual * stride; + win.pitch[1] = win.pitch[2] = + (stride == 1) ? (var->xres_virtual >> 1) : 0; + mmp_overlay_set_win(fbi->overlay, &win); +} + static int mmpfb_set_par(struct fb_info *info) { struct mmpfb_info *fbi = info->par; struct fb_var_screeninfo *var = &info->var; struct mmp_addr addr; - struct mmp_win win; struct mmp_mode mode; int ret; @@ -409,11 +426,8 @@ static int mmpfb_set_par(struct fb_info *info) fbmode_to_mmpmode(&mode, &fbi->mode, fbi->output_fmt); mmp_path_set_mode(fbi->path, &mode); - memset(&win, 0, sizeof(win)); - win.xsrc = win.xdst = fbi->mode.xres; - win.ysrc = win.ydst = fbi->mode.yres; - win.pix_fmt = fbi->pix_fmt; - mmp_overlay_set_win(fbi->overlay, &win); + /* set window related info */ + mmpfb_set_win(info); /* set address always */ memset(&addr, 0, sizeof(addr)); @@ -427,16 +441,12 @@ static int mmpfb_set_par(struct fb_info *info) static void mmpfb_power(struct mmpfb_info *fbi, int power) { struct mmp_addr addr; - struct mmp_win win; struct fb_var_screeninfo *var = &fbi->fb_info->var; /* for power on, always set address/window again */ if (power) { - memset(&win, 0, sizeof(win)); - win.xsrc = win.xdst = fbi->mode.xres; - win.ysrc = win.ydst = fbi->mode.yres; - win.pix_fmt = fbi->pix_fmt; - mmp_overlay_set_win(fbi->overlay, &win); + /* set window related info */ + mmpfb_set_win(fbi->fb_info); /* set address always */ memset(&addr, 0, sizeof(addr)); diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c index 6ac755270ab..8621a9f2bdc 100644 --- a/drivers/video/mmp/hw/mmp_ctrl.c +++ b/drivers/video/mmp/hw/mmp_ctrl.c @@ -53,15 +53,14 @@ static irqreturn_t ctrl_handle_irq(int irq, void *dev_id) tmp = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR); if (tmp & isr) writel_relaxed(~isr, ctrl->reg_base + SPU_IRQ_ISR); - } while ((isr = readl(ctrl->reg_base + SPU_IRQ_ISR)) & imask); + } while ((isr = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR)) & imask); return IRQ_HANDLED; } static u32 fmt_to_reg(struct mmp_overlay *overlay, int pix_fmt) { - u32 link_config = path_to_path_plat(overlay->path)->link_config; - u32 rbswap, uvswap = 0, yuvswap = 0, + u32 rbswap = 0, uvswap = 0, yuvswap = 0, csc_en = 0, val = 0, vid = overlay_is_vid(overlay); @@ -71,27 +70,23 @@ static u32 fmt_to_reg(struct mmp_overlay *overlay, int pix_fmt) case PIXFMT_RGB888PACK: case PIXFMT_RGB888UNPACK: case PIXFMT_RGBA888: - rbswap = !(link_config & 0x1); + rbswap = 1; break; case PIXFMT_VYUY: case PIXFMT_YVU422P: case PIXFMT_YVU420P: - rbswap = link_config & 0x1; uvswap = 1; break; case PIXFMT_YUYV: - rbswap = link_config & 0x1; yuvswap = 1; break; default: - rbswap = link_config & 0x1; break; } switch (pix_fmt) { case PIXFMT_RGB565: case PIXFMT_BGR565: - val = 0; break; case PIXFMT_RGB1555: case PIXFMT_BGR1555: @@ -147,17 +142,27 @@ static void dmafetch_set_fmt(struct mmp_overlay *overlay) static void overlay_set_win(struct mmp_overlay *overlay, struct mmp_win *win) { struct lcd_regs *regs = path_regs(overlay->path); - u32 pitch; /* assert win supported */ memcpy(&overlay->win, win, sizeof(struct mmp_win)); mutex_lock(&overlay->access_ok); - pitch = win->xsrc * pixfmt_to_stride(win->pix_fmt); - writel_relaxed(pitch, ®s->g_pitch); - writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->g_size); - writel_relaxed((win->ydst << 16) | win->xdst, ®s->g_size_z); - writel_relaxed(0, ®s->g_start); + + if (overlay_is_vid(overlay)) { + writel_relaxed(win->pitch[0], ®s->v_pitch_yc); + writel_relaxed(win->pitch[2] << 16 | + win->pitch[1], ®s->v_pitch_uv); + + writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->v_size); + writel_relaxed((win->ydst << 16) | win->xdst, ®s->v_size_z); + writel_relaxed(win->ypos << 16 | win->xpos, ®s->v_start); + } else { + writel_relaxed(win->pitch[0], ®s->g_pitch); + + writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->g_size); + writel_relaxed((win->ydst << 16) | win->xdst, ®s->g_size_z); + writel_relaxed(win->ypos << 16 | win->xpos, ®s->g_start); + } dmafetch_set_fmt(overlay); mutex_unlock(&overlay->access_ok); @@ -239,7 +244,13 @@ static int overlay_set_addr(struct mmp_overlay *overlay, struct mmp_addr *addr) /* FIXME: assert addr supported */ memcpy(&overlay->addr, addr, sizeof(struct mmp_addr)); - writel(addr->phys[0], ®s->g_0); + + if (overlay_is_vid(overlay)) { + writel_relaxed(addr->phys[0], ®s->v_y0); + writel_relaxed(addr->phys[1], ®s->v_u0); + writel_relaxed(addr->phys[2], ®s->v_v0); + } else + writel_relaxed(addr->phys[0], ®s->g_0); return overlay->addr.phys[0]; } @@ -248,7 +259,8 @@ static void path_set_mode(struct mmp_path *path, struct mmp_mode *mode) { struct lcd_regs *regs = path_regs(path); u32 total_x, total_y, vsync_ctrl, tmp, sclk_src, sclk_div, - link_config = path_to_path_plat(path)->link_config; + link_config = path_to_path_plat(path)->link_config, + dsi_rbswap = path_to_path_plat(path)->link_config; /* FIXME: assert videomode supported */ memcpy(&path->mode, mode, sizeof(struct mmp_mode)); @@ -263,6 +275,12 @@ static void path_set_mode(struct mmp_path *path, struct mmp_mode *mode) tmp |= CFG_DUMB_ENA(1); writel_relaxed(tmp, ctrl_regs(path) + intf_ctrl(path->id)); + /* interface rb_swap setting */ + tmp = readl_relaxed(ctrl_regs(path) + intf_rbswap_ctrl(path->id)) & + (~(CFG_INTFRBSWAP_MASK)); + tmp |= dsi_rbswap & CFG_INTFRBSWAP_MASK; + writel_relaxed(tmp, ctrl_regs(path) + intf_rbswap_ctrl(path->id)); + writel_relaxed((mode->yres << 16) | mode->xres, ®s->screen_active); writel_relaxed((mode->left_margin << 16) | mode->right_margin, ®s->screen_h_porch); @@ -370,20 +388,12 @@ static void path_set_default(struct mmp_path *path) * bus arbiter for faster read if not tv path; * 2.enable horizontal smooth filter; */ - if (PATH_PN == path->id) { - mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK - | CFG_ARBFAST_ENA(1); - tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id)); - tmp |= mask; - writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id)); - } else if (PATH_TV == path->id) { - mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK - | CFG_ARBFAST_ENA(1); - tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id)); - tmp &= ~mask; - tmp |= CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK; - writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id)); - } + mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK | CFG_ARBFAST_ENA(1); + tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id)); + tmp |= mask; + if (PATH_TV == path->id) + tmp &= ~CFG_ARBFAST_ENA(1); + writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id)); } static int path_init(struct mmphw_path_plat *path_plat, @@ -419,6 +429,7 @@ static int path_init(struct mmphw_path_plat *path_plat, path_plat->path = path; path_plat->path_config = config->path_config; path_plat->link_config = config->link_config; + path_plat->dsi_rbswap = config->dsi_rbswap; path_set_default(path); kfree(path_info); diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/mmp/hw/mmp_ctrl.h index edd2002b0e9..53301cfdb1a 100644 --- a/drivers/video/mmp/hw/mmp_ctrl.h +++ b/drivers/video/mmp/hw/mmp_ctrl.h @@ -163,6 +163,8 @@ struct lcd_regs { #define LCD_SCLK(path) ((PATH_PN == path->id) ? LCD_CFG_SCLK_DIV :\ ((PATH_TV == path->id) ? LCD_TCLK_DIV : LCD_PN2_SCLK_DIV)) +#define intf_rbswap_ctrl(id) ((id) ? (((id) & 1) ? LCD_TVIF_CTRL : \ + PN2_IOPAD_CONTROL) : LCD_TOP_CTRL) /* dither configure */ #ifdef CONFIG_CPU_PXA988 @@ -615,6 +617,8 @@ struct lcd_regs { #define LCD_SPU_DUMB_CTRL 0x01B8 #define CFG_DUMBMODE(mode) ((mode)<<28) #define CFG_DUMBMODE_MASK 0xF0000000 +#define CFG_INTFRBSWAP(mode) ((mode)<<24) +#define CFG_INTFRBSWAP_MASK 0x0F000000 #define CFG_LCDGPIO_O(data) ((data)<<20) #define CFG_LCDGPIO_O_MASK 0x0FF00000 #define CFG_LCDGPIO_ENA(gpio) ((gpio)<<12) @@ -1427,6 +1431,7 @@ struct mmphw_path_plat { struct mmp_path *path; u32 path_config; u32 link_config; + u32 dsi_rbswap; }; /* mmp ctrl describes mmp controller related info */ |