aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/s3c-fb.c
diff options
context:
space:
mode:
authorPawel Osciak <p.osciak@samsung.com>2010-08-10 21:02:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-11 11:59:10 -0400
commit067b226b9e8e20463e0937344c93101ac8d8d2b1 (patch)
tree518d26953ac86514594307976e5a670212c52c6e /drivers/video/s3c-fb.c
parenteb42b0441bc7fd29066bb7c38ebabe3d0e3ff202 (diff)
s3c-fb: add support for display panning
Supports all bpp modes. The PRTCON register is used to disable in-hardware updates of registers that store start and end addresses of framebuffer memory. This prevents display corruption in case we do not make it before VSYNC with updating them atomically. With this feature there is no need to wait for a VSYNC interrupt before each such update. Signed-off-by: Pawel Osciak <p.osciak@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Cc: InKi Dae <inki.dae@samsung.com> Cc: Ben Dooks <ben-linux@fluff.org> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/s3c-fb.c')
-rw-r--r--drivers/video/s3c-fb.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 5f931b4933bd..de427d928f48 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -71,6 +71,7 @@ struct s3c_fb;
71 * @buf_end: Offset of buffer end registers. 71 * @buf_end: Offset of buffer end registers.
72 * @osd: The base for the OSD registers. 72 * @osd: The base for the OSD registers.
73 * @palette: Address of palette memory, or 0 if none. 73 * @palette: Address of palette memory, or 0 if none.
74 * @has_prtcon: Set if has PRTCON register.
74 */ 75 */
75struct s3c_fb_variant { 76struct s3c_fb_variant {
76 unsigned int is_2443:1; 77 unsigned int is_2443:1;
@@ -85,6 +86,8 @@ struct s3c_fb_variant {
85 unsigned short osd; 86 unsigned short osd;
86 unsigned short osd_stride; 87 unsigned short osd_stride;
87 unsigned short palette[S3C_FB_MAX_WIN]; 88 unsigned short palette[S3C_FB_MAX_WIN];
89
90 unsigned int has_prtcon:1;
88}; 91};
89 92
90/** 93/**
@@ -379,6 +382,9 @@ static int s3c_fb_set_par(struct fb_info *info)
379 382
380 info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; 383 info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
381 384
385 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
386 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
387
382 /* disable the window whilst we update it */ 388 /* disable the window whilst we update it */
383 writel(0, regs + WINCON(win_no)); 389 writel(0, regs + WINCON(win_no));
384 390
@@ -735,6 +741,63 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
735 return 0; 741 return 0;
736} 742}
737 743
744/**
745 * s3c_fb_pan_display() - Pan the display.
746 *
747 * Note that the offsets can be written to the device at any time, as their
748 * values are latched at each vsync automatically. This also means that only
749 * the last call to this function will have any effect on next vsync, but
750 * there is no need to sleep waiting for it to prevent tearing.
751 *
752 * @var: The screen information to verify.
753 * @info: The framebuffer device.
754 */
755static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
756 struct fb_info *info)
757{
758 struct s3c_fb_win *win = info->par;
759 struct s3c_fb *sfb = win->parent;
760 void __iomem *buf = sfb->regs + win->index * 8;
761 unsigned int start_boff, end_boff;
762
763 /* Offset in bytes to the start of the displayed area */
764 start_boff = var->yoffset * info->fix.line_length;
765 /* X offset depends on the current bpp */
766 if (info->var.bits_per_pixel >= 8) {
767 start_boff += var->xoffset * (info->var.bits_per_pixel >> 3);
768 } else {
769 switch (info->var.bits_per_pixel) {
770 case 4:
771 start_boff += var->xoffset >> 1;
772 break;
773 case 2:
774 start_boff += var->xoffset >> 2;
775 break;
776 case 1:
777 start_boff += var->xoffset >> 3;
778 break;
779 default:
780 dev_err(sfb->dev, "invalid bpp\n");
781 return -EINVAL;
782 }
783 }
784 /* Offset in bytes to the end of the displayed area */
785 end_boff = start_boff + var->yres * info->fix.line_length;
786
787 /* Temporarily turn off per-vsync update from shadow registers until
788 * both start and end addresses are updated to prevent corruption */
789 if (sfb->variant.has_prtcon)
790 writel(PRTCON_PROTECT, sfb->regs + PRTCON);
791
792 writel(info->fix.smem_start + start_boff, buf + sfb->variant.buf_start);
793 writel(info->fix.smem_start + end_boff, buf + sfb->variant.buf_end);
794
795 if (sfb->variant.has_prtcon)
796 writel(0, sfb->regs + PRTCON);
797
798 return 0;
799}
800
738static struct fb_ops s3c_fb_ops = { 801static struct fb_ops s3c_fb_ops = {
739 .owner = THIS_MODULE, 802 .owner = THIS_MODULE,
740 .fb_check_var = s3c_fb_check_var, 803 .fb_check_var = s3c_fb_check_var,
@@ -744,6 +807,7 @@ static struct fb_ops s3c_fb_ops = {
744 .fb_fillrect = cfb_fillrect, 807 .fb_fillrect = cfb_fillrect,
745 .fb_copyarea = cfb_copyarea, 808 .fb_copyarea = cfb_copyarea,
746 .fb_imageblit = cfb_imageblit, 809 .fb_imageblit = cfb_imageblit,
810 .fb_pan_display = s3c_fb_pan_display,
747}; 811};
748 812
749/** 813/**
@@ -1243,6 +1307,8 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx __devinitdata = {
1243 [3] = 0x320, 1307 [3] = 0x320,
1244 [4] = 0x340, 1308 [4] = 0x340,
1245 }, 1309 },
1310
1311 .has_prtcon = 1,
1246 }, 1312 },
1247 .win[0] = &s3c_fb_data_64xx_wins[0], 1313 .win[0] = &s3c_fb_data_64xx_wins[0],
1248 .win[1] = &s3c_fb_data_64xx_wins[1], 1314 .win[1] = &s3c_fb_data_64xx_wins[1],
@@ -1271,6 +1337,8 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 __devinitdata = {
1271 [3] = 0x3000, 1337 [3] = 0x3000,
1272 [4] = 0x3400, 1338 [4] = 0x3400,
1273 }, 1339 },
1340
1341 .has_prtcon = 1,
1274 }, 1342 },
1275 .win[0] = &s3c_fb_data_64xx_wins[0], 1343 .win[0] = &s3c_fb_data_64xx_wins[0],
1276 .win[1] = &s3c_fb_data_64xx_wins[1], 1344 .win[1] = &s3c_fb_data_64xx_wins[1],