[PATCH 3/7] [ARM] s3c-fb: Added support for alpha blending.

Pawel Osciak p.osciak at samsung.com
Fri Sep 11 14:04:55 EDT 2009


Reviewed-by: Marek Szyprowski <m.szyprowski at samsung.com>
Reviewed-by: Kyungmin Park <kyungmin.park at samsung.com>
Signed-off-by: Pawel Osciak <p.osciak at samsung.com>

---
 arch/arm/mach-s3c6400/include/mach/regs-fb.h |    6 ++
 arch/arm/plat-s3c/include/plat/regs-fb.h     |    7 +++
 arch/arm/plat-s3c/include/plat/s3c-fb.h      |   27 +++++++++
 drivers/video/s3c-fb.c                       |   75 ++++++++++++++++++++++++++
 4 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s3c6400/include/mach/regs-fb.h b/arch/arm/mach-s3c6400/include/mach/regs-fb.h
index 6339426..84facc9 100644
--- a/arch/arm/mach-s3c6400/include/mach/regs-fb.h
+++ b/arch/arm/mach-s3c6400/include/mach/regs-fb.h
@@ -24,6 +24,9 @@
  * override them at a later date.
 */
 
+#ifndef __ASM_ARCH_REGS_FB_H
+#define __ASM_ARCH_REGS_FB_H __FILE__
+
 #include <plat/regs-fb.h>
 
 #define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
