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); pm_runtime_get_sync(sfb->dev); wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4)); switch (blank_mode) { case FB_BLANK_POWERDOWN: wincon &= ~WINCONx_ENWIN; sfb->enabled &= ~(1 << index); case FB_BLANK_NORMAL: shadow_protect_win(win, 1); writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), sfb->regs + sfb->variant.winmap + (index * 4)); shadow_protect_win(win, 0); break; case FB_BLANK_UNBLANK: shadow_protect_win(win, 1); writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4)); shadow_protect_win(win, 0); wincon |= WINCONx_ENWIN; sfb->enabled |= (1 << index); break; case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND: default: pm_runtime_put_sync(sfb->dev); return 1; } shadow_protect_win(win, 1); writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4)); shadow_protect_win(win, 0); if (index == sfb->pdata->default_win) { shadow_protect_win(win, 1); s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); shadow_protect_win(win, 0); } pm_runtime_put_sync(sfb->dev); return 0; }
/** * 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; u32 output_on = sfb->output_on; dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); pm_runtime_get_sync(sfb->dev); wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4)); 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) */ shadow_protect_win(win, 1); writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), sfb->regs + sfb->variant.winmap + (index * 4)); shadow_protect_win(win, 0); break; case FB_BLANK_UNBLANK: shadow_protect_win(win, 1); writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4)); shadow_protect_win(win, 0); wincon |= WINCONx_ENWIN; sfb->enabled |= (1 << index); break; case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND: default: pm_runtime_put_sync(sfb->dev); return 1; } shadow_protect_win(win, 1); writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4)); /* 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. */ s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); shadow_protect_win(win, 0); pm_runtime_put_sync(sfb->dev); return output_on == sfb->output_on; }
/** * 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; }
/** * 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; }