/** * s3c_fb_blank() - blank or unblank the given window * @blank_mode: The blank state from FB_BLANK_* * @info: The framebuffer to blank. * * Framebuffer layer request to change the power state. */ static int s3c_fb_blank(int blank_mode, struct fb_info *info) { struct s3c_fb_win *win = info->par; struct s3c_fb *sfb = win->parent; unsigned int index = win->index; u32 wincon; dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); wincon = readl(sfb->regs + WINCON(index)); switch (blank_mode) { case FB_BLANK_POWERDOWN: wincon &= ~WINCONx_ENWIN; sfb->enabled &= ~(1 << index); /* fall through to FB_BLANK_NORMAL */ case FB_BLANK_NORMAL: /* disable the DMA and display 0x0 (black) */ writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), sfb->regs + WINxMAP(index)); break; case FB_BLANK_UNBLANK: writel(0x0, sfb->regs + WINxMAP(index)); wincon |= WINCONx_ENWIN; sfb->enabled |= (1 << index); break; case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND: default: return 1; } writel(wincon, sfb->regs + WINCON(index)); /* Check the enabled state to see if we need to be running the * main LCD interface, as if there are no active windows then * it is highly likely that we also do not need to output * anything. */ /* We could do something like the following code, but the current * system of using framebuffer events means that we cannot make * the distinction between just window 0 being inactive and all * the windows being down. * * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); */ /* we're stuck with this until we can do something about overriding * the power control using the blanking event for a single fb. */ if (index == 0) s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); return 0; }
int decon_reg_is_win_enabled(int idx) { if (decon_read(WINCON(idx)) & WINCONx_ENWIN) return 1; return 0; }
static int s3c_fb_blank(int blank_mode, struct fb_info *info) { struct s3c_fb_win *win = info->par; struct s3c_fb *sfb = win->parent; unsigned int index = win->index; u32 wincon; dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); wincon = readl(sfb->regs + WINCON(index)); switch (blank_mode) { case FB_BLANK_POWERDOWN: wincon &= ~WINCONx_ENWIN; sfb->enabled &= ~(1 << index); case FB_BLANK_NORMAL: writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), sfb->regs + WINxMAP(index)); break; case FB_BLANK_UNBLANK: writel(0x0, sfb->regs + WINxMAP(index)); wincon |= WINCONx_ENWIN; sfb->enabled |= (1 << index); break; case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND: default: return 1; } writel(wincon, sfb->regs + WINCON(index)); if (index == 0) s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); return 0; }
void decon_reg_clear_win(int win) { decon_write(WINCON(win), 0); decon_write(VIDOSD_A(win), 0); decon_write(VIDOSD_B(win), 0); decon_write(VIDOSD_C(win), 0); decon_write(VIDOSD_D(win), 0); }
static void decon_int_get_enabled_win(struct decon_device *decon) { int i; decon->underrun_stat.used_windows = 0; for (i = 0; i < decon->pdata->max_win; ++i) if (decon_read(decon->id, WINCON(i)) & WINCON_ENWIN) set_bit(i * 4, &decon->underrun_stat.used_windows); }
/** * s3c_fb_clear_win() - clear hardware window registers. * @sfb: The base resources for the hardware. * @win: The window to process. * * Reset the specific window registers to a known state. */ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win) { void __iomem *regs = sfb->regs; writel(0, regs + WINCON(win)); writel(0xffffff, regs + WxKEYCONy(win, 0)); writel(0xffffff, regs + WxKEYCONy(win, 1)); writel(0, regs + VIDOSD_A(win)); writel(0, regs + VIDOSD_B(win)); writel(0, regs + VIDOSD_C(win)); }
void decon_reg_set_regs_data(int idx, struct decon_regs_data *regs) { decon_write(WINCON(idx), regs->wincon); decon_write(WINxMAP(idx), regs->winmap); decon_write(VIDOSD_A(idx), regs->vidosd_a); decon_write(VIDOSD_B(idx), regs->vidosd_b); decon_write(VIDOSD_C(idx), regs->vidosd_c); decon_write(VIDOSD_D(idx), regs->vidosd_d); decon_write(VIDW_BUF_START(idx), regs->vidw_buf_start); decon_write(VIDW_BUF_END(idx), regs->vidw_buf_end); decon_write(VIDW_BUF_SIZE(idx), regs->vidw_buf_size); if (idx) decon_write(BLENDEQ(idx - 1), regs->blendeq); }
/** * s3c_fb_set_par() - framebuffer request to set new framebuffer state. * @info: The framebuffer to change. * * Framebuffer layer request to set a new mode for the specified framebuffer */ static int s3c_fb_set_par(struct fb_info *info) { struct fb_var_screeninfo *var = &info->var; struct s3c_fb_win *win = info->par; struct s3c_fb *sfb = win->parent; void __iomem *regs = sfb->regs; int win_no = win->index; u32 osdc_data = 0; u32 data; u32 pagewidth; int clkdiv; dev_dbg(sfb->dev, "setting framebuffer parameters\n"); switch (var->bits_per_pixel) { case 32: case 24: case 16: case 12: info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 8: if (s3c_fb_win_has_palette(win_no, 8)) info->fix.visual = FB_VISUAL_PSEUDOCOLOR; else info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 1: info->fix.visual = FB_VISUAL_MONO01; break; default: info->fix.visual = FB_VISUAL_PSEUDOCOLOR; break; } info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; /* disable the window whilst we update it */ writel(0, regs + WINCON(win_no)); /* use window 0 as the basis for the lcd output timings */ if (win_no == 0) { clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); data = sfb->pdata->vidcon0; data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); if (clkdiv > 1) data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR; else data &= ~VIDCON0_CLKDIR; /* 1:1 clock */ /* write the timing data to the panel */ data |= VIDCON0_ENVID | VIDCON0_ENVID_F; writel(data, regs + VIDCON0); data = VIDTCON0_VBPD(var->upper_margin - 1) | VIDTCON0_VFPD(var->lower_margin - 1) | VIDTCON0_VSPW(var->vsync_len - 1); writel(data, regs + VIDTCON0); data = VIDTCON1_HBPD(var->left_margin - 1) | VIDTCON1_HFPD(var->right_margin - 1) | VIDTCON1_HSPW(var->hsync_len - 1); writel(data, regs + VIDTCON1); data = VIDTCON2_LINEVAL(var->yres - 1) | VIDTCON2_HOZVAL(var->xres - 1); writel(data, regs + VIDTCON2); } /* write the buffer address */ writel(info->fix.smem_start, regs + VIDW_BUF_START(win_no)); data = info->fix.smem_start + info->fix.line_length * var->yres; writel(data, regs + VIDW_BUF_END(win_no)); pagewidth = (var->xres * var->bits_per_pixel) >> 3; data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | VIDW_BUF_SIZE_PAGEWIDTH(pagewidth); writel(data, regs + VIDW_BUF_SIZE(win_no)); /* write 'OSD' registers to control position of framebuffer */ data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0); writel(data, regs + VIDOSD_A(win_no)); data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, var->xres - 1)) | VIDOSDxB_BOTRIGHT_Y(var->yres - 1); writel(data, regs + VIDOSD_B(win_no)); data = var->xres * var->yres; osdc_data = VIDISD14C_ALPHA1_R(0xf) | VIDISD14C_ALPHA1_G(0xf) | VIDISD14C_ALPHA1_B(0xf); if (s3c_fb_has_osd_d(win_no)) { writel(data, regs + VIDOSD_D(win_no)); writel(osdc_data, regs + VIDOSD_C(win_no)); } else writel(data, regs + VIDOSD_C(win_no)); data = WINCONx_ENWIN; /* note, since we have to round up the bits-per-pixel, we end up * relying on the bitfield information for r/g/b/a to work out * exactly which mode of operation is intended. */ switch (var->bits_per_pixel) { case 1: data |= WINCON0_BPPMODE_1BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_4WORD; break; case 2: data |= WINCON0_BPPMODE_2BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_8WORD; break; case 4: data |= WINCON0_BPPMODE_4BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_8WORD; break; case 8: if (var->transp.length != 0) data |= WINCON1_BPPMODE_8BPP_1232; else data |= WINCON0_BPPMODE_8BPP_PALETTE; data |= WINCONx_BURSTLEN_8WORD; data |= WINCONx_BYTSWP; break; case 16: if (var->transp.length != 0) data |= WINCON1_BPPMODE_16BPP_A1555; else data |= WINCON0_BPPMODE_16BPP_565; data |= WINCONx_HAWSWP; data |= WINCONx_BURSTLEN_16WORD; break; case 24: case 32: if (var->red.length == 6) { if (var->transp.length != 0) data |= WINCON1_BPPMODE_19BPP_A1666; else data |= WINCON1_BPPMODE_18BPP_666; } else if (var->transp.length == 1) data |= WINCON1_BPPMODE_25BPP_A1888 | WINCON1_BLD_PIX; else if (var->transp.length == 4) data |= WINCON1_BPPMODE_28BPP_A4888 | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; else data |= WINCON0_BPPMODE_24BPP_888; data |= WINCONx_BURSTLEN_16WORD; break; } /* It has no color key control register for window0 */ if (win_no > 0) { u32 keycon0_data = 0, keycon1_data = 0; keycon0_data = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F | WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); keycon1_data = WxKEYCON1_COLVAL(0xffffff); writel(keycon0_data, regs + WxKEYCONy(win_no-1, 0)); writel(keycon1_data, regs + WxKEYCONy(win_no-1, 1)); } writel(data, regs + WINCON(win_no)); writel(0x0, regs + WINxMAP(win_no)); return 0; }
/** * s3c_fb_set_par() - framebuffer request to set new framebuffer state. * @info: The framebuffer to change. * * Framebuffer layer request to set a new mode for the specified framebuffer */ static int s3c_fb_set_par(struct fb_info *info) { struct fb_var_screeninfo *var = &info->var; struct s3c_fb_win *win = info->par; struct s3c_fb *sfb = win->parent; void __iomem *regs = sfb->regs; void __iomem *buf = regs; int win_no = win->index; u32 alpha = 0; u32 data; u32 pagewidth; dev_dbg(sfb->dev, "setting framebuffer parameters\n"); pm_runtime_get_sync(sfb->dev); shadow_protect_win(win, 1); switch (var->bits_per_pixel) { case 32: case 24: case 16: case 12: info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 8: if (win->variant.palette_sz >= 256) info->fix.visual = FB_VISUAL_PSEUDOCOLOR; else info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 1: info->fix.visual = FB_VISUAL_MONO01; break; default: info->fix.visual = FB_VISUAL_PSEUDOCOLOR; break; } info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; /* disable the window whilst we update it */ writel(0, regs + WINCON(win_no)); if (!sfb->output_on) s3c_fb_enable(sfb, 1); /* write the buffer address */ /* start and end registers stride is 8 */ buf = regs + win_no * 8; writel(info->fix.smem_start, buf + sfb->variant.buf_start); data = info->fix.smem_start + info->fix.line_length * var->yres; writel(data, buf + sfb->variant.buf_end); pagewidth = (var->xres * var->bits_per_pixel) >> 3; data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | VIDW_BUF_SIZE_PAGEWIDTH(pagewidth) | VIDW_BUF_SIZE_OFFSET_E(info->fix.line_length - pagewidth) | VIDW_BUF_SIZE_PAGEWIDTH_E(pagewidth); writel(data, regs + sfb->variant.buf_size + (win_no * 4)); /* write 'OSD' registers to control position of framebuffer */ data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0) | VIDOSDxA_TOPLEFT_X_E(0) | VIDOSDxA_TOPLEFT_Y_E(0); writel(data, regs + VIDOSD_A(win_no, sfb->variant)); data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, var->xres - 1)) | VIDOSDxB_BOTRIGHT_Y(var->yres - 1) | VIDOSDxB_BOTRIGHT_X_E(s3c_fb_align_word(var->bits_per_pixel, var->xres - 1)) | VIDOSDxB_BOTRIGHT_Y_E(var->yres - 1); writel(data, regs + VIDOSD_B(win_no, sfb->variant)); data = var->xres * var->yres; alpha = VIDISD14C_ALPHA1_R(0xf) | VIDISD14C_ALPHA1_G(0xf) | VIDISD14C_ALPHA1_B(0xf); vidosd_set_alpha(win, alpha); vidosd_set_size(win, data); /* Enable DMA channel for this window */ if (sfb->variant.has_shadowcon) { data = readl(sfb->regs + SHADOWCON); data |= SHADOWCON_CHx_ENABLE(win_no); writel(data, sfb->regs + SHADOWCON); } data = WINCONx_ENWIN; sfb->enabled |= (1 << win->index); /* note, since we have to round up the bits-per-pixel, we end up * relying on the bitfield information for r/g/b/a to work out * exactly which mode of operation is intended. */ switch (var->bits_p
static int s3c_fb_set_par(struct fb_info *info) { struct fb_var_screeninfo *var = &info->var; struct s3c_fb_win *win = info->par; struct s3c_fb *sfb = win->parent; void __iomem *regs = sfb->regs; void __iomem *buf = regs; int win_no = win->index; u32 alpha = 0; u32 data; u32 pagewidth; int clkdiv; dev_dbg(sfb->dev, "setting framebuffer parameters\n"); pm_runtime_get_sync(sfb->dev); shadow_protect_win(win, 1); switch (var->bits_per_pixel) { case 32: case 24: case 16: case 12: info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 8: if (win->variant.palette_sz >= 256) info->fix.visual = FB_VISUAL_PSEUDOCOLOR; else info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 1: info->fix.visual = FB_VISUAL_MONO01; break; default: info->fix.visual = FB_VISUAL_PSEUDOCOLOR; break; } info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; writel(0, regs + WINCON(win_no)); if (win_no == sfb->pdata->default_win) { clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); data = sfb->pdata->vidcon0; data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); if (clkdiv > 1) data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR; else data &= ~VIDCON0_CLKDIR; if (sfb->variant.is_2443) data |= (1 << 5); writel(data, regs + VIDCON0); s3c_fb_enable(sfb, 1); data = VIDTCON0_VBPD(var->upper_margin - 1) | VIDTCON0_VFPD(var->lower_margin - 1) | VIDTCON0_VSPW(var->vsync_len - 1); writel(data, regs + sfb->variant.vidtcon); data = VIDTCON1_HBPD(var->left_margin - 1) | VIDTCON1_HFPD(var->right_margin - 1) | VIDTCON1_HSPW(var->hsync_len - 1); writel(data, regs + sfb->variant.vidtcon + 4); data = VIDTCON2_LINEVAL(var->yres - 1) | VIDTCON2_HOZVAL(var->xres - 1) | VIDTCON2_LINEVAL_E(var->yres - 1) | VIDTCON2_HOZVAL_E(var->xres - 1); writel(data, regs + sfb->variant.vidtcon + 8); } buf = regs + win_no * 8; writel(info->fix.smem_start, buf + sfb->variant.buf_start); data = info->fix.smem_start + info->fix.line_length * var->yres; writel(data, buf + sfb->variant.buf_end); pagewidth = (var->xres * var->bits_per_pixel) >> 3; data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | VIDW_BUF_SIZE_PAGEWIDTH(pagewidth) | VIDW_BUF_SIZE_OFFSET_E(info->fix.line_length - pagewidth) | VIDW_BUF_SIZE_PAGEWIDTH_E(pagewidth); writel(data, regs + sfb->variant.buf_size + (win_no * 4)); data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0) | VIDOSDxA_TOPLEFT_X_E(0) | VIDOSDxA_TOPLEFT_Y_E(0); writel(data, regs + VIDOSD_A(win_no, sfb->variant)); data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, var->xres - 1)) | VIDOSDxB_BOTRIGHT_Y(var->yres - 1) | VIDOSDxB_BOTRIGHT_X_E(s3c_fb_align_word(var->bits_per_pixel, var->xres - 1)) | VIDOSDxB_BOTRIGHT_Y_E(var->yres - 1); writel(data, regs + VIDOSD_B(win_no, sfb->variant)); data = var->xres * var->yres; alpha = VIDISD14C_ALPHA1_R(0xf) | VIDISD14C_ALPHA1_G(0xf) | VIDISD14C_ALPHA1_B(0xf); vidosd_set_alpha(win, alpha); vidosd_set_size(win, data); if (sfb->variant.has_shadowcon) { data = readl(sfb->regs + SHADOWCON); data |= SHADOWCON_CHx_ENABLE(win_no); writel(data, sfb->regs + SHADOWCON); } data = WINCONx_ENWIN; sfb->enabled |= (1 << win->index); switch (var->bits_per_pixel) { case 1: data |= WINCON0_BPPMODE_1BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_4WORD; break; case 2: data |= WINCON0_BPPMODE_2BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_8WORD; break; case 4: data |= WINCON0_BPPMODE_4BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_8WORD; break; case 8: if (var->transp.length != 0) data |= WINCON1_BPPMODE_8BPP_1232; else data |= WINCON0_BPPMODE_8BPP_PALETTE; data |= WINCONx_BURSTLEN_8WORD; data |= WINCONx_BYTSWP; break; case 16: if (var->transp.length != 0) data |= WINCON1_BPPMODE_16BPP_A1555; else data |= WINCON0_BPPMODE_16BPP_565; data |= WINCONx_HAWSWP; data |= WINCONx_BURSTLEN_16WORD; break; case 24: case 32: if (var->red.length == 6) { if (var->transp.length != 0) data |= WINCON1_BPPMODE_19BPP_A1666; else data |= WINCON1_BPPMODE_18BPP_666; } else if (var->transp.length == 1) data |= WINCON1_BPPMODE_25BPP_A1888 | WINCON1_BLD_PIX; else if ((var->transp.length == 4) || (var->transp.length == 8)) data |= WINCON1_BPPMODE_28BPP_A4888 | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; else data |= WINCON0_BPPMODE_24BPP_888; data |= WINCONx_WSWP; data |= WINCONx_BURSTLEN_16WORD; break; } if (win_no > 0) { u32 keycon0_data = 0, keycon1_data = 0; void __iomem *keycon = regs + sfb->variant.keycon; keycon0_data = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F | WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); keycon1_data = WxKEYCON1_COLVAL(0xffffff); keycon += (win_no - 1) * 8; writel(keycon0_data, keycon + WKEYCON0); writel(keycon1_data, keycon + WKEYCON1); } writel(data, regs + sfb->variant.wincon + (win_no * 4)); writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); if (sfb->variant.has_blendcon) { data = readl(sfb->regs + BLENDCON); data &= ~BLENDCON_NEW_MASK; if (var->transp.length > 4) data |= BLENDCON_NEW_8BIT_ALPHA_VALUE; else data |= BLENDCON_NEW_4BIT_ALPHA_VALUE; writel(data, sfb->regs + BLENDCON); } shadow_protect_win(win, 0); pm_runtime_put_sync(sfb->dev); return 0; }
/* enable each window */ void decon_reg_activate_window(u32 index) { decon_write_mask(WINCON(index), ~0, WINCONx_ENWIN); decon_reg_update_standalone(); }
/** * s3c_fb_set_par() - framebuffer request to set new framebuffer state. * @info: The framebuffer to change. * * Framebuffer layer request to set a new mode for the specified framebuffer */ static int s3c_fb_set_par(struct fb_info *info) { struct fb_var_screeninfo *var = &info->var; struct s3c_fb_win *win = info->par; struct s3c_fb *sfb = win->parent; void __iomem *regs = sfb->regs; void __iomem *buf = regs; int win_no = win->index; u32 alpha = 0; u32 data; u32 pagewidth; int clkdiv; dev_dbg(sfb->dev, "setting framebuffer parameters\n"); shadow_protect_win(win, 1); switch (var->bits_per_pixel) { case 32: case 24: case 16: case 12: info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 8: if (win->variant.palette_sz >= 256) info->fix.visual = FB_VISUAL_PSEUDOCOLOR; else info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 1: info->fix.visual = FB_VISUAL_MONO01; break; default: info->fix.visual = FB_VISUAL_PSEUDOCOLOR; break; } info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; /* disable the window whilst we update it */ writel(0, regs + WINCON(win_no)); /* use platform specified window as the basis for the lcd timings */ if (win_no == sfb->pdata->default_win) { clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); data = sfb->pdata->vidcon0; data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); if (clkdiv > 1) data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR; else data &= ~VIDCON0_CLKDIR; /* 1:1 clock */ /* write the timing data to the panel */ if (sfb->variant.is_2443) data |= (1 << 5); data |= VIDCON0_ENVID | VIDCON0_ENVID_F; writel(data, regs + VIDCON0); data = VIDTCON0_VBPD(var->upper_margin - 1) | VIDTCON0_VFPD(var->lower_margin - 1) | VIDTCON0_VSPW(var->vsync_len - 1); writel(data, regs + sfb->variant.vidtcon); data = VIDTCON1_HBPD(var->left_margin - 1) | VIDTCON1_HFPD(var->right_margin - 1) | VIDTCON1_HSPW(var->hsync_len - 1); /* VIDTCON1 */ writel(data, regs + sfb->variant.vidtcon + 4); data = VIDTCON2_LINEVAL(var->yres - 1) | VIDTCON2_HOZVAL(var->xres - 1); writel(data, regs +sfb->variant.vidtcon + 8 ); } /* write the buffer address */ /* start and end registers stride is 8 */ buf = regs + win_no * 8; writel(info->fix.smem_start, buf + sfb->variant.buf_start); data = info->fix.smem_start + info->fix.line_length * var->yres; writel(data, buf + sfb->variant.buf_end); pagewidth = (var->xres * var->bits_per_pixel) >> 3; data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | VIDW_BUF_SIZE_PAGEWIDTH(pagewidth); writel(data, regs + sfb->variant.buf_size + (win_no * 4)); /* write 'OSD' registers to control position of framebuffer */ data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0); writel(data, regs + VIDOSD_A(win_no, sfb->variant)); data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, var->xres - 1)) | VIDOSDxB_BOTRIGHT_Y(var->yres - 1); writel(data, regs + VIDOSD_B(win_no, sfb->variant)); data = var->xres * var->yres; alpha = VIDISD14C_ALPHA1_R(0xf) | VIDISD14C_ALPHA1_G(0xf) | VIDISD14C_ALPHA1_B(0xf); vidosd_set_alpha(win, alpha); vidosd_set_size(win, data); data = WINCONx_ENWIN; /* note, since we have to round up the bits-per-pixel, we end up * relying on the bitfield information for r/g/b/a to work out * exactly which mode of operation is intended. */ switch (var->bits_per_pixel) { case 1: data |= WINCON0_BPPMODE_1BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_4WORD; break; case 2: data |= WINCON0_BPPMODE_2BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_8WORD; break; case 4: data |= WINCON0_BPPMODE_4BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_8WORD; break; case 8: if (var->transp.length != 0) data |= WINCON1_BPPMODE_8BPP_1232; else data |= WINCON0_BPPMODE_8BPP_PALETTE; data |= WINCONx_BURSTLEN_8WORD; data |= WINCONx_BYTSWP; break; case 16: if (var->transp.length != 0) data |= WINCON1_BPPMODE_16BPP_A1555; else data |= WINCON0_BPPMODE_16BPP_565; data |= WINCONx_HAWSWP; data |= WINCONx_BURSTLEN_16WORD; break; case 24: case 32: if (var->red.length == 6) { if (var->transp.length != 0) data |= WINCON1_BPPMODE_19BPP_A1666; else data |= WINCON1_BPPMODE_18BPP_666; } else if (var->transp.length == 1) data |= WINCON1_BPPMODE_25BPP_A1888 | WINCON1_BLD_PIX; else if (var->transp.length == 4) data |= WINCON1_BPPMODE_28BPP_A4888 | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; else data |= WINCON0_BPPMODE_24BPP_888; data |= WINCONx_WSWP; data |= WINCONx_BURSTLEN_16WORD; break; } /* Enable the colour keying for the window below this one */ if (win_no > 0) { u32 keycon0_data = 0, keycon1_data = 0; void __iomem *keycon = regs + sfb->variant.keycon; keycon0_data = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F | WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); keycon1_data = WxKEYCON1_COLVAL(0xffffff); keycon += (win_no - 1) * 8; writel(keycon0_data, keycon + WKEYCON0); writel(keycon1_data, keycon + WKEYCON1); } writel(data, regs + sfb->variant.wincon + (win_no * 4)); writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); /* Enable DMA channel for this window */ if (sfb->variant.has_shadowcon) { data = readl(sfb->regs + SHADOWCON); data |= SHADOWCON_CHx_ENABLE(win_no); writel(data, sfb->regs + SHADOWCON); } shadow_protect_win(win, 0); return 0; }
/** * s3c_fb_set_par() - framebuffer request to set new framebuffer state. * @info: The framebuffer to change. * * Framebuffer layer request to set a new mode for the specified framebuffer */ static int s3c_fb_set_par(struct fb_info *info) { struct fb_var_screeninfo *var = &info->var; struct s3c_fb_win *win = info->par; struct s3c_fb *sfb = win->parent; void __iomem *regs = sfb->regs; void __iomem *buf = regs; int win_no = win->index; u32 alpha = 0; u32 data; u32 pagewidth; dev_dbg(sfb->dev, "setting framebuffer parameters\n"); pm_runtime_get_sync(sfb->dev); shadow_protect_win(win, 1); switch (var->bits_per_pixel) { case 32: case 24: case 16: case 12: info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 8: if (win->variant.palette_sz >= 256) info->fix.visual = FB_VISUAL_PSEUDOCOLOR; else info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 1: info->fix.visual = FB_VISUAL_MONO01; break; default: info->fix.visual = FB_VISUAL_PSEUDOCOLOR; break; } info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; /* disable the window whilst we update it */ writel(0, regs + WINCON(win_no)); if (!sfb->output_on) s3c_fb_enable(sfb, 1); /* write the buffer address */ /* start and end registers stride is 8 */ buf = regs + win_no * 8; writel(info->fix.smem_start, buf + sfb->variant.buf_start); data = info->fix.smem_start + info->fix.line_length * var->yres; writel(data, buf + sfb->variant.buf_end); pagewidth = (var->xres * var->bits_per_pixel) >> 3; data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | VIDW_BUF_SIZE_PAGEWIDTH(pagewidth) | VIDW_BUF_SIZE_OFFSET_E(info->fix.line_length - pagewidth) | VIDW_BUF_SIZE_PAGEWIDTH_E(pagewidth); writel(data, regs + sfb->variant.buf_size + (win_no * 4)); /* write 'OSD' registers to control position of framebuffer */ data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0) | VIDOSDxA_TOPLEFT_X_E(0) | VIDOSDxA_TOPLEFT_Y_E(0); writel(data, regs + VIDOSD_A(win_no, sfb->variant)); data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, var->xres - 1)) | VIDOSDxB_BOTRIGHT_Y(var->yres - 1) | VIDOSDxB_BOTRIGHT_X_E(s3c_fb_align_word(var->bits_per_pixel, var->xres - 1)) | VIDOSDxB_BOTRIGHT_Y_E(var->yres - 1); writel(data, regs + VIDOSD_B(win_no, sfb->variant)); data = var->xres * var->yres; alpha = VIDISD14C_ALPHA1_R(0xf) | VIDISD14C_ALPHA1_G(0xf) | VIDISD14C_ALPHA1_B(0xf); vidosd_set_alpha(win, alpha); vidosd_set_size(win, data); /* Enable DMA channel for this window */ if (sfb->variant.has_shadowcon) { data = readl(sfb->regs + SHADOWCON); data |= SHADOWCON_CHx_ENABLE(win_no); writel(data, sfb->regs + SHADOWCON); } data = WINCONx_ENWIN; sfb->enabled |= (1 << win->index); /* note, since we have to round up the bits-per-pixel, we end up * relying on the bitfield information for r/g/b/a to work out * exactly which mode of operation is intended. */ switch (var->bits_per_pixel) { case 1: data |= WINCON0_BPPMODE_1BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_4WORD; break; case 2: data |= WINCON0_BPPMODE_2BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_8WORD; break; case 4: data |= WINCON0_BPPMODE_4BPP; data |= WINCONx_BITSWP; data |= WINCONx_BURSTLEN_8WORD; break; case 8: if (var->transp.length != 0) data |= WINCON1_BPPMODE_8BPP_1232; else data |= WINCON0_BPPMODE_8BPP_PALETTE; data |= WINCONx_BURSTLEN_8WORD; data |= WINCONx_BYTSWP; break; case 16: if (var->transp.length != 0) data |= WINCON1_BPPMODE_16BPP_A1555; else data |= WINCON0_BPPMODE_16BPP_565; data |= WINCONx_HAWSWP; data |= WINCONx_BURSTLEN_16WORD; break; case 24: case 32: if (var->red.length == 6) { if (var->transp.length != 0) data |= WINCON1_BPPMODE_19BPP_A1666; else data |= WINCON1_BPPMODE_18BPP_666; } else if (var->transp.length == 1) data |= WINCON1_BPPMODE_25BPP_A1888 | WINCON1_BLD_PIX; else if ((var->transp.length == 4) || (var->transp.length == 8)) data |= WINCON1_BPPMODE_28BPP_A4888 | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; else data |= WINCON0_BPPMODE_24BPP_888; data |= WINCONx_WSWP; data |= WINCONx_BURSTLEN_16WORD; break; } /* Enable the colour keying for the window below this one */ if (win_no > 0) { u32 keycon0_data = 0, keycon1_data = 0; void __iomem *keycon = regs + sfb->variant.keycon; keycon0_data = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F | WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); keycon1_data = WxKEYCON1_COLVAL(0xffffff); keycon += (win_no - 1) * 8; writel(keycon0_data, keycon + WKEYCON0); writel(keycon1_data, keycon + WKEYCON1); } writel(data, regs + sfb->variant.wincon + (win_no * 4)); writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); /* Set alpha value width */ if (sfb->variant.has_blendcon) { data = readl(sfb->regs + BLENDCON); data &= ~BLENDCON_NEW_MASK; if (var->transp.length > 4) data |= BLENDCON_NEW_8BIT_ALPHA_VALUE; else data |= BLENDCON_NEW_4BIT_ALPHA_VALUE; writel(data, sfb->regs + BLENDCON); } shadow_protect_win(win, 0); pm_runtime_put_sync(sfb->dev); return 0; }
static void decon_dump_registers_exynos5430(struct display_driver *pdispdrv) { u32 val; DUMP_DECON_REGISTER(VIDCON0); DUMP_DECON_REGISTER(VIDOUTCON0); DUMP_DECON_REGISTER(WINCON(0)); DUMP_DECON_REGISTER(WINCON(1)); DUMP_DECON_REGISTER(WINCON(2)); DUMP_DECON_REGISTER(WINCON(3)); DUMP_DECON_REGISTER(WINCON(4)); DUMP_DECON_REGISTER(VIDOSD_H(0)); DUMP_DECON_REGISTER(VIDOSD_H(1)); DUMP_DECON_REGISTER(VIDOSD_H(2)); DUMP_DECON_REGISTER(VIDOSD_H(3)); DUMP_DECON_REGISTER(VIDOSD_H(4)); DUMP_DECON_REGISTER(SHADOWCON); DUMP_DECON_REGISTER(VIDOSD_A(0)); DUMP_DECON_REGISTER(VIDOSD_A(1)); DUMP_DECON_REGISTER(VIDOSD_A(2)); DUMP_DECON_REGISTER(VIDOSD_A(3)); DUMP_DECON_REGISTER(VIDOSD_A(4)); DUMP_DECON_REGISTER(VIDOSD_B(0)); DUMP_DECON_REGISTER(VIDOSD_B(1)); DUMP_DECON_REGISTER(VIDOSD_B(2)); DUMP_DECON_REGISTER(VIDOSD_B(3)); DUMP_DECON_REGISTER(VIDOSD_B(4)); DUMP_DECON_REGISTER(VIDOSD_C(0)); DUMP_DECON_REGISTER(VIDOSD_C(1)); DUMP_DECON_REGISTER(VIDOSD_C(2)); DUMP_DECON_REGISTER(VIDOSD_C(3)); DUMP_DECON_REGISTER(VIDOSD_C(4)); DUMP_DECON_REGISTER(VIDOSD_D(0)); DUMP_DECON_REGISTER(VIDOSD_D(1)); DUMP_DECON_REGISTER(VIDOSD_D(2)); DUMP_DECON_REGISTER(VIDOSD_D(3)); DUMP_DECON_REGISTER(VIDOSD_D(4)); DUMP_DECON_REGISTER(VIDOSD_E(0)); DUMP_DECON_REGISTER(VIDOSD_E(1)); DUMP_DECON_REGISTER(VIDOSD_E(2)); DUMP_DECON_REGISTER(VIDOSD_E(3)); DUMP_DECON_REGISTER(VIDOSD_E(4)); DUMP_DECON_REGISTER(VIDW_BUF_START(0)); DUMP_DECON_REGISTER(VIDW_BUF_START(1)); DUMP_DECON_REGISTER(VIDW_BUF_START(2)); DUMP_DECON_REGISTER(VIDW_BUF_START(3)); DUMP_DECON_REGISTER(VIDW_BUF_START(4)); DUMP_DECON_REGISTER(VIDW_BUF_START1(0)); DUMP_DECON_REGISTER(VIDW_BUF_START1(1)); DUMP_DECON_REGISTER(VIDW_BUF_START1(2)); DUMP_DECON_REGISTER(VIDW_BUF_START1(3)); DUMP_DECON_REGISTER(VIDW_BUF_START1(4)); DUMP_DECON_REGISTER(VIDW_BUF_START2(0)); DUMP_DECON_REGISTER(VIDW_BUF_START2(1)); DUMP_DECON_REGISTER(VIDW_BUF_START2(2)); DUMP_DECON_REGISTER(VIDW_BUF_START2(3)); DUMP_DECON_REGISTER(VIDW_BUF_START2(4)); DUMP_DECON_REGISTER(VIDW_BUF_END(0)); DUMP_DECON_REGISTER(VIDW_BUF_END(1)); DUMP_DECON_REGISTER(VIDW_BUF_END(2)); DUMP_DECON_REGISTER(VIDW_BUF_END(3)); DUMP_DECON_REGISTER(VIDW_BUF_END(4)); DUMP_DECON_REGISTER(VIDW_BUF_END1(0)); DUMP_DECON_REGISTER(VIDW_BUF_END1(1)); DUMP_DECON_REGISTER(VIDW_BUF_END1(2)); DUMP_DECON_REGISTER(VIDW_BUF_END1(3)); DUMP_DECON_REGISTER(VIDW_BUF_END1(4)); DUMP_DECON_REGISTER(VIDW_BUF_END2(0)); DUMP_DECON_REGISTER(VIDW_BUF_END2(1)); DUMP_DECON_REGISTER(VIDW_BUF_END2(2)); DUMP_DECON_REGISTER(VIDW_BUF_END2(3)); DUMP_DECON_REGISTER(VIDW_BUF_END2(4)); DUMP_DECON_REGISTER(VIDW_BUF_SIZE(0)); DUMP_DECON_REGISTER(VIDW_BUF_SIZE(1)); DUMP_DECON_REGISTER(VIDW_BUF_SIZE(2)); DUMP_DECON_REGISTER(VIDW_BUF_SIZE(3)); DUMP_DECON_REGISTER(VIDW_BUF_SIZE(4)); DUMP_DECON_REGISTER(LOCAL_SIZE(0)); DUMP_DECON_REGISTER(LOCAL_SIZE(1)); DUMP_DECON_REGISTER(LOCAL_SIZE(2)); DUMP_DECON_REGISTER(VIDINTCON0); DUMP_DECON_REGISTER(VIDINTCON1); DUMP_DECON_REGISTER(VIDINTCON2); DUMP_DECON_REGISTER(VIDINTCON3); DUMP_DECON_REGISTER(WKEYCON); DUMP_DECON_REGISTER(WxKEYALPHA(1)); DUMP_DECON_REGISTER(WxKEYALPHA(2)); DUMP_DECON_REGISTER(WxKEYALPHA(3)); DUMP_DECON_REGISTER(WxKEYALPHA(4)); DUMP_DECON_REGISTER(WINxMAP(0)); DUMP_DECON_REGISTER(WINxMAP(1)); DUMP_DECON_REGISTER(WINxMAP(2)); DUMP_DECON_REGISTER(WINxMAP(3)); DUMP_DECON_REGISTER(WINxMAP(4)); DUMP_DECON_REGISTER(QOSLUT07_00); DUMP_DECON_REGISTER(QOSLUT15_08); DUMP_DECON_REGISTER(QOSCTRL); DUMP_DECON_REGISTER(BLENDCON); DUMP_DECON_REGISTER(SHD_VIDW_BUF_START(0)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_START(1)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_START(2)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_START(3)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_START(4)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_END(0)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_END(1)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_END(2)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_END(3)); DUMP_DECON_REGISTER(SHD_VIDW_BUF_END(4)); DUMP_DECON_REGISTER(FRAMEFIFO_REG0); DUMP_DECON_REGISTER(FRAMEFIFO_REG7); DUMP_DECON_REGISTER(FRAMEFIFO_REG8); DUMP_DECON_REGISTER(FRAMEFIFO_STATUS); DUMP_DECON_REGISTER(DECON_MODECON); DUMP_DECON_REGISTER(DECON_CMU); DUMP_DECON_REGISTER(DECON_UPDATE); DUMP_DECON_REGISTER(DECON_CRFMID); DUMP_DECON_REGISTER(DECON_RRFRMID); DUMP_DECON_REGISTER(VIDCON1); DUMP_DECON_REGISTER(VIDCON2); DUMP_DECON_REGISTER(VIDCON3); DUMP_DECON_REGISTER(VIDCON4); #if defined(CONFIG_SOC_EXYNOS5433) DUMP_DECON_REGISTER(VIDTCON00); DUMP_DECON_REGISTER(VIDTCON01); DUMP_DECON_REGISTER(VIDTCON10); DUMP_DECON_REGISTER(VIDTCON11); #else DUMP_DECON_REGISTER(VIDTCON0); DUMP_DECON_REGISTER(VIDTCON1); #endif DUMP_DECON_REGISTER(VIDTCON2); DUMP_DECON_REGISTER(FRAME_SIZE); DUMP_DECON_REGISTER(LINECNT_OP_THRESHOLD); DUMP_DECON_REGISTER(TRIGCON); DUMP_DECON_REGISTER(CRCCTRL); DUMP_DECON_REGISTER(ENHANCER_CTRL); DUMP_DECON_REGISTER(WINCON_SHADOW(0)); DUMP_DECON_REGISTER(WINCON_SHADOW(1)); DUMP_DECON_REGISTER(WINCON_SHADOW(2)); DUMP_DECON_REGISTER(WINCON_SHADOW(3)); DUMP_DECON_REGISTER(WINCON_SHADOW(4)); DUMP_DECON_REGISTER(DECON_UPDATE_SHADOW); #if defined(CONFIG_SOC_EXYNOS5433) DUMP_DECON_REGISTER(VIDOSD_A_SHADOW(0)); DUMP_DECON_REGISTER(VIDOSD_A_SHADOW(1)); DUMP_DECON_REGISTER(VIDOSD_A_SHADOW(2)); DUMP_DECON_REGISTER(VIDOSD_A_SHADOW(3)); DUMP_DECON_REGISTER(VIDOSD_A_SHADOW(4)); DUMP_DECON_REGISTER(VIDOSD_B_SHADOW(0)); DUMP_DECON_REGISTER(VIDOSD_B_SHADOW(1)); DUMP_DECON_REGISTER(VIDOSD_B_SHADOW(2)); DUMP_DECON_REGISTER(VIDOSD_B_SHADOW(3)); DUMP_DECON_REGISTER(VIDOSD_B_SHADOW(4)); DUMP_DECON_REGISTER(VIDOSD_C_SHADOW(0)); DUMP_DECON_REGISTER(VIDOSD_C_SHADOW(1)); DUMP_DECON_REGISTER(VIDOSD_C_SHADOW(2)); DUMP_DECON_REGISTER(VIDOSD_C_SHADOW(3)); DUMP_DECON_REGISTER(VIDOSD_C_SHADOW(4)); DUMP_DECON_REGISTER(VIDOSD_D_SHADOW(0)); DUMP_DECON_REGISTER(VIDOSD_D_SHADOW(1)); DUMP_DECON_REGISTER(VIDOSD_D_SHADOW(2)); DUMP_DECON_REGISTER(VIDOSD_D_SHADOW(3)); DUMP_DECON_REGISTER(VIDOSD_D_SHADOW(4)); DUMP_DECON_REGISTER(VIDOSD_E_SHADOW(0)); DUMP_DECON_REGISTER(VIDOSD_E_SHADOW(1)); DUMP_DECON_REGISTER(VIDOSD_E_SHADOW(2)); DUMP_DECON_REGISTER(VIDOSD_E_SHADOW(3)); DUMP_DECON_REGISTER(VIDOSD_E_SHADOW(4)); DUMP_DECON_REGISTER(LOCAL_SIZE_SHADOW(0)); DUMP_DECON_REGISTER(LOCAL_SIZE_SHADOW(1)); DUMP_DECON_REGISTER(LOCAL_SIZE_SHADOW(2)); DUMP_DECON_REGISTER(VIDTCON00_SHADOW); DUMP_DECON_REGISTER(VIDTCON01_SHADOW); DUMP_DECON_REGISTER(VIDTCON10_SHADOW); DUMP_DECON_REGISTER(VIDTCON11_SHADOW); DUMP_DECON_REGISTER(VIDTCON2_SHADOW); #endif }