diff options
Diffstat (limited to 'drivers/video/s3c-fb.c')
-rw-r--r-- | drivers/video/s3c-fb.c | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 5e9c6302433b..43680e545427 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -358,9 +358,16 @@ static int s3c_fb_set_par(struct fb_info *info) writel(data, regs + VIDOSD_B(win_no)); data = var->xres * var->yres; + + u32 osdc_data = 0; + + 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(0, regs + VIDOSD_C(win_no)); + writel(osdc_data, regs + VIDOSD_C(win_no)); } else writel(data, regs + VIDOSD_C(win_no)); @@ -409,8 +416,12 @@ static int s3c_fb_set_par(struct fb_info *info) data |= WINCON1_BPPMODE_19BPP_A1666; else data |= WINCON1_BPPMODE_18BPP_666; - } else if (var->transp.length != 0) - data |= WINCON1_BPPMODE_25BPP_A1888; + } 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; @@ -418,6 +429,20 @@ static int s3c_fb_set_par(struct fb_info *info) 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)); @@ -700,9 +725,12 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) */ static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) { - fb_dealloc_cmap(&win->fbinfo->cmap); - unregister_framebuffer(win->fbinfo); - s3c_fb_free_memory(sfb, win); + if (win->fbinfo) { + unregister_framebuffer(win->fbinfo); + fb_dealloc_cmap(&win->fbinfo->cmap); + s3c_fb_free_memory(sfb, win); + framebuffer_release(win->fbinfo); + } } /** @@ -753,7 +781,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, ret = s3c_fb_alloc_memory(sfb, win); if (ret) { dev_err(sfb->dev, "failed to allocate display memory\n"); - goto err_framebuffer; + return ret; } /* setup the r/b/g positions for the window's palette */ @@ -776,7 +804,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, ret = s3c_fb_check_var(&fbinfo->var, fbinfo); if (ret < 0) { dev_err(sfb->dev, "check_var failed on initial video params\n"); - goto err_alloc_mem; + return ret; } /* create initial colour map */ @@ -796,20 +824,13 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, ret = register_framebuffer(fbinfo); if (ret < 0) { dev_err(sfb->dev, "failed to register framebuffer\n"); - goto err_alloc_mem; + return ret; } *res = win; dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); return 0; - -err_alloc_mem: - s3c_fb_free_memory(sfb, win); - -err_framebuffer: - unregister_framebuffer(fbinfo); - return ret; } /** @@ -947,7 +968,8 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) int win; for (win = 0; win <= S3C_FB_MAX_WIN; win++) - s3c_fb_release_win(sfb, sfb->windows[win]); + if (sfb->windows[win]) + s3c_fb_release_win(sfb, sfb->windows[win]); iounmap(sfb->regs); @@ -985,11 +1007,20 @@ static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state) static int s3c_fb_resume(struct platform_device *pdev) { struct s3c_fb *sfb = platform_get_drvdata(pdev); + struct s3c_fb_platdata *pd = sfb->pdata; struct s3c_fb_win *win; int win_no; clk_enable(sfb->bus_clk); + /* setup registers */ + writel(pd->vidcon1, sfb->regs + VIDCON1); + + /* zero all windows before we do anything */ + for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) + s3c_fb_clear_win(sfb, win_no); + + /* restore framebuffers */ for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) { win = sfb->windows[win_no]; if (!win) |