aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2013-10-04 16:34:01 -0400
committerThierry Reding <treding@nvidia.com>2013-10-31 04:55:46 -0400
commit773af77fc479fd454c3f6836f86bf63996545cf4 (patch)
treea3610dd713a97cf934810079da61b1196e85d95b
parent5f60ed0d840d53e9d65aa54e1a5365af8ce2769e (diff)
drm/tegra: Add support for tiled buffer objects
The gr2d and gr3d engines work more efficiently on buffers with a tiled memory layout. Allow created buffers to be marked as tiled so that the display controller can scan them out 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.c21
-rw-r--r--drivers/gpu/drm/tegra/dc.h4
-rw-r--r--drivers/gpu/drm/tegra/drm.c2
-rw-r--r--drivers/gpu/drm/tegra/drm.h2
-rw-r--r--drivers/gpu/drm/tegra/fb.c12
-rw-r--r--drivers/gpu/drm/tegra/gem.c13
-rw-r--r--drivers/gpu/drm/tegra/gem.h13
-rw-r--r--include/uapi/drm/tegra_drm.h2
8 files changed, 60 insertions, 9 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 054ca1b6bd31..c51aaf7555f5 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.tiled = tegra_fb_is_tiled(fb);
50 51
51 for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) { 52 for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
52 struct tegra_bo *bo = tegra_fb_get_plane(fb, i); 53 struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
@@ -157,6 +158,16 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
157 tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE); 158 tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
158 tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH); 159 tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH);
159 160
161 if (tegra_fb_is_tiled(fb)) {
162 value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
163 DC_WIN_BUFFER_ADDR_MODE_TILE;
164 } else {
165 value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
166 DC_WIN_BUFFER_ADDR_MODE_LINEAR;
167 }
168
169 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
170
160 value = GENERAL_UPDATE | WIN_A_UPDATE; 171 value = GENERAL_UPDATE | WIN_A_UPDATE;
161 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 172 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
162 173
@@ -509,6 +520,16 @@ int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
509 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET); 520 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
510 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET); 521 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
511 522
523 if (window->tiled) {
524 value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
525 DC_WIN_BUFFER_ADDR_MODE_TILE;
526 } else {
527 value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
528 DC_WIN_BUFFER_ADDR_MODE_LINEAR;
529 }
530
531 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
532
512 value = WIN_ENABLE; 533 value = WIN_ENABLE;
513 534
514 if (yuv) { 535 if (yuv) {
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 79eaec9aac77..e0b94c26bb86 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -365,6 +365,10 @@
365#define DC_WIN_BUF_STRIDE 0x70b 365#define DC_WIN_BUF_STRIDE 0x70b
366#define DC_WIN_UV_BUF_STRIDE 0x70c 366#define DC_WIN_UV_BUF_STRIDE 0x70c
367#define DC_WIN_BUFFER_ADDR_MODE 0x70d 367#define DC_WIN_BUFFER_ADDR_MODE 0x70d
368#define DC_WIN_BUFFER_ADDR_MODE_LINEAR (0 << 0)
369#define DC_WIN_BUFFER_ADDR_MODE_TILE (1 << 0)
370#define DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV (0 << 16)
371#define DC_WIN_BUFFER_ADDR_MODE_TILE_UV (1 << 16)
368#define DC_WIN_DV_CONTROL 0x70e 372#define DC_WIN_DV_CONTROL 0x70e
369 373
370#define DC_WIN_BLEND_NOKEY 0x70f 374#define DC_WIN_BLEND_NOKEY 0x70f
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 26a2903879d8..ecb6ec735ef1 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -262,7 +262,7 @@ static int tegra_gem_create(struct drm_device *drm, void *data,
262 struct drm_tegra_gem_create *args = data; 262 struct drm_tegra_gem_create *args = data;
263 struct tegra_bo *bo; 263 struct tegra_bo *bo;
264 264
265 bo = tegra_bo_create_with_handle(file, drm, args->size, 265 bo = tegra_bo_create_with_handle(file, drm, args->size, args->flags,
266 &args->handle); 266 &args->handle);
267 if (IS_ERR(bo)) 267 if (IS_ERR(bo))
268 return PTR_ERR(bo); 268 return PTR_ERR(bo);
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index b599fd4650ad..e07a10eedae6 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 tiled;
151}; 152};
152 153
153/* from dc.c */ 154/* from dc.c */
@@ -254,6 +255,7 @@ extern int tegra_output_exit(struct tegra_output *output);
254/* from fb.c */ 255/* from fb.c */
255struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer, 256struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
256 unsigned int index); 257 unsigned int index);
258bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer);
257extern int tegra_drm_fb_init(struct drm_device *drm); 259extern int tegra_drm_fb_init(struct drm_device *drm);
258extern void tegra_drm_fb_exit(struct drm_device *drm); 260extern void tegra_drm_fb_exit(struct drm_device *drm);
259extern void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev); 261extern void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 1fd4e196b934..fdb00e040046 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_tiled(struct drm_framebuffer *framebuffer)
38{
39 struct tegra_fb *fb = to_tegra_fb(framebuffer);
40
41 if (fb->planes[0]->flags & TEGRA_BO_TILED)
42 return true;
43
44 return false;
45}
46
37static void tegra_fb_destroy(struct drm_framebuffer *framebuffer) 47static void tegra_fb_destroy(struct drm_framebuffer *framebuffer)
38{ 48{
39 struct tegra_fb *fb = to_tegra_fb(framebuffer); 49 struct tegra_fb *fb = to_tegra_fb(framebuffer);
@@ -188,7 +198,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
188 198
189 size = cmd.pitches[0] * cmd.height; 199 size = cmd.pitches[0] * cmd.height;
190 200
191 bo = tegra_bo_create(drm, size); 201 bo = tegra_bo_create(drm, size, 0);
192 if (IS_ERR(bo)) 202 if (IS_ERR(bo))
193 return PTR_ERR(bo); 203 return PTR_ERR(bo);
194 204
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 267c0c21e5cc..d851ec106cf4 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -18,6 +18,8 @@
18 * GNU General Public License for more details. 18 * GNU General Public License for more details.
19 */ 19 */
20 20
21#include <drm/tegra_drm.h>
22
21#include "gem.h" 23#include "gem.h"
22 24
23static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo) 25static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo)
@@ -97,7 +99,8 @@ static void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo)
97 dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, bo->paddr); 99 dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, bo->paddr);
98} 100}
99 101
100struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size) 102struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
103 unsigned long flags)
101{ 104{
102 struct tegra_bo *bo; 105 struct tegra_bo *bo;
103 int err; 106 int err;
@@ -126,6 +129,9 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size)
126 if (err) 129 if (err)
127 goto err_mmap; 130 goto err_mmap;
128 131
132 if (flags & DRM_TEGRA_GEM_CREATE_TILED)
133 bo->flags |= TEGRA_BO_TILED;
134
129 return bo; 135 return bo;
130 136
131err_mmap: 137err_mmap:
@@ -142,12 +148,13 @@ err_dma:
142struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, 148struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
143 struct drm_device *drm, 149 struct drm_device *drm,
144 unsigned int size, 150 unsigned int size,
151 unsigned long flags,
145 unsigned int *handle) 152 unsigned int *handle)
146{ 153{
147 struct tegra_bo *bo; 154 struct tegra_bo *bo;
148 int ret; 155 int ret;
149 156
150 bo = tegra_bo_create(drm, size); 157 bo = tegra_bo_create(drm, size, flags);
151 if (IS_ERR(bo)) 158 if (IS_ERR(bo))
152 return bo; 159 return bo;
153 160
@@ -187,7 +194,7 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
187 if (args->size < args->pitch * args->height) 194 if (args->size < args->pitch * args->height)
188 args->size = args->pitch * args->height; 195 args->size = args->pitch * args->height;
189 196
190 bo = tegra_bo_create_with_handle(file, drm, args->size, 197 bo = tegra_bo_create_with_handle(file, drm, args->size, 0,
191 &args->handle); 198 &args->handle);
192 if (IS_ERR(bo)) 199 if (IS_ERR(bo))
193 return PTR_ERR(bo); 200 return PTR_ERR(bo);
diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h
index 2b54f1425d5e..c4993fc2c3bd 100644
--- a/drivers/gpu/drm/tegra/gem.h
+++ b/drivers/gpu/drm/tegra/gem.h
@@ -24,9 +24,12 @@
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)
28
27struct tegra_bo { 29struct tegra_bo {
28 struct drm_gem_object gem; 30 struct drm_gem_object gem;
29 struct host1x_bo base; 31 struct host1x_bo base;
32 unsigned long flags;
30 dma_addr_t paddr; 33 dma_addr_t paddr;
31 void *vaddr; 34 void *vaddr;
32}; 35};
@@ -38,11 +41,13 @@ static inline struct tegra_bo *to_tegra_bo(struct drm_gem_object *gem)
38 41
39extern const struct host1x_bo_ops tegra_bo_ops; 42extern const struct host1x_bo_ops tegra_bo_ops;
40 43
41struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size); 44struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
45 unsigned long flags);
42struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, 46struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
43 struct drm_device *drm, 47 struct drm_device *drm,
44 unsigned int size, 48 unsigned int size,
45 unsigned int *handle); 49 unsigned long flags,
50 unsigned int *handle);
46void tegra_bo_free_object(struct drm_gem_object *gem); 51void tegra_bo_free_object(struct drm_gem_object *gem);
47int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, 52int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
48 struct drm_mode_create_dumb *args); 53 struct drm_mode_create_dumb *args);
diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h
index 73bde4eaf16c..6b420029a645 100644
--- a/include/uapi/drm/tegra_drm.h
+++ b/include/uapi/drm/tegra_drm.h
@@ -19,6 +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)
23
22struct drm_tegra_gem_create { 24struct drm_tegra_gem_create {
23 __u64 size; 25 __u64 size;
24 __u32 flags; 26 __u32 flags;