@@ -262,3 +265,6 @@ static inline void s3c_fb_init_palette(unsigned int window,
  * 1110		-none-	 -none-	  -none-   -none-    -none-
  * 1111		-none-	 -none-   -none-   -none-    -none-
 */
+
+#endif /* __ASM_ARCH_REGS_FB_H */
+
diff --git a/arch/arm/plat-s3c/include/plat/regs-fb.h b/arch/arm/plat-s3c/include/plat/regs-fb.h
index 4c024ca..26b878b 100644
--- a/arch/arm/plat-s3c/include/plat/regs-fb.h
+++ b/arch/arm/plat-s3c/include/plat/regs-fb.h
@@ -28,6 +28,9 @@
  * ensure all the localised SoC support is included as necessary.
 */
 
+#ifndef __PLAT_S3C_REGS_FB_H
+#define __PLAT_S3C_REGS_FB_H	__FILE__
+
 /* VIDCON0 */
 
 #define VIDCON0					(0x00)
@@ -179,6 +182,8 @@
 #define WINCONx_BURSTLEN_16WORD			(0x0 << 9)
 #define WINCONx_BURSTLEN_8WORD			(0x1 << 9)
 #define WINCONx_BURSTLEN_4WORD			(0x2 << 9)
+#define WINCONx_BLD_PIX				(1 << 6)
+#define WINCONx_ALPHA_SEL			(1 << 1)
 
 #define WINCONx_ENWIN				(1 << 0)
 #define WINCON0_BPPMODE_MASK			(0xf << 2)
@@ -369,3 +374,5 @@
 #define WPALCON_W0PAL_16BPP_A555		(0x5 << 0)
 #define WPALCON_W0PAL_16BPP_565			(0x6 << 0)
 
+#endif /* __PLAT_S3C_REGS_FB_H */
+
diff --git a/arch/arm/plat-s3c/include/plat/s3c-fb.h b/arch/arm/plat-s3c/include/plat/s3c-fb.h
index b08f9ad..080524d 100644
--- a/arch/arm/plat-s3c/include/plat/s3c-fb.h
+++ b/arch/arm/plat-s3c/include/plat/s3c-fb.h
@@ -21,6 +21,16 @@ struct s3c_fb_color {
 	__u32 b : 8;
 } __attribute__((__packed__));
 
+struct s3c_fb_alpha {
+	__u32 reserved : 8;
+	__u32 r0 : 4;
+	__u32 g0 : 4;
+	__u32 b0 : 4;
+	__u32 r1 : 4;
+	__u32 g1 : 4;
+	__u32 b1 : 4;
+} __attribute__((__packed__));
+
 typedef enum s3c_fb_color_key_mode {
 	S3CFB_COLORKEY_MODE_BG = 0,
 	S3CFB_COLORKEY_MODE_FG = 1
@@ -32,6 +42,17 @@ typedef enum s3c_fb_source {
 	S3CFB_SOURCE_LOCAL_YCbCr = 2
 } s3c_fb_source_t;
 
+typedef enum s3c_fb_alpha_mode {
+	/* Use alpha value from each pixel */
+	S3CFB_ALPHA_PIXEL_VALUE,
+	/* Use global alpha (0 or 1) value chosen by alpha bit of the pixel */
+	S3CFB_ALPHA_PIXEL_SWITCH,
+	/* Blend all pixels with global alpha0 value */
+	S3CFB_ALPHA_PLANE_0,
+	/* Blend all pixels with global alpha1 value */
+	S3CFB_ALPHA_PLANE_1
+} s3c_fb_alpha_mode_t;
+
 #ifndef FBIO_WAITFORVSYNC
 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
 #endif
@@ -50,5 +71,11 @@ typedef enum s3c_fb_source {
 
 /* Param: s3c_fb_source */
 #define S3CFB_IOCTL_SET_SOURCE		_IO(S3CFB_IOCTL_MAGIC, 5)
+
+/* Param: s3c_fb_alpha_mode */
+#define S3CFB_IOCTL_SET_ALPHA_MODE	_IO(S3CFB_IOCTL_MAGIC, 6)
+
+#define S3CFB_IOCTL_SET_WINDOW_ALPHA	_IOW(S3CFB_IOCTL_MAGIC, 7,\
+					struct s3c_fb_alpha)
 #endif /* __LINUX_S3C_FB_H__ */
 
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 28622c0..54ed018 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -997,6 +997,67 @@ static int s3c_fb_set_source(struct s3c_fb_win *win, s3c_fb_source_t source)
 	return 0;
 }
 
+static int s3c_fb_set_alpha_mode(struct s3c_fb_win *win,
+				 s3c_fb_alpha_mode_t mode)
+{
+	struct s3c_fb *sfb = win->parent;
+	int wincon_reg;
+
+	if (win->index == 0) {
+		dev_err(sfb->dev,
+			"Alpha mode for window %d is not supported.\n",
+			win->index);
+		return -EINVAL;
+	}
+
+	wincon_reg = readl(sfb->regs + WINCONx(win->index));
+	wincon_reg &= ~(WINCONx_BLD_PIX | WINCONx_ALPHA_SEL);
+
+	switch (mode) {
+	case S3CFB_ALPHA_PIXEL_VALUE:
+		/* Use alpha value of each pixel */
+		wincon_reg |= WINCONx_BLD_PIX | WINCONx_ALPHA_SEL;
+		break;
+	case S3CFB_ALPHA_PIXEL_SWITCH:
+		/* Use global alpha chosen by the alpha bit of each pixel */
+		wincon_reg |= WINCONx_BLD_PIX;
+		break;
+	case S3CFB_ALPHA_PLANE_0:
+		/* Use global alpha0 for every pixel */
+		wincon_reg &= ~WINCONx_BLD_PIX;
+		break;
+	case S3CFB_ALPHA_PLANE_1:
+		/* Use global alpha1 for every pixel */
+		wincon_reg &= ~WINCONx_BLD_PIX;
+		wincon_reg |= WINCONx_ALPHA_SEL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	writel(wincon_reg, sfb->regs + WINCONx(win->index));
+
+	return 0;
+}
+
+static int s3c_fb_set_win_alpha(struct s3c_fb_win *win,
+				struct s3c_fb_alpha *alpha)
+{
+	struct s3c_fb *sfb = win->parent;
+	u32 vidosdc_reg = 0;
+
+	if (win->index == 0) {
+		dev_err(sfb->dev, "Alpha cannot be set for window %d\n.",
+			win->index);
+	}
+
+	vidosdc_reg = alpha->r0 << 20 | alpha->g0 << 16 | alpha->b0 << 12
+		    | alpha->r1 << 8  | alpha->g1 << 4  | alpha->b1;
+	writel(vidosdc_reg, sfb->regs + VIDOSD_C(win->index));
+
+	return 0;
+}
+
 static int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			unsigned long arg)
 {
@@ -1039,6 +1100,20 @@ static int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd,
 
 	case S3CFB_IOCTL_SET_SOURCE:
 		return s3c_fb_set_source(win, arg);
+
+	case S3CFB_IOCTL_SET_ALPHA_MODE:
+		return s3c_fb_set_alpha_mode(win, arg);
+
+	case S3CFB_IOCTL_SET_WINDOW_ALPHA: {
+		struct s3c_fb_alpha alpha_arg;
+		ret = copy_from_user(&alpha_arg, (void __user *)arg,
+				     sizeof(struct s3c_fb_alpha));
+		if (ret)
+			return ret;
+
+		return s3c_fb_set_win_alpha(win, &alpha_arg);
+		}
+
 	default:
 		return -ENOTTY;
 	}
-- 
1.6.4.2.253.g0b1fac



More information about the linux-arm-kernel mailing list