From e67fafadde2b908ee5c4309fc3bd3cd5a110b0e0 Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Thu, 2 Apr 2009 16:58:39 +0530
Subject: [PATCH 1/1] DSS2: Added support for the YUV VRFB rotation.

Modified disc_setup_plane to get the rotation_type from
driver and set the row_inc value accordingly.

Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
 arch/arm/plat-omap/include/mach/display.h |    6 ++
 drivers/video/omap2/dss/dispc.c           |   77 ++++++++++++++++++++++++++++-
 drivers/video/omap2/dss/dss.h             |    1 +
 drivers/video/omap2/dss/manager.c         |    2 +
 4 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
index eaacf3e..d48b5d2 100644
--- a/arch/arm/plat-omap/include/mach/display.h
+++ b/arch/arm/plat-omap/include/mach/display.h
@@ -338,6 +338,11 @@ enum omap_dss_overlay_managers {
 
 struct omap_overlay_manager;
 
+enum omap_dss_rotation_type {
+	OMAP_DSS_ROT_DMA = 0,
+	OMAP_DSS_ROT_VRFB = 1,
+};
+
 struct omap_overlay_info {
 	bool enabled;
 
@@ -348,6 +353,7 @@ struct omap_overlay_info {
 	u16 height;
 	enum omap_color_mode color_mode;
 	u8 rotation;
+	enum omap_dss_rotation_type rotation_type;
 	bool mirror;
 
 	u16 pos_x;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 711086f..597186b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1133,7 +1133,70 @@ static int pixinc(int pixels, u8 ps)
 		BUG();
 }
 
-static void calc_rotation_offset(u8 rotation, bool mirror,
+static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
+		u16 screen_width,
+		u16 width, u16 height,
+		enum omap_color_mode color_mode, bool fieldmode,
+		unsigned *offset0, unsigned *offset1,
+		u16 *row_inc, u16 *pix_inc)
+{
+	u8 ps;
+
+	switch (color_mode) {
+	case OMAP_DSS_COLOR_RGB16:
+	case OMAP_DSS_COLOR_ARGB16:
+		ps = 2;
+		break;
+
+	case OMAP_DSS_COLOR_RGB24P:
+		ps = 3;
+		break;
+
+	case OMAP_DSS_COLOR_RGB24U:
+	case OMAP_DSS_COLOR_ARGB32:
+	case OMAP_DSS_COLOR_RGBA32:
+	case OMAP_DSS_COLOR_RGBX32:
+	case OMAP_DSS_COLOR_YUV2:
+	case OMAP_DSS_COLOR_UYVY:
+		ps = 4;
+		break;
+
+	default:
+		BUG();
+		return;
+	}
+
+	DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width,
+			width, height);
+	switch (rotation + mirror * 4) {
+	case 0:
+	case 2:
+		/* If the pixel format is YUV or UYVY divide the width
+		 * of the image by 2  for 0 degree and
+		 */
+		if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+			color_mode == OMAP_DSS_COLOR_UYVY)
+			width = width >> 1;
+	case 1:
+	case 3:
+		*offset0 = 0;
+		if (fieldmode)
+			*offset1 = screen_width * ps;
+		else
+			*offset1 = 0;
+
+		*row_inc = pixinc(1 + (screen_width - width) +
+				(fieldmode ? screen_width : 0),
+				ps);
+		*pix_inc = pixinc(1, ps);
+		break;
+	default: {
+		BUG();
+	}
+	}
+}
+
+static void calc_dma_rotation_offset(u8 rotation, bool mirror,
 		u16 screen_width,
 		u16 width, u16 height,
 		enum omap_color_mode color_mode, bool fieldmode,
@@ -1296,6 +1359,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
 		u16 out_width, u16 out_height,
 		enum omap_color_mode color_mode,
 		bool ilace,
+		enum omap_dss_rotation_type rotation_type,
 		u8 rotation, int mirror,
 		u8 global_alpha)
 {
@@ -1363,7 +1427,13 @@ static int _dispc_setup_plane(enum omap_plane plane,
 		fieldmode = 1;
 
 	//printk("%s %d\n", __func__, __LINE__);
-	calc_rotation_offset(rotation, mirror,
+	if (rotation_type == OMAP_DSS_ROT_DMA)
+		calc_dma_rotation_offset(rotation, mirror,
+			screen_width, width, height, color_mode,
+			fieldmode,
+			&offset0, &offset1, &row_inc, &pix_inc);
+	else
+		calc_vrfb_rotation_offset(rotation, mirror,
 			screen_width, width, height, color_mode,
 			fieldmode,
 			&offset0, &offset1, &row_inc, &pix_inc);
@@ -2747,6 +2817,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
 		       u16 out_width, u16 out_height,
 		       enum omap_color_mode color_mode,
 		       bool ilace,
+		       enum omap_dss_rotation_type rotation_type,
 		       u8 rotation, bool mirror,
 		       u8 global_alpha)
 {
@@ -2778,6 +2849,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
 			   width, height,
 			   out_width, out_height,
 			   color_mode, ilace,
+			   rotation_type,
 			   rotation, mirror, global_alpha);
 
 	enable_clocks(0);
@@ -2991,6 +3063,7 @@ void dispc_setup_partial_planes(struct omap_display *display,
 				pw, ph,
 				pow, poh,
 				pi->color_mode, 0,
+				pi->rotation_type,
 				pi->rotation, // XXX rotation probably wrong
 				pi->mirror,
 				g_alpha);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 4576821..53ccac2 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -268,6 +268,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
 		      u16 out_width, u16 out_height,
 		      enum omap_color_mode color_mode,
 		      bool ilace,
+		      enum omap_dss_rotation_type rotation_type,
 		      u8 rotation, bool mirror,
 		      u8 global_alpha);
 
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e829156..ff29bc5 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -195,6 +195,7 @@ static ssize_t manager_color_key_enabled_store(struct omap_overlay_manager *mgr,
 	return size;
 }
 
+
 struct manager_attribute {
 	struct attribute attr;
 	ssize_t (*show)(struct omap_overlay_manager *, char *);
@@ -397,6 +398,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 				outh,
 				ovl->info.color_mode,
 				ilace,
+				ovl->info.rotation_type,
 				ovl->info.rotation,
 				ovl->info.mirror,
 				ovl->info.global_alpha);
-- 
1.6.0.3

