aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2013-10-07 03:47:58 -0400
committerThierry Reding <treding@nvidia.com>2013-10-31 04:55:46 -0400
commitdb7fbdfd25ee009165b6c3b80a9d1c6d8534ad94 (patch)
tree1ba0c25b63b227a7f139b03ae217daf0b7ec1f81
parent773af77fc479fd454c3f6836f86bf63996545cf4 (diff)
drm/tegra: Support bottom-up buffer objects
The gr3d engine renders images bottom-up. Allow buffers that are used for 3D content to be marked as such and implement support in the display controller to present them properly. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dc.c24
-rw-r--r--drivers/gpu/drm/tegra/dc.h1
-rw-r--r--drivers/gpu/drm/tegra/drm.h2
-rw-r--r--drivers/gpu/drm/tegra/fb.c10
-rw-r--r--drivers/gpu/drm/tegra/gem.c3
-rw-r--r--drivers/gpu/drm/tegra/gem.h3
-rw-r--r--include/uapi/drm/tegra_drm.h3
7 files changed, 44 insertions, 2 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index c51aaf7555f5..ae1cb31ead7e 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -47,6 +47,7 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
47 window.dst.h = crtc_h; 47 window.dst.h = crtc_h;
48 window.format = tegra_dc_format(fb->pixel_format); 48 window.format = tegra_dc_format(fb->pixel_format);
49 window.bits_per_pixel = fb->bits_per_pixel; 49 window.bits_per_pixel = fb->bits_per_pixel;
50 window.bottom_up = tegra_fb_is_bottom_up(fb);
50 window.tiled = tegra_fb_is_tiled(fb); 51 window.tiled = tegra_fb_is_tiled(fb);
51 52
52 for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) { 53 for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
@@ -147,6 +148,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
147{ 148{
148 unsigned int format = tegra_dc_format(fb->pixel_format); 149 unsigned int format = tegra_dc_format(fb->pixel_format);
149 struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); 150 struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
151 unsigned int h_offset = 0, v_offset = 0;
150 unsigned long value; 152 unsigned long value;
151 153
152 tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); 154 tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -168,6 +170,22 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
168 170
169 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE); 171 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
170 172
173 /* make sure bottom-up buffers are properly displayed */
174 if (tegra_fb_is_bottom_up(fb)) {
175 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
176 value |= INVERT_V;
177 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
178
179 v_offset += fb->height - 1;
180 } else {
181 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
182 value &= ~INVERT_V;
183 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
184 }
185
186 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
187 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
188
171 value = GENERAL_UPDATE | WIN_A_UPDATE; 189 value = GENERAL_UPDATE | WIN_A_UPDATE;
172 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 190 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
173 191
@@ -517,6 +535,9 @@ int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
517 tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE); 535 tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE);
518 } 536 }
519 537
538 if (window->bottom_up)
539 v_offset += window->src.h - 1;
540
520 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET); 541 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
521 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET); 542 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
522 543
@@ -548,6 +569,9 @@ int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
548 value |= COLOR_EXPAND; 569 value |= COLOR_EXPAND;
549 } 570 }
550 571
572 if (window->bottom_up)
573 value |= INVERT_V;
574
551 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); 575 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
552 576
553 /* 577 /*
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index e0b94c26bb86..91bbda291470 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -302,6 +302,7 @@
302#define DC_WIN_CSC_KVB 0x618 302#define DC_WIN_CSC_KVB 0x618
303 303
304#define DC_WIN_WIN_OPTIONS 0x700 304#define DC_WIN_WIN_OPTIONS 0x700
305#define INVERT_V (1 << 2)
305#define COLOR_EXPAND (1 << 6) 306#define COLOR_EXPAND (1 << 6)
306#define CSC_ENABLE (1 << 18) 307#define CSC_ENABLE (1 << 18)
307#define WIN_ENABLE (1 << 30) 308#define WIN_ENABLE (1 << 30)
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index e07a10eedae6..fdfe259ed7f8 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -148,6 +148,7 @@ struct tegra_dc_window {
148 unsigned int format; 148 unsigned int format;
149 unsigned int stride[2]; 149 unsigned int stride[2];
150 unsigned long base[3]; 150 unsigned long base[3];
151 bool bottom_up;
151 bool tiled; 152 bool tiled;
152}; 153};
153 154
@@ -255,6 +256,7 @@ extern int tegra_output_exit(struct tegra_output *output);
255/* from fb.c */ 256/* from fb.c */
256struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer, 257struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
257 unsigned int index); 258 unsigned int index);
259bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer);
258bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer); 260bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer);
259extern int tegra_drm_fb_init(struct drm_device *drm); 261extern int tegra_drm_fb_init(struct drm_device *drm);
260extern void tegra_drm_fb_exit(struct drm_device *drm); 262extern void tegra_drm_fb_exit(struct drm_device *drm);
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index fdb00e040046..490f7719e317 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -34,6 +34,16 @@ struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
34 return fb->planes[index]; 34 return fb->planes[index];
35} 35}
36 36
37bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer)
38{
39 struct tegra_fb *fb = to_tegra_fb(framebuffer);
40
41 if (fb->planes[0]->flags & TEGRA_BO_BOTTOM_UP)
42 return true;
43
44 return false;
45}
46
37bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer) 47bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer)
38{ 48{
39 struct tegra_fb *fb = to_tegra_fb(framebuffer); 49 struct tegra_fb *fb = to_tegra_fb(framebuffer);
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index d851ec106cf4..28a9cbc07ab9 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -132,6 +132,9 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
132 if (flags & DRM_TEGRA_GEM_CREATE_TILED) 132 if (flags & DRM_TEGRA_GEM_CREATE_TILED)
133 bo->flags |= TEGRA_BO_TILED; 133 bo->flags |= TEGRA_BO_TILED;
134 134
135 if (flags & DRM_TEGRA_GEM_CREATE_BOTTOM_UP)
136 bo->flags |= TEGRA_BO_BOTTOM_UP;
137
135 return bo; 138 return bo;
136 139
137err_mmap: 140err_mmap:
diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h
index c4993fc2c3bd..7674000bf47d 100644
--- a/drivers/gpu/drm/tegra/gem.h
+++ b/drivers/gpu/drm/tegra/gem.h
@@ -24,7 +24,8 @@
24#include <drm/drm.h> 24#include <drm/drm.h>
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26 26
27#define TEGRA_BO_TILED (1 << 0) 27#define TEGRA_BO_TILED (1 << 0)
28#define TEGRA_BO_BOTTOM_UP (1 << 1)
28 29
29struct tegra_bo { 30struct tegra_bo {
30 struct drm_gem_object gem; 31 struct drm_gem_object gem;
diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h
index 6b420029a645..0f8575f58db8 100644
--- a/include/uapi/drm/tegra_drm.h
+++ b/include/uapi/drm/tegra_drm.h
@@ -19,7 +19,8 @@
19 19
20#include <drm/drm.h> 20#include <drm/drm.h>
21 21
22#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0) 22#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0)
23#define DRM_TEGRA_GEM_CREATE_BOTTOM_UP (1 << 1)
23 24
24struct drm_tegra_gem_create { 25struct drm_tegra_gem_create {
25 __u64 size; 26 __u64 size;