summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAri Hirvonen <ahirvonen@nvidia.com>2011-03-02 02:06:27 +0200
committerRohan Somvanshi <rsomvanshi@nvidia.com>2011-05-27 19:52:32 -0700
commit60c73b63e651413fb8fba2c03b32c21843e8de22 (patch)
tree489d69cd9785ef8f40317ae1cd057c1cb2a4126f
parentb5d5cd3e4e7af0915d2013f578f285244d7e5acd (diff)
video: tegra: add display inversion support
Change-Id: I6ec62abdaf3a8ec2e59e2a533b36b280d69538e1 Signed-off-by: Ari Hirvonen <ahirvonen@nvidia.com> Reviewed-on: http://git-master/r/33037 Reviewed-by: Michael I Gold <gold@nvidia.com> Tested-by: Michael I Gold <gold@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h4
-rw-r--r--drivers/video/tegra/dc/dc.c27
-rw-r--r--drivers/video/tegra/dc/dc_reg.h4
-rw-r--r--drivers/video/tegra/fb.c4
-rw-r--r--include/video/tegrafb.h10
5 files changed, 39 insertions, 10 deletions
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index d6b953597b84..25cf8021215a 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -296,7 +296,9 @@ struct tegra_dc_win {
#define TEGRA_WIN_FLAG_ENABLED (1 << 0)
#define TEGRA_WIN_FLAG_BLEND_PREMULT (1 << 1)
#define TEGRA_WIN_FLAG_BLEND_COVERAGE (1 << 2)
-#define TEGRA_WIN_FLAG_TILED (1 << 3)
+#define TEGRA_WIN_FLAG_INVERT_H (1 << 3)
+#define TEGRA_WIN_FLAG_INVERT_V (1 << 4)
+#define TEGRA_WIN_FLAG_TILED (1 << 5)
#define TEGRA_WIN_BLEND_FLAGS_MASK \
(TEGRA_WIN_FLAG_BLEND_PREMULT | TEGRA_WIN_FLAG_BLEND_COVERAGE)
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 3f91005b6575..2fdc8c58ad1f 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -503,6 +503,10 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
struct tegra_dc_win *win = windows[i];
unsigned h_dda;
unsigned v_dda;
+ unsigned h_offset;
+ unsigned v_offset;
+ bool invert_h = (win->flags & TEGRA_WIN_FLAG_INVERT_H) != 0;
+ bool invert_v = (win->flags & TEGRA_WIN_FLAG_INVERT_V) != 0;
bool yuvp = tegra_dc_is_yuv_planar(win->fmt);
if (win->z != dc->blend.z[win->idx]) {
@@ -572,6 +576,20 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
DC_WIN_LINE_STRIDE);
}
+ h_offset = win->x;
+ if (invert_h) {
+ h_offset += win->w - 1;
+ }
+ h_offset *= tegra_dc_fmt_bpp(win->fmt) / 8;
+
+ v_offset = win->y;
+ if (invert_v) {
+ v_offset += win->h - 1;
+ }
+
+ tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
+ tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
+
if (win->flags & TEGRA_WIN_FLAG_TILED)
tegra_dc_writel(dc,
DC_WIN_BUFFER_ADDR_MODE_TILE |
@@ -583,10 +601,6 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV,
DC_WIN_BUFFER_ADDR_MODE);
- tegra_dc_writel(dc, win->x * tegra_dc_fmt_bpp(win->fmt) / 8,
- DC_WINBUF_ADDR_H_OFFSET);
- tegra_dc_writel(dc, win->y, DC_WINBUF_ADDR_V_OFFSET);
-
val = WIN_ENABLE;
if (yuvp)
val |= CSC_ENABLE;
@@ -598,6 +612,11 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
if (win->h != win->out_h)
val |= V_FILTER_ENABLE;
+ if (invert_h)
+ val |= H_DIRECTION_DECREMENT;
+ if (invert_v)
+ val |= V_DIRECTION_DECREMENT;
+
tegra_dc_writel(dc, val, DC_WIN_WIN_OPTIONS);
win->dirty = no_vsync ? 0 : 1;
diff --git a/drivers/video/tegra/dc/dc_reg.h b/drivers/video/tegra/dc/dc_reg.h
index 29f98c1c4da7..11bce9a4e3ea 100644
--- a/drivers/video/tegra/dc/dc_reg.h
+++ b/drivers/video/tegra/dc/dc_reg.h
@@ -362,9 +362,9 @@
#define DC_WIN_V_FILTER_P(x) (0x619 + (x))
#define DC_WIN_WIN_OPTIONS 0x700
#define H_DIRECTION_INCREMENT (0 << 0)
-#define H_DIRECTION_DECREMENTT (1 << 0)
+#define H_DIRECTION_DECREMENT (1 << 0)
#define V_DIRECTION_INCREMENT (0 << 2)
-#define V_DIRECTION_DECREMENTT (1 << 2)
+#define V_DIRECTION_DECREMENT (1 << 2)
#define COLOR_EXPAND (1 << 6)
#define H_FILTER_ENABLE (1 << 8)
#define V_FILTER_ENABLE (1 << 10)
diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c
index 21ed13a3b73f..d23199600269 100644
--- a/drivers/video/tegra/fb.c
+++ b/drivers/video/tegra/fb.c
@@ -407,6 +407,10 @@ static int tegra_fb_set_windowattr(struct tegra_fb_info *tegra_fb,
win->flags |= TEGRA_WIN_FLAG_BLEND_PREMULT;
else if (flip_win->attr.blend == TEGRA_FB_WIN_BLEND_COVERAGE)
win->flags |= TEGRA_WIN_FLAG_BLEND_COVERAGE;
+ if (flip_win->attr.flags & TEGRA_FB_WIN_FLAG_INVERT_H)
+ win->flags |= TEGRA_WIN_FLAG_INVERT_H;
+ if (flip_win->attr.flags & TEGRA_FB_WIN_FLAG_INVERT_V)
+ win->flags |= TEGRA_WIN_FLAG_INVERT_V;
if (flip_win->attr.layout == TEGRA_FB_WIN_LAYOUT_TILED)
win->flags |= TEGRA_WIN_FLAG_TILED;
diff --git a/include/video/tegrafb.h b/include/video/tegrafb.h
index c589742b2cfc..3d75f2dbe0eb 100644
--- a/include/video/tegrafb.h
+++ b/include/video/tegrafb.h
@@ -45,9 +45,12 @@
#define TEGRA_FB_WIN_FMT_YCbCr422RA 24
#define TEGRA_FB_WIN_FMT_YUV422RA 25
-#define TEGRA_FB_WIN_BLEND_NONE 0
-#define TEGRA_FB_WIN_BLEND_PREMULT 1
-#define TEGRA_FB_WIN_BLEND_COVERAGE 2
+#define TEGRA_FB_WIN_BLEND_NONE 0
+#define TEGRA_FB_WIN_BLEND_PREMULT 1
+#define TEGRA_FB_WIN_BLEND_COVERAGE 2
+
+#define TEGRA_FB_WIN_FLAG_INVERT_H (1 << 0)
+#define TEGRA_FB_WIN_FLAG_INVERT_V (1 << 1)
#define TEGRA_FB_WIN_LAYOUT_LINEAR 0
#define TEGRA_FB_WIN_LAYOUT_TILED 1
@@ -56,6 +59,7 @@
struct tegra_fb_windowattr {
__s32 index;
__u32 buff_id;
+ __u32 flags;
__u32 blend;
__u32 layout;
__u32 offset;