325 lines
8.7 KiB
Diff
325 lines
8.7 KiB
Diff
From 77e848eeba461e9b55b09d39fd0d640caea13e19 Mon Sep 17 00:00:00 2001
|
|
From: Hardik Shah <hardik.shah@ti.com>
|
|
Date: Thu, 9 Apr 2009 12:09:44 +0530
|
|
Subject: [PATCH] DSS2: VRFB rotation and mirroring implemented.
|
|
|
|
DSS2 modified to accept the rotation_type input
|
|
to get the dma or VRFB rotation.
|
|
|
|
DSS2: VRFB: Changed to pass DSS mode to vrfb_setup instead of Bpp.
|
|
|
|
VRFB size registers requires the width to be halved when the
|
|
mode is YUV or UYVY. So modifed to pass the mode to omap_vrfb_setup
|
|
function.
|
|
|
|
Code added by Tim Yamin for few bug fixes
|
|
|
|
Signed-off-by: Tim Yamin <plasm@roo.me.uk>
|
|
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
|
|
---
|
|
arch/arm/plat-omap/include/mach/display.h | 6 ++
|
|
arch/arm/plat-omap/include/mach/vrfb.h | 3 +-
|
|
arch/arm/plat-omap/vrfb.c | 36 +++++++++-
|
|
drivers/video/omap2/dss/dispc.c | 109 +++++++++++++++++++++++++++--
|
|
drivers/video/omap2/dss/dss.h | 1 +
|
|
drivers/video/omap2/dss/manager.c | 1 +
|
|
6 files changed, 144 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
|
|
index 6b702c7..b0a6272 100644
|
|
--- a/arch/arm/plat-omap/include/mach/display.h
|
|
+++ b/arch/arm/plat-omap/include/mach/display.h
|
|
@@ -341,6 +341,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;
|
|
|
|
@@ -351,6 +356,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/arch/arm/plat-omap/include/mach/vrfb.h b/arch/arm/plat-omap/include/mach/vrfb.h
|
|
index 2047862..12c7fab 100644
|
|
--- a/arch/arm/plat-omap/include/mach/vrfb.h
|
|
+++ b/arch/arm/plat-omap/include/mach/vrfb.h
|
|
@@ -24,6 +24,7 @@
|
|
#ifndef __VRFB_H
|
|
#define __VRFB_H
|
|
|
|
+#include <mach/display.h>
|
|
#define OMAP_VRFB_LINE_LEN 2048
|
|
|
|
struct vrfb
|
|
@@ -42,6 +43,6 @@ extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
|
|
u8 bytespp);
|
|
extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
|
|
u16 width, u16 height,
|
|
- u8 bytespp);
|
|
+ enum omap_color_mode color_mode);
|
|
|
|
#endif /* __VRFB_H */
|
|
diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c
|
|
index d68065f..2f08f6d 100644
|
|
--- a/arch/arm/plat-omap/vrfb.c
|
|
+++ b/arch/arm/plat-omap/vrfb.c
|
|
@@ -5,7 +5,6 @@
|
|
|
|
#include <mach/io.h>
|
|
#include <mach/vrfb.h>
|
|
-
|
|
/*#define DEBUG*/
|
|
|
|
#ifdef DEBUG
|
|
@@ -50,19 +49,48 @@ EXPORT_SYMBOL(omap_vrfb_adjust_size);
|
|
|
|
void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
|
|
u16 width, u16 height,
|
|
- u8 bytespp)
|
|
+ enum omap_color_mode color_mode)
|
|
{
|
|
unsigned pixel_size_exp;
|
|
u16 vrfb_width;
|
|
u16 vrfb_height;
|
|
u8 ctx = vrfb->context;
|
|
+ u8 bytespp;
|
|
|
|
DBG("omapfb_set_vrfb(%d, %lx, %dx%d, %d)\n", ctx, paddr,
|
|
width, height, bytespp);
|
|
|
|
- if (bytespp == 4)
|
|
+ switch (color_mode) {
|
|
+ case OMAP_DSS_COLOR_RGB16:
|
|
+ case OMAP_DSS_COLOR_ARGB16:
|
|
+ bytespp = 2;
|
|
+ break;
|
|
+
|
|
+ case OMAP_DSS_COLOR_RGB24P:
|
|
+ bytespp = 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:
|
|
+ bytespp = 4;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ BUG();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
|
|
+ color_mode == OMAP_DSS_COLOR_UYVY)
|
|
+ width >>= 1;
|
|
+
|
|
+ if (bytespp == 4) {
|
|
pixel_size_exp = 2;
|
|
- else if (bytespp == 2)
|
|
+ } else if (bytespp == 2)
|
|
pixel_size_exp = 1;
|
|
else
|
|
BUG();
|
|
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
|
|
index 16c68b8..23a8155 100644
|
|
--- a/drivers/video/omap2/dss/dispc.c
|
|
+++ b/drivers/video/omap2/dss/dispc.c
|
|
@@ -1106,7 +1106,7 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
|
|
case 0: vidrot = 0; break;
|
|
case 1: vidrot = 1; break;
|
|
case 2: vidrot = 2; break;
|
|
- case 3: vidrot = 1; break;
|
|
+ case 3: vidrot = 3; break;
|
|
}
|
|
}
|
|
|
|
@@ -1134,7 +1134,92 @@ static s32 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,
|
|
+ s32 *row_inc, s32 *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 and 180 degree rotation.
|
|
+ */
|
|
+ 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;
|
|
+
|
|
+ case 4:
|
|
+ case 6:
|
|
+ /* If the pixel format is YUV or UYVY divide the width
|
|
+ * of the image by 2 for 0 degree and 180 degree
|
|
+ */
|
|
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
|
|
+ color_mode == OMAP_DSS_COLOR_UYVY)
|
|
+ width = width >> 1;
|
|
+ case 5:
|
|
+ case 7:
|
|
+ *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,
|
|
@@ -1357,6 +1442,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)
|
|
{
|
|
const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
|
|
@@ -1463,10 +1549,16 @@ static int _dispc_setup_plane(enum omap_plane plane,
|
|
return -EINVAL;
|
|
}
|
|
|
|
- calc_rotation_offset(rotation, mirror,
|
|
- screen_width, width, frame_height, color_mode,
|
|
- fieldmode,
|
|
- &offset0, &offset1, &row_inc, &pix_inc);
|
|
+ if (rotation_type == OMAP_DSS_ROT_DMA)
|
|
+ calc_dma_rotation_offset(rotation, mirror,
|
|
+ screen_width, width, frame_height, color_mode,
|
|
+ fieldmode,
|
|
+ &offset0, &offset1, &row_inc, &pix_inc);
|
|
+ else
|
|
+ calc_vrfb_rotation_offset(rotation, mirror,
|
|
+ screen_width, width, frame_height, color_mode,
|
|
+ fieldmode,
|
|
+ &offset0, &offset1, &row_inc, &pix_inc);
|
|
|
|
DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
|
|
offset0, offset1, row_inc, pix_inc);
|
|
@@ -2889,6 +2981,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)
|
|
{
|
|
int r = 0;
|
|
@@ -2909,6 +3002,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);
|
|
|
|
enable_clocks(0);
|
|
@@ -3122,7 +3216,8 @@ void dispc_setup_partial_planes(struct omap_display *display,
|
|
pw, ph,
|
|
pow, poh,
|
|
pi->color_mode, 0,
|
|
- pi->rotation, // XXX rotation probably wrong
|
|
+ pi->rotation_type,
|
|
+ pi->rotation,
|
|
pi->mirror);
|
|
|
|
dispc_enable_plane(ovl->id, 1);
|
|
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
|
|
index d0917a8..584dce6 100644
|
|
--- a/drivers/video/omap2/dss/dss.h
|
|
+++ b/drivers/video/omap2/dss/dss.h
|
|
@@ -272,6 +272,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);
|
|
|
|
void dispc_go(enum omap_channel channel);
|
|
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
|
|
index b0fee80..8ca0bbb 100644
|
|
--- a/drivers/video/omap2/dss/manager.c
|
|
+++ b/drivers/video/omap2/dss/manager.c
|
|
@@ -395,6 +395,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);
|
|
|
|
--
|
|
1.5.6.5
|
|
|