diff options
author | Ari Hirvonen <ahirvonen@nvidia.com> | 2011-03-02 02:06:27 +0200 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2011-05-27 19:52:32 -0700 |
commit | 60c73b63e651413fb8fba2c03b32c21843e8de22 (patch) | |
tree | 489d69cd9785ef8f40317ae1cd057c1cb2a4126f | |
parent | b5d5cd3e4e7af0915d2013f578f285244d7e5acd (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.h | 4 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 27 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_reg.h | 4 | ||||
-rw-r--r-- | drivers/video/tegra/fb.c | 4 | ||||
-rw-r--r-- | include/video/tegrafb.h | 10 |
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; |