msm: mdss: refactor mdss color formats

Add missing color formats and reorganize color formats to have better
code reuse and make it easy to add new formats if required.

Change-Id: Ic7c6bb6f35a9c282d9ef99bd5e1d18b0b8033971
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 776bf8b..17281d5 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -40,6 +40,11 @@
 #define MAX_DOWNSCALE_RATIO	4
 #define MAX_UPSCALE_RATIO	20
 
+#define C3_ALPHA	3	/* alpha */
+#define C2_R_Cr		2	/* R/Cr */
+#define C1_B_Cb		1	/* B/Cb */
+#define C0_G_Y		0	/* G/luma */
+
 #ifdef MDSS_MDP_DEBUG_REG
 static inline void mdss_mdp_reg_write(u32 addr, u32 val)
 {
@@ -173,23 +178,8 @@
 	u8 bpp;
 	u8 alpha_enable;	/*  source has alpha */
 
-	/*
-	 * number of bits for source component,
-	 * 0 = 1 bit, 1 = 2 bits, 2 = 6 bits, 3 = 8 bits
-	 */
-	u8 a_bit;	/* component 3, alpha */
-	u8 r_bit;	/* component 2, R_Cr */
-	u8 b_bit;	/* component 1, B_Cb */
-	u8 g_bit;	/* component 0, G_lumz */
-
-	/*
-	 * unpack pattern
-	 * A = C3, R = C2, B = C1, G = C0
-	 */
-	u8 element3;
-	u8 element2;
-	u8 element1;
-	u8 element0;
+	u8 bits[MAX_PLANES];
+	u8 element[MAX_PLANES];
 };
 
 struct mdss_mdp_plane_sizes {
diff --git a/drivers/video/msm/mdss/mdss_mdp_formats.h b/drivers/video/msm/mdss/mdss_mdp_formats.h
index 07eefc1..d8ae531 100644
--- a/drivers/video/msm/mdss/mdss_mdp_formats.h
+++ b/drivers/video/msm/mdss/mdss_mdp_formats.h
@@ -18,311 +18,147 @@
 
 #include "mdss_mdp.h"
 
-#define C3_ALPHA	3	/* alpha */
-#define C2_R_Cr		2	/* R/Cr */
-#define C1_B_Cb		1	/* B/Cb */
-#define C0_G_Y		0	/* G/luma */
+	/*
+	 * number of bits for source component,
+	 * 0 = 1 bit, 1 = 2 bits, 2 = 6 bits, 3 = 8 bits
+	 */
+enum {
+	COLOR_4BIT,
+	COLOR_5BIT,
+	COLOR_6BIT,
+	COLOR_8BIT,
+};
 
-static struct mdss_mdp_format_params mdss_mdp_format_map[MDP_IMGTYPE_LIMIT] = {
-	[MDP_RGB_565] = {
-		.format = MDP_RGB_565,
+#define FMT_RGB_565(fmt, e0, e1, e2)				\
+	{							\
+		.format = (fmt),				\
+		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,	\
+		.unpack_tight = 1,				\
+		.unpack_align_msb = 0,				\
+		.alpha_enable = 0,				\
+		.unpack_count = 3,				\
+		.bpp = 2,					\
+		.element = { (e0), (e1), (e2) },		\
+		.bits = {					\
+			[C2_R_Cr] = COLOR_5BIT,			\
+			[C0_G_Y] = COLOR_6BIT,			\
+			[C1_B_Cb] = COLOR_5BIT,			\
+		},						\
+	}
+
+#define FMT_RGB_888(fmt, e0, e1, e2)				\
+	{							\
+		.format = (fmt),				\
+		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,	\
+		.unpack_tight = 1,				\
+		.unpack_align_msb = 0,				\
+		.alpha_enable = 0,				\
+		.unpack_count = 3,				\
+		.bpp = 3,					\
+		.element = { (e0), (e1), (e2) },		\
+		.bits = {					\
+			[C2_R_Cr] = COLOR_8BIT,			\
+			[C0_G_Y] = COLOR_8BIT,			\
+			[C1_B_Cb] = COLOR_8BIT,			\
+		},						\
+	}
+
+#define FMT_RGB_8888(fmt, alpha_en, e0, e1, e2, e3)		\
+	{							\
+		.format = (fmt),				\
+		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,	\
+		.unpack_tight = 1,				\
+		.unpack_align_msb = 0,				\
+		.alpha_enable = (alpha_en),			\
+		.unpack_count = 4,				\
+		.bpp = 4,					\
+		.element = { (e0), (e1), (e2), (e3) },		\
+		.bits = {					\
+			[C3_ALPHA] = COLOR_8BIT,		\
+			[C2_R_Cr] = COLOR_8BIT,			\
+			[C0_G_Y] = COLOR_8BIT,			\
+			[C1_B_Cb] = COLOR_8BIT,			\
+		},						\
+	}
+
+#define FMT_YUV_COMMON(fmt)					\
+		.format = (fmt),				\
+		.is_yuv = 1,					\
+		.bits = {					\
+			[C2_R_Cr] = COLOR_8BIT,			\
+			[C0_G_Y] = COLOR_8BIT,			\
+			[C1_B_Cb] = COLOR_8BIT,			\
+		},						\
+		.alpha_enable = 0,				\
+		.unpack_tight = 1,				\
+		.unpack_align_msb = 0
+
+#define FMT_YUV_PSEUDO(fmt, samp, e0, e1)			\
+	{							\
+		FMT_YUV_COMMON(fmt),				\
+		.fetch_planes = MDSS_MDP_PLANE_PSEUDO_PLANAR,	\
+		.chroma_sample = samp,				\
+		.unpack_count = 2,				\
+		.bpp = 2,					\
+		.element = { (e0), (e1) },			\
+	}
+
+#define FMT_YUV_PLANR(fmt, samp, e0, e1)			\
+	{							\
+		FMT_YUV_COMMON(fmt),				\
+		.fetch_planes = MDSS_MDP_PLANE_PLANAR,		\
+		.chroma_sample = samp,				\
+		.element = { (e0), (e1) }			\
+	}
+
+static struct mdss_mdp_format_params mdss_mdp_format_map[] = {
+	FMT_RGB_565(MDP_RGB_565, C1_B_Cb, C0_G_Y, C2_R_Cr),
+	FMT_RGB_565(MDP_BGR_565, C2_R_Cr, C0_G_Y, C1_B_Cb),
+	FMT_RGB_888(MDP_RGB_888, C2_R_Cr, C0_G_Y, C1_B_Cb),
+	FMT_RGB_888(MDP_BGR_888, C1_B_Cb, C0_G_Y, C2_R_Cr),
+
+	FMT_RGB_8888(MDP_XRGB_8888, 0, C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb),
+	FMT_RGB_8888(MDP_ARGB_8888, 1, C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb),
+	FMT_RGB_8888(MDP_RGBA_8888, 1, C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA),
+	FMT_RGB_8888(MDP_RGBX_8888, 0, C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA),
+	FMT_RGB_8888(MDP_BGRA_8888, 1, C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA),
+
+	FMT_YUV_PSEUDO(MDP_Y_CRCB_H1V1, MDSS_MDP_CHROMA_RGB, C2_R_Cr, C1_B_Cb),
+	FMT_YUV_PSEUDO(MDP_Y_CBCR_H1V1, MDSS_MDP_CHROMA_RGB, C1_B_Cb, C2_R_Cr),
+	FMT_YUV_PSEUDO(MDP_Y_CRCB_H2V1, MDSS_MDP_CHROMA_H2V1, C2_R_Cr, C1_B_Cb),
+	FMT_YUV_PSEUDO(MDP_Y_CBCR_H2V1, MDSS_MDP_CHROMA_H2V1, C1_B_Cb, C2_R_Cr),
+	FMT_YUV_PSEUDO(MDP_Y_CRCB_H1V2, MDSS_MDP_CHROMA_H1V2, C2_R_Cr, C1_B_Cb),
+	FMT_YUV_PSEUDO(MDP_Y_CBCR_H1V2, MDSS_MDP_CHROMA_H1V2, C1_B_Cb, C2_R_Cr),
+	FMT_YUV_PSEUDO(MDP_Y_CRCB_H2V2, MDSS_MDP_CHROMA_420, C2_R_Cr, C1_B_Cb),
+	FMT_YUV_PSEUDO(MDP_Y_CBCR_H2V2, MDSS_MDP_CHROMA_420, C1_B_Cb, C2_R_Cr),
+
+	FMT_YUV_PLANR(MDP_Y_CR_CB_H2V2, MDSS_MDP_CHROMA_420, C2_R_Cr, C1_B_Cb),
+	FMT_YUV_PLANR(MDP_Y_CB_CR_H2V2, MDSS_MDP_CHROMA_420, C1_B_Cb, C2_R_Cr),
+	FMT_YUV_PLANR(MDP_Y_CR_CB_GH2V2, MDSS_MDP_CHROMA_420, C2_R_Cr, C1_B_Cb),
+
+	{
+		FMT_YUV_COMMON(MDP_YCBCR_H1V1),
 		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
-		.a_bit = 0,
-		.r_bit = 1,	/* R, 5 bits */
-		.b_bit = 1,	/* B, 5 bits */
-		.g_bit = 2,	/* G, 6 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 2,
-		.element2 = C2_R_Cr,
-		.element1 = C0_G_Y,
-		.element0 = C1_B_Cb,
-		.bpp = 1,	/* 2 bpp */
-	},
-	[MDP_BGR_565] = {
-		.format = MDP_BGR_565,
-		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
-		.a_bit = 0,
-		.r_bit = 1,	/* R, 5 bits */
-		.b_bit = 1,	/* B, 5 bits */
-		.g_bit = 2,	/* G, 6 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 2,
-		.element2 = C1_B_Cb,
-		.element1 = C0_G_Y,
-		.element0 = C2_R_Cr,
-		.bpp = 1,	/* 2 bpp */
-	},
-	[MDP_RGB_888] = {
-		.format = MDP_RGB_888,
-		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 2,
-		.element2 = C1_B_Cb,
-		.element1 = C0_G_Y,
-		.element0 = C2_R_Cr,
-		.bpp = 2,	/* 3 bpp */
-	},
-	[MDP_XRGB_8888] = {
-		.format = MDP_XRGB_8888,
-		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
-		.a_bit = 3,	/* alpha, 4 bits */
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
+		.chroma_sample = MDSS_MDP_CHROMA_RGB,
 		.unpack_count = 3,
-		.element3 = C1_B_Cb,
-		.element2 = C0_G_Y,
-		.element1 = C2_R_Cr,
-		.element0 = C3_ALPHA,
-		.bpp = 3,	/* 4 bpp */
+		.bpp = 3,
+		.element = { C2_R_Cr, C1_B_Cb, C0_G_Y },
 	},
-	[MDP_ARGB_8888] = {
-		.format = MDP_ARGB_8888,
+	{
+		FMT_YUV_COMMON(MDP_YCRCB_H1V1),
 		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
-		.a_bit = 3,	/* alpha, 4 bits */
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 1,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
+		.chroma_sample = MDSS_MDP_CHROMA_RGB,
 		.unpack_count = 3,
-		.element3 = C1_B_Cb,
-		.element2 = C0_G_Y,
-		.element1 = C2_R_Cr,
-		.element0 = C3_ALPHA,
-		.bpp = 3,	/* 4 bpp */
+		.bpp = 3,
+		.element = { C1_B_Cb, C2_R_Cr, C0_G_Y },
 	},
-	[MDP_RGBA_8888] = {
-		.format = MDP_RGBA_8888,
-		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
-		.a_bit = 3,	/* alpha, 4 bits */
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 1,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 3,
-		.element3 = C3_ALPHA,
-		.element2 = C1_B_Cb,
-		.element1 = C0_G_Y,
-		.element0 = C2_R_Cr,
-		.bpp = 3,	/* 4 bpp */
-	},
-	[MDP_RGBX_8888] = {
-		.format = MDP_RGBX_8888,
-		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
-		.a_bit = 3,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 3,
-		.element3 = C3_ALPHA,
-		.element2 = C1_B_Cb,
-		.element1 = C0_G_Y,
-		.element0 = C2_R_Cr,
-		.bpp = 3,	/* 4 bpp */
-	},
-	[MDP_BGRA_8888] = {
-		.format = MDP_BGRA_8888,
-		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
-		.a_bit = 3,	/* alpha, 4 bits */
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 1,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 3,
-		.element3 = C3_ALPHA,
-		.element2 = C2_R_Cr,
-		.element1 = C0_G_Y,
-		.element0 = C1_B_Cb,
-		.bpp = 3,	/* 4 bpp */
-	},
-	[MDP_YCRYCB_H2V1] = {
-		.format = MDP_YCRYCB_H2V1,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
+	{
+		FMT_YUV_COMMON(MDP_YCRYCB_H2V1),
 		.fetch_planes = MDSS_MDP_PLANE_INTERLEAVED,
 		.chroma_sample = MDSS_MDP_CHROMA_H2V1,
-		.unpack_count = 3,
-		.element3 = C0_G_Y,
-		.element2 = C2_R_Cr,
-		.element1 = C0_G_Y,
-		.element0 = C1_B_Cb,
-	},
-	[MDP_Y_CRCB_H2V1] = {
-		.format = MDP_Y_CRCB_H2V1,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PSEUDO_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_H2V1,
-		.element1 = C1_B_Cb,
-		.element0 = C2_R_Cr,
-	},
-	[MDP_Y_CBCR_H2V1] = {
-		.format = MDP_Y_CBCR_H2V1,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PSEUDO_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_H2V1,
-		.element1 = C2_R_Cr,
-		.element0 = C1_B_Cb,
-	},
-	[MDP_Y_CRCB_H1V2] = {
-		.format = MDP_Y_CRCB_H1V2,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PSEUDO_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_H1V2,
-		.element1 = C1_B_Cb,
-		.element0 = C2_R_Cr,
-	},
-	[MDP_Y_CBCR_H1V2] = {
-		.format = MDP_Y_CBCR_H1V2,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PSEUDO_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_H1V2,
-		.element1 = C2_R_Cr,
-		.element0 = C1_B_Cb,
-	},
-	[MDP_Y_CRCB_H2V2] = {
-		.format = MDP_Y_CRCB_H2V2,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PSEUDO_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_420,
-		.element1 = C1_B_Cb,
-		.element0 = C2_R_Cr,
-	},
-	[MDP_Y_CBCR_H2V2] = {
-		.format = MDP_Y_CBCR_H2V2,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PSEUDO_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_420,
-		.element1 = C2_R_Cr,
-		.element0 = C1_B_Cb,
-	},
-	[MDP_Y_CR_CB_H2V2] = {
-		.format = MDP_Y_CR_CB_H2V2,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_420,
-	},
-	[MDP_Y_CB_CR_H2V2] = {
-		.format = MDP_Y_CB_CR_H2V2,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_420,
-	},
-	[MDP_Y_CR_CB_GH2V2] = {
-		.format = MDP_Y_CR_CB_GH2V2,
-		.is_yuv = 1,
-		.a_bit = 0,
-		.r_bit = 3,	/* R, 8 bits */
-		.b_bit = 3,	/* B, 8 bits */
-		.g_bit = 3,	/* G, 8 bits */
-		.alpha_enable = 0,
-		.unpack_tight = 1,
-		.unpack_align_msb = 0,
-		.unpack_count = 1,	/* 2 */
-		.bpp = 1,	/* 2 bpp */
-		.fetch_planes = MDSS_MDP_PLANE_PLANAR,
-		.chroma_sample = MDSS_MDP_CHROMA_420,
+		.unpack_count = 4,
+		.bpp = 2,
+		.element = { C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y },
 	},
 };
 #endif
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index af422b7..8b4434e 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -145,20 +145,24 @@
 
 	dst_format = (chroma_samp << 23) |
 		     (fmt->fetch_planes << 19) |
-		     (fmt->unpack_align_msb << 18) |
-		     (fmt->unpack_tight << 17) |
-		     (fmt->unpack_count << 12) |
-		     (fmt->bpp << 9) |
-		     (fmt->alpha_enable << 8) |
-		     (fmt->a_bit << 6) |
-		     (fmt->r_bit << 4) |
-		     (fmt->b_bit << 2) |
-		     (fmt->g_bit << 0);
+		     (fmt->bits[C3_ALPHA] << 6) |
+		     (fmt->bits[C2_R_Cr] << 4) |
+		     (fmt->bits[C1_B_Cb] << 2) |
+		     (fmt->bits[C0_G_Y] << 0);
 
-	pattern = (fmt->element3 << 24) |
-		  (fmt->element2 << 15) |
-		  (fmt->element1 << 8) |
-		  (fmt->element0 << 0);
+	if (fmt->alpha_enable)
+		dst_format |= BIT(8); /* DSTC3_EN */
+
+	if (fmt->fetch_planes != MDSS_MDP_PLANE_PLANAR) {
+		pattern = (fmt->element[3] << 24) | (fmt->element[2] << 15) |
+			(fmt->element[1] << 8) | (fmt->element[0] << 0);
+		dst_format |= (fmt->unpack_align_msb << 18) |
+			      (fmt->unpack_tight << 17) |
+			      ((fmt->unpack_count - 1) << 12) |
+			      ((fmt->bpp - 1) << 9);
+	} else {
+		pattern = 0;
+	}
 
 	ystride0 = (ctx->dst_planes.ystride[0]) |
 		   (ctx->dst_planes.ystride[1] << 16);
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 9a8260f..2e45760 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -363,6 +363,12 @@
 	}
 
 	chroma_sample = pipe->src_fmt->chroma_sample;
+	if (pipe->flags & MDP_SOURCE_ROTATED_90) {
+		if (chroma_sample == MDSS_MDP_CHROMA_H1V2)
+			chroma_sample = MDSS_MDP_CHROMA_H2V1;
+		else if (chroma_sample == MDSS_MDP_CHROMA_H2V1)
+			chroma_sample = MDSS_MDP_CHROMA_H1V2;
+	}
 
 	if ((pipe->src.h != pipe->dst.h) ||
 	    (chroma_sample == MDSS_MDP_CHROMA_420) ||
@@ -523,7 +529,7 @@
 static int mdss_mdp_format_setup(struct mdss_mdp_pipe *pipe)
 {
 	struct mdss_mdp_format_params *fmt;
-	u32 rot90, opmode, chroma_samp;
+	u32 opmode, chroma_samp, unpack, src_format;
 
 	fmt = pipe->src_fmt;
 
@@ -536,8 +542,6 @@
 	pr_debug("pnum=%d format=%d opmode=%x\n", pipe->num, fmt->format,
 			opmode);
 
-	rot90 = !!(pipe->flags & MDP_ROT_90);
-
 	chroma_samp = fmt->chroma_sample;
 	if (pipe->flags & MDP_SOURCE_ROTATED_90) {
 		if (chroma_samp == MDSS_MDP_CHROMA_H2V1)
@@ -546,26 +550,34 @@
 			chroma_samp = MDSS_MDP_CHROMA_H2V1;
 	}
 
-	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_FORMAT,
-			    (chroma_samp << 23) |
-			    (fmt->fetch_planes << 19) |
-			    (fmt->unpack_align_msb << 18) |
-			    (fmt->unpack_tight << 17) |
-			    (fmt->unpack_count << 12) |
-			    (rot90 << 11) |
-			    (fmt->bpp << 9) |
-			    (fmt->alpha_enable << 8) |
-			    (fmt->a_bit << 6) |
-			    (fmt->r_bit << 4) |
-			    (fmt->b_bit << 2) |
-			    (fmt->g_bit << 0));
+	src_format = (chroma_samp << 23) |
+		     (fmt->fetch_planes << 19) |
+		     (fmt->bits[C3_ALPHA] << 6) |
+		     (fmt->bits[C2_R_Cr] << 4) |
+		     (fmt->bits[C1_B_Cb] << 2) |
+		     (fmt->bits[C0_G_Y] << 0);
 
-	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN,
-			    (fmt->element3 << 24) |
-			    (fmt->element2 << 16) |
-			    (fmt->element1 << 8) |
-			    (fmt->element0 << 0));
+	if (pipe->flags & MDP_ROT_90)
+		src_format |= BIT(11); /* ROT90 */
 
+	if (fmt->alpha_enable &&
+			fmt->fetch_planes != MDSS_MDP_PLANE_INTERLEAVED)
+		src_format |= BIT(8); /* SRCC3_EN */
+
+	if (fmt->fetch_planes != MDSS_MDP_PLANE_PLANAR) {
+		unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
+			(fmt->element[1] << 8) | (fmt->element[0] << 0);
+
+		src_format |= ((fmt->unpack_count - 1) << 12) |
+			  (fmt->unpack_tight << 17) |
+			  (fmt->unpack_align_msb << 18) |
+			  ((fmt->bpp - 1) << 9);
+	} else {
+		unpack = 0;
+	}
+
+	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_FORMAT, src_format);
+	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN, unpack);
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_OP_MODE, opmode);
 
 	return 0;
@@ -595,17 +607,23 @@
 static int mdss_mdp_src_addr_setup(struct mdss_mdp_pipe *pipe,
 				   struct mdss_mdp_data *data)
 {
-	int ret;
+	int is_rot = pipe->mixer->rotator_mode;
+	int ret = 0;
 
 	pr_debug("pnum=%d\n", pipe->num);
 
-	if (pipe->type != MDSS_MDP_PIPE_TYPE_DMA)
+	if (!is_rot)
 		data->bwc_enabled = pipe->bwc_mode;
 
 	ret = mdss_mdp_data_check(data, &pipe->src_planes);
 	if (ret)
 		return ret;
 
+	/* planar format expects YCbCr, swap chroma planes if YCrCb */
+	if (!is_rot && (pipe->src_fmt->fetch_planes == MDSS_MDP_PLANE_PLANAR) &&
+	    (pipe->src_fmt->element[0] == C2_R_Cr))
+		swap(data->p[1].addr, data->p[2].addr);
+
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC0_ADDR, data->p[0].addr);
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC1_ADDR, data->p[1].addr);
 	mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC2_ADDR, data->p[2].addr);
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index f6b4fce..7f61a14 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -164,14 +164,16 @@
 
 struct mdss_mdp_format_params *mdss_mdp_get_format_params(u32 format)
 {
-	struct mdss_mdp_format_params *fmt = NULL;
 	if (format < MDP_IMGTYPE_LIMIT) {
-		fmt = &mdss_mdp_format_map[format];
-		if (fmt->format != format)
-			fmt = NULL;
+		struct mdss_mdp_format_params *fmt = NULL;
+		int i;
+		for (i = 0; i < ARRAY_SIZE(mdss_mdp_format_map); i++) {
+			fmt = &mdss_mdp_format_map[i];
+			if (format == fmt->format)
+				return fmt;
+		}
 	}
-
-	return fmt;
+	return NULL;
 }
 
 int mdss_mdp_get_plane_sizes(u32 format, u32 w, u32 h,
@@ -193,7 +195,7 @@
 	memset(ps, 0, sizeof(struct mdss_mdp_plane_sizes));
 
 	if (fmt->fetch_planes == MDSS_MDP_PLANE_INTERLEAVED) {
-		u32 bpp = fmt->bpp + 1;
+		u32 bpp = fmt->bpp;
 		ps->num_planes = 1;
 		ps->plane_size[0] = w * h * bpp;
 		ps->ystride[0] = w * bpp;
@@ -206,16 +208,14 @@
 		vert = vmap[fmt->chroma_sample];
 
 		if (format == MDP_Y_CR_CB_GH2V2) {
-			ps->plane_size[0] = ALIGN(w, 16) * h;
-			ps->plane_size[1] = ALIGN(w / horiz, 16) * (h / vert);
 			ps->ystride[0] = ALIGN(w, 16);
 			ps->ystride[1] = ALIGN(w / horiz, 16);
 		} else {
-			ps->plane_size[0] = w * h;
-			ps->plane_size[1] = (w / horiz) * (h / vert);
 			ps->ystride[0] = w;
 			ps->ystride[1] = (w / horiz);
 		}
+		ps->plane_size[0] = ps->ystride[0] * h;
+		ps->plane_size[1] = ps->ystride[1] * (h / vert);
 
 		if (fmt->fetch_planes == MDSS_MDP_PLANE_PSEUDO_PLANAR) {
 			ps->num_planes = 2;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 2519a6e..4dd6907 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -105,6 +105,7 @@
 	MDP_YCRCB_H1V1,   /* YCrCb interleave */
 	MDP_YCBCR_H1V1,   /* YCbCr interleave */
 	MDP_BGR_565,      /* BGR 565 planer */
+	MDP_BGR_888,      /* BGR 888 */
 	MDP_IMGTYPE_LIMIT,
 	MDP_RGB_BORDERFILL,	/* border fill pipe */
 	MDP_FB_FORMAT = MDP_IMGTYPE2_START,    /* framebuffer format */