video: tegra: add display inversion support
Ari Hirvonen [Wed, 2 Mar 2011 00:06:27 +0000 (02:06 +0200)]
Change-Id: Ied3851e0cb801f607499493f1e552f42daa97e6b
Signed-off-by: Ari Hirvonen <ahirvonen@nvidia.com>

arch/arm/mach-tegra/include/mach/dc.h
drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/dc_reg.h
drivers/video/tegra/fb.c
include/video/tegrafb.h

index 9bd2619..8ca6f3d 100644 (file)
@@ -122,6 +122,8 @@ 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_INVERT_H                (1 << 3)
+#define TEGRA_WIN_FLAG_INVERT_V                (1 << 4)
 
 #define TEGRA_WIN_BLEND_FLAGS_MASK \
        (TEGRA_WIN_FLAG_BLEND_PREMULT | TEGRA_WIN_FLAG_BLEND_COVERAGE)
index 4549670..e846be9 100644 (file)
@@ -500,6 +500,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]) {
@@ -567,9 +571,19 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
                                        DC_WIN_LINE_STRIDE);
                }
 
-               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);
+               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);
 
                val = WIN_ENABLE;
                if (yuvp)
@@ -582,6 +596,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;
index ab21c6e..43d0fa5 100644 (file)
 #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)
index 9b70114..06f399b 100644 (file)
@@ -387,6 +387,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;
        win->fmt = flip_win->attr.pixformat;
        win->x = flip_win->attr.x;
        win->y = flip_win->attr.y;
index b9861bc..01f94c6 100644 (file)
 #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)
 
 /* set index to -1 to ignore window data */
 struct tegra_fb_windowattr {
        __s32   index;
        __u32   buff_id;
+       __u32   flags;
        __u32   blend;
        __u32   offset;
        __u32   offset_u;