aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <molnar@ti.com>2010-07-17 00:39:41 -0400
committerPaolo Pisati <paolo.pisati@canonical.com>2012-08-17 04:19:02 -0400
commitb13a8b20c3607a331f5d55b110d6a3dbbe676c03 (patch)
treee601090aa253680ba8408cf73e0b79518a0be684
parenta5491c9d0de5f33056b336c788d54e864e150c4d (diff)
TILER: Cleaned up tiler-iface.c and tiler.h, _tiler.h
Updated comments. Simplified common expression when copying ioctl data. Simplified block_info filling. Removed unused variables, initializers, macros. Fixed issue with registering buffer with no blocks. Signed-off-by: Lajos Molnar <molnar@ti.com> Signed-off-by: David Sin <davidsin@ti.com> TILER: Minor comment & code cleanup Updated header comments. Removed extranous headers. Made ssptr_id flag read-only, as it should not be changed once tiler is being used. __analize_area now returns error values. 1D stride is explicitly set to 0 by describe. Signed-off-by: Lajos Molnar <molnar@ti.com> Signed-off-by: David Sin <davidsin@ti.com>
-rw-r--r--arch/arm/mach-omap2/include/mach/dmm.h2
-rw-r--r--arch/arm/mach-omap2/include/mach/tiler.h142
-rw-r--r--drivers/media/video/tiler/_tiler.h21
-rw-r--r--drivers/media/video/tiler/dmm.c1
-rw-r--r--drivers/media/video/tiler/tcm.h2
-rw-r--r--drivers/media/video/tiler/tiler-iface.c284
-rw-r--r--drivers/media/video/tiler/tiler-main.c77
-rw-r--r--drivers/media/video/tiler/tmm-pat.c2
-rw-r--r--drivers/media/video/tiler/tmm.h2
9 files changed, 274 insertions, 259 deletions
diff --git a/arch/arm/mach-omap2/include/mach/dmm.h b/arch/arm/mach-omap2/include/mach/dmm.h
index 77f824d2a8c..68b798a22c4 100644
--- a/arch/arm/mach-omap2/include/mach/dmm.h
+++ b/arch/arm/mach-omap2/include/mach/dmm.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * dmm.h 2 * dmm.h
3 * 3 *
4 * DMM driver support functions for TI OMAP processors. 4 * DMM driver support functions for TI DMM-TILER hardware block.
5 * 5 *
6 * Author: David Sin <davidsin@ti.com> 6 * Author: David Sin <davidsin@ti.com>
7 * 7 *
diff --git a/arch/arm/mach-omap2/include/mach/tiler.h b/arch/arm/mach-omap2/include/mach/tiler.h
index a598fe51ffd..84452bc8944 100644
--- a/arch/arm/mach-omap2/include/mach/tiler.h
+++ b/arch/arm/mach-omap2/include/mach/tiler.h
@@ -1,7 +1,10 @@
1/* 1/*
2 * tiler.h 2 * tiler.h
3 * 3 *
4 * TILER driver support functions for TI OMAP processors. 4 * TILER driver support functions for TI TILER hardware block.
5 *
6 * Authors: Lajos Molnar <molnar@ti.com>
7 * David Sin <davidsin@ti.com>
5 * 8 *
6 * Copyright (C) 2009-2010 Texas Instruments, Inc. 9 * Copyright (C) 2009-2010 Texas Instruments, Inc.
7 * 10 *
@@ -17,8 +20,6 @@
17#ifndef TILER_H 20#ifndef TILER_H
18#define TILER_H 21#define TILER_H
19 22
20#define TILER_MAX_NUM_BLOCKS 16
21
22#include <linux/mm.h> 23#include <linux/mm.h>
23 24
24/* 25/*
@@ -40,27 +41,29 @@ enum tiler_fmt {
40 TILFMT_8AND16 = 4, /* used to mark NV12 reserve block */ 41 TILFMT_8AND16 = 4, /* used to mark NV12 reserve block */
41}; 42};
42 43
44/* tiler block info */
43struct tiler_block_t { 45struct tiler_block_t {
44 u32 phys; /* system space (L3) tiler addr */ 46 u32 phys; /* system space (L3) tiler addr */
45 u32 width; /* width */ 47 u32 width; /* width */
46 u32 height; /* height */ 48 u32 height; /* height */
47 u32 key; /* secret key */ 49 u32 key; /* secret key */
48 u32 id; /* unique block ID */ 50 u32 id; /* unique block ID */
49}; 51};
50 52
53/* tiler (image/video frame) view */
51struct tiler_view_t { 54struct tiler_view_t {
52 u32 tsptr; /* tiler space addr */ 55 u32 tsptr; /* tiler space addr */
53 u32 width; /* width */ 56 u32 width; /* width */
54 u32 height; /* height */ 57 u32 height; /* height */
55 u32 bpp; /* bytes per pixel */ 58 u32 bpp; /* bytes per pixel */
56 s32 h_inc; /* horizontal increment */ 59 s32 h_inc; /* horizontal increment */
57 s32 v_inc; /* vertical increment */ 60 s32 v_inc; /* vertical increment */
58}; 61};
59 62
60/* get tiler format for a physical address */ 63/* get the tiler format for a physical address or TILFMT_INVALID */
61enum tiler_fmt tiler_fmt(u32 phys); 64enum tiler_fmt tiler_fmt(u32 phys);
62 65
63/* get tiler block bytes-per-pixel */ 66/* get the modified (1 for page mode) bytes-per-pixel for a tiler block */
64u32 tiler_bpp(const struct tiler_block_t *b); 67u32 tiler_bpp(const struct tiler_block_t *b);
65 68
66/* get tiler block physical stride */ 69/* get tiler block physical stride */
@@ -86,7 +89,7 @@ static inline u32 tiler_size(const struct tiler_block_t *b)
86 * must be 0) with the tiler block information. 'height' must be 1 89 * must be 0) with the tiler block information. 'height' must be 1
87 * for 1D block. 90 * for 1D block.
88 * @param fmt TILER block format 91 * @param fmt TILER block format
89 * @param align block alignment (default: PAGE_SIZE) 92 * @param align block alignment (default: normally PAGE_SIZE)
90 * @param offs block offset 93 * @param offs block offset
91 * 94 *
92 * @return error status 95 * @return error status
@@ -101,8 +104,8 @@ s32 tiler_alloc(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 align,
101 * @param blk pointer to tiler block data. This must be set up ('phys' member 104 * @param blk pointer to tiler block data. This must be set up ('phys' member
102 * must be 0) with the tiler block information. 'height' must be 1 105 * must be 0) with the tiler block information. 'height' must be 1
103 * for 1D block. 106 * for 1D block.
104 * @param fmt TILER bit mode 107 * @param fmt TILER block format
105 * @param align block alignment (default: PAGE_SIZE) 108 * @param align block alignment (default: normally PAGE_SIZE)
106 * @param offs block offset 109 * @param offs block offset
107 * @param gid group ID 110 * @param gid group ID
108 * @param pid process ID 111 * @param pid process ID
@@ -110,7 +113,7 @@ s32 tiler_alloc(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 align,
110 * @return error status 113 * @return error status
111 */ 114 */
112s32 tiler_allocx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 align, 115s32 tiler_allocx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 align,
113 u32 offs, u32 gid, pid_t pid); 116 u32 offs, u32 gid, pid_t pid);
114 117
115/** 118/**
116 * Mmaps a portion of a tiler block to a virtual address. Use this method in 119 * Mmaps a portion of a tiler block to a virtual address. Use this method in
@@ -120,7 +123,9 @@ s32 tiler_allocx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 align,
120 * @param blk pointer to tiler block data 123 * @param blk pointer to tiler block data
121 * @param offs offset from where to map (must be page aligned) 124 * @param offs offset from where to map (must be page aligned)
122 * @param size size of area to map (must be page aligned) 125 * @param size size of area to map (must be page aligned)
123 * @param addr virtual address 126 * @param vma VMM memory area to map to
127 * @param voffs offset (from vm_start) in the VMM memory area to start
128 * mapping at
124 * 129 *
125 * @return error status 130 * @return error status
126 */ 131 */
@@ -136,11 +141,12 @@ s32 tiler_mmap_blk(struct tiler_block_t *blk, u32 offs, u32 size,
136 * @param offs offset from where to map (must be page aligned) 141 * @param offs offset from where to map (must be page aligned)
137 * @param size size of area to map (must be page aligned) 142 * @param size size of area to map (must be page aligned)
138 * @param addr virtual address 143 * @param addr virtual address
144 * @param mtype ioremap memory type (e.g. MT_DEVICE)
139 * 145 *
140 * @return error status 146 * @return error status
141 */ 147 */
142s32 tiler_ioremap_blk(struct tiler_block_t *blk, u32 offs, u32 size, u32 addr, 148s32 tiler_ioremap_blk(struct tiler_block_t *blk, u32 offs, u32 size, u32 addr,
143 u32 mtype); 149 u32 mtype);
144 150
145/** 151/**
146 * Maps an existing buffer to a 1D or 2D TILER area for the 152 * Maps an existing buffer to a 1D or 2D TILER area for the
@@ -152,9 +158,9 @@ s32 tiler_ioremap_blk(struct tiler_block_t *blk, u32 offs, u32 size, u32 addr,
152 * into tiler container. 158 * into tiler container.
153 * 159 *
154 * @param blk pointer to tiler block data. This must be set up 160 * @param blk pointer to tiler block data. This must be set up
155 * ('phys' member must be 0) with the tiler block information. 161 * ('phys' member must be 0) with the tiler block
156 * 'height' must be 1 for 1D block. 162 * information. 'height' must be 1 for 1D block.
157 * @param fmt TILER bit mode 163 * @param fmt TILER format
158 * @param usr_addr user space address of existing buffer. 164 * @param usr_addr user space address of existing buffer.
159 * 165 *
160 * @return error status 166 * @return error status
@@ -171,9 +177,9 @@ s32 tiler_map(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 usr_addr);
171 * into tiler container. 177 * into tiler container.
172 * 178 *
173 * @param blk pointer to tiler block data. This must be set up 179 * @param blk pointer to tiler block data. This must be set up
174 * ('phys' member must be 0) with the tiler block information. 180 * ('phys' member must be 0) with the tiler block
175 * 'height' must be 1 for 1D block. 181 * information. 'height' must be 1 for 1D block.
176 * @param fmt TILER bit mode 182 * @param fmt TILER format
177 * @param gid group ID 183 * @param gid group ID
178 * @param pid process ID 184 * @param pid process ID
179 * @param usr_addr user space address of existing buffer. 185 * @param usr_addr user space address of existing buffer.
@@ -181,7 +187,7 @@ s32 tiler_map(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 usr_addr);
181 * @return error status 187 * @return error status
182 */ 188 */
183s32 tiler_mapx(struct tiler_block_t *blk, enum tiler_fmt fmt, 189s32 tiler_mapx(struct tiler_block_t *blk, enum tiler_fmt fmt,
184 u32 gid, pid_t pid, u32 usr_addr); 190 u32 gid, pid_t pid, u32 usr_addr);
185 191
186/** 192/**
187 * Frees TILER memory. Since there may be multiple references for the same area 193 * Frees TILER memory. Since there may be multiple references for the same area
@@ -189,34 +195,30 @@ s32 tiler_mapx(struct tiler_block_t *blk, enum tiler_fmt fmt,
189 * have been freed. 195 * have been freed.
190 * 196 *
191 * @param blk pointer to a tiler block data as filled by tiler_alloc, 197 * @param blk pointer to a tiler block data as filled by tiler_alloc,
192 * tiler_map or tiler_dup. 'phys' member will be set to 0 on 198 * tiler_map or tiler_dup. 'phys' and 'id' members will be set to
193 * success. 199 * 0 on success.
194 */ 200 */
195void tiler_free(struct tiler_block_t *blk); 201void tiler_free(struct tiler_block_t *blk);
196 202
197/** 203/**
198 * Reserves tiler area for n identical blocks for the current 204 * Reserves tiler area for n identical blocks for the current process. Use this
199 * process. Use this method to get optimal placement of 205 * method to get optimal placement of multiple identical tiler blocks; however,
200 * multiple identical tiler blocks; however, it may not reserve 206 * it may not reserve area if tiler_alloc is equally efficient.
201 * area if tiler_alloc is equally efficient.
202 * 207 *
203 * @param n number of identical set of blocks 208 * @param n number of identical set of blocks
204 * @param fmt TILER bit mode 209 * @param fmt TILER format
205 * @param width block width 210 * @param width block width
206 * @param height block height (must be 1 for 1D) 211 * @param height block height (must be 1 for 1D)
207 * @param align block alignment (default: PAGE_SIZE) 212 * @param align block alignment (default: PAGE_SIZE)
208 * @param offs block offset 213 * @param offs block offset
209 *
210 * @return error status
211 */ 214 */
212s32 tiler_reserve(u32 n, enum tiler_fmt fmt, u32 width, u32 height, 215void tiler_reserve(u32 n, enum tiler_fmt fmt, u32 width, u32 height, u32 align,
213 u32 align, u32 offs); 216 u32 offs);
214 217
215/** 218/**
216 * Reserves tiler area for n identical blocks. Use this method 219 * Reserves tiler area for n identical blocks. Use this method to get optimal
217 * to get optimal placement of multiple identical tiler blocks; 220 * placement of multiple identical tiler blocks; however, it may not reserve
218 * however, it may not reserve area if tiler_alloc is equally 221 * area if tiler_alloc is equally efficient.
219 * efficient.
220 * 222 *
221 * @param n number of identical set of blocks 223 * @param n number of identical set of blocks
222 * @param fmt TILER bit mode 224 * @param fmt TILER bit mode
@@ -226,33 +228,27 @@ s32 tiler_reserve(u32 n, enum tiler_fmt fmt, u32 width, u32 height,
226 * @param offs block offset 228 * @param offs block offset
227 * @param gid group ID 229 * @param gid group ID
228 * @param pid process ID 230 * @param pid process ID
229 *
230 * @return error status
231 */ 231 */
232s32 tiler_reservex(u32 n, enum tiler_fmt fmt, u32 width, u32 height, 232void tiler_reservex(u32 n, enum tiler_fmt fmt, u32 width, u32 height,
233 u32 align, u32 offs, u32 gid, pid_t pid); 233 u32 align, u32 offs, u32 gid, pid_t pid);
234 234
235/** 235/**
236 * Reserves tiler area for n identical NV12 blocks for the 236 * Reserves tiler area for n identical NV12 blocks for the current process. Use
237 * current process. Use this method to get optimal placement of 237 * this method to get optimal placement of multiple identical NV12 tiler blocks;
238 * multiple identical NV12 tiler blocks; however, it may not 238 * however, it may not reserve area if tiler_alloc is equally efficient.
239 * reserve area if tiler_alloc is equally efficient.
240 * 239 *
241 * @param n number of identical set of blocks 240 * @param n number of identical set of blocks
242 * @param width block width (Y) 241 * @param width block width (Y)
243 * @param height block height (Y) 242 * @param height block height (Y)
244 * @param align block alignment (default: PAGE_SIZE) 243 * @param align block alignment (default: PAGE_SIZE)
245 * @param offs block offset 244 * @param offs block offset
246 *
247 * @return error status
248 */ 245 */
249s32 tiler_reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs); 246void tiler_reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs);
250 247
251/** 248/**
252 * Reserves tiler area for n identical NV12 blocks. Use this 249 * Reserves tiler area for n identical NV12 blocks. Use this method to get
253 * method to get optimal placement of multiple identical NV12 250 * optimal placement of multiple identical NV12 tiler blocks; however, it may
254 * tiler blocks; however, it may not reserve area if tiler_alloc 251 * not reserve area if tiler_alloc is equally efficient.
255 * is equally efficient.
256 * 252 *
257 * @param n number of identical set of blocks 253 * @param n number of identical set of blocks
258 * @param width block width (Y) 254 * @param width block width (Y)
@@ -261,18 +257,16 @@ s32 tiler_reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs);
261 * @param offs block offset 257 * @param offs block offset
262 * @param gid group ID 258 * @param gid group ID
263 * @param pid process ID 259 * @param pid process ID
264 *
265 * @return error status
266 */ 260 */
267s32 tiler_reservex_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs, 261void tiler_reservex_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs,
268 u32 gid, pid_t pid); 262 u32 gid, pid_t pid);
269 263
270/** 264/**
271 * Create a view based on a tiler address and width and height 265 * Create a view based on a tiler address and width and height
272 * 266 *
273 * This method should only be used as a last resort, if tilview object cannot 267 * This method should only be used as a last resort, e.g. if tilview object
274 * be passed because of incoherence with other view 2D objects that must be 268 * cannot be passed because of incoherence with other view 2D objects that must
275 * supported. 269 * be supported.
276 * 270 *
277 * @param view Pointer to a view where the information will be stored 271 * @param view Pointer to a view where the information will be stored
278 * @param ssptr MUST BE a tiler address 272 * @param ssptr MUST BE a tiler address
@@ -333,6 +327,7 @@ s32 tilview_flip(struct tiler_view_t *view, bool flip_x, bool flip_y);
333 * ---------------------------- IOCTL Definitions ---------------------------- 327 * ---------------------------- IOCTL Definitions ----------------------------
334 */ 328 */
335 329
330/* ioctls */
336#define TILIOC_GBLK _IOWR('z', 100, struct tiler_block_info) 331#define TILIOC_GBLK _IOWR('z', 100, struct tiler_block_info)
337#define TILIOC_FBLK _IOW('z', 101, struct tiler_block_info) 332#define TILIOC_FBLK _IOW('z', 101, struct tiler_block_info)
338#define TILIOC_GSSP _IOWR('z', 102, u32) 333#define TILIOC_GSSP _IOWR('z', 102, u32)
@@ -350,23 +345,26 @@ struct area {
350 u16 height; 345 u16 height;
351}; 346};
352 347
348/* userspace tiler block info */
353struct tiler_block_info { 349struct tiler_block_info {
354 enum tiler_fmt fmt; 350 enum tiler_fmt fmt;
355 union { 351 union {
356 struct area area; 352 struct area area;
357 u32 len; 353 u32 len;
358 } dim; 354 } dim;
359 u32 stride; 355 u32 stride; /* stride is not maintained for 1D blocks */
360 void *ptr; 356 void *ptr; /* userspace address for mapping existing buffer */
361 u32 id; 357 u32 id;
362 u32 key; 358 u32 key;
363 u32 group_id; 359 u32 group_id;
364 /* alignment requirements for ssptr: ssptr & (align - 1) == offs */ 360 u32 align; /* alignment requirements for ssptr */
365 u32 align; 361 u32 offs; /* offset (ssptr & (align - 1) will equal offs) */
366 u32 offs; 362 u32 ssptr; /* physical address, may not exposed by default */
367 u32 ssptr;
368}; 363};
369 364
365#define TILER_MAX_NUM_BLOCKS 16
366
367/* userspace tiler buffer info */
370struct tiler_buf_info { 368struct tiler_buf_info {
371 u32 num_blocks; 369 u32 num_blocks;
372 struct tiler_block_info blocks[TILER_MAX_NUM_BLOCKS]; 370 struct tiler_block_info blocks[TILER_MAX_NUM_BLOCKS];
@@ -374,6 +372,4 @@ struct tiler_buf_info {
374 u32 length; /* also used as number of buffers for reservation */ 372 u32 length; /* also used as number of buffers for reservation */
375}; 373};
376 374
377
378#endif 375#endif
379
diff --git a/drivers/media/video/tiler/_tiler.h b/drivers/media/video/tiler/_tiler.h
index 24031348bf6..aeec9f6de6e 100644
--- a/drivers/media/video/tiler/_tiler.h
+++ b/drivers/media/video/tiler/_tiler.h
@@ -1,7 +1,9 @@
1/* 1/*
2 * _tiler.h 2 * _tiler.h
3 * 3 *
4 * TILER driver internal shared definitions for TI OMAP processors. 4 * TI TILER driver internal shared definitions.
5 *
6 * Author: Lajos Molnar <molnar@ti.com>
5 * 7 *
6 * Copyright (C) 2009-2010 Texas Instruments, Inc. 8 * Copyright (C) 2009-2010 Texas Instruments, Inc.
7 * 9 *
@@ -21,9 +23,6 @@
21#include <mach/tiler.h> 23#include <mach/tiler.h>
22#include "tcm.h" 24#include "tcm.h"
23 25
24#define MIN(a, b) ((a) < (b) ? (a) : (b))
25#define MAX(a, b) ((a) > (b) ? (a) : (b))
26
27#define TILER_FORMATS (TILFMT_MAX - TILFMT_MIN + 1) 26#define TILER_FORMATS (TILFMT_MAX - TILFMT_MIN + 1)
28 27
29/* per process (thread group) info */ 28/* per process (thread group) info */
@@ -48,6 +47,7 @@ struct gid_info {
48 struct process_info *pi; /* parent */ 47 struct process_info *pi; /* parent */
49}; 48};
50 49
50/* info for an area reserved from a container */
51struct area_info { 51struct area_info {
52 struct list_head by_gid; /* areas in this pid/gid */ 52 struct list_head by_gid; /* areas in this pid/gid */
53 struct list_head blocks; /* blocks in this area */ 53 struct list_head blocks; /* blocks in this area */
@@ -57,6 +57,7 @@ struct area_info {
57 struct gid_info *gi; /* link to parent, if still alive */ 57 struct gid_info *gi; /* link to parent, if still alive */
58}; 58};
59 59
60/* info for a block */
60struct mem_info { 61struct mem_info {
61 struct list_head global; /* reserved / global blocks */ 62 struct list_head global; /* reserved / global blocks */
62 struct tiler_block_t blk; /* block info */ 63 struct tiler_block_t blk; /* block info */
@@ -72,6 +73,7 @@ struct mem_info {
72 void *parent; /* area info for 2D, else group info */ 73 void *parent; /* area info for 2D, else group info */
73}; 74};
74 75
76/* tiler geometry information */
75struct tiler_geom { 77struct tiler_geom {
76 u32 x_shft; /* unused X-bits (as part of bpp) */ 78 u32 x_shft; /* unused X-bits (as part of bpp) */
77 u32 y_shft; /* unused Y-bits (as part of bpp) */ 79 u32 y_shft; /* unused Y-bits (as part of bpp) */
@@ -81,6 +83,7 @@ struct tiler_geom {
81 u32 bpp_m; /* modified bytes per pixel (=1 for page mode) */ 83 u32 bpp_m; /* modified bytes per pixel (=1 for page mode) */
82}; 84};
83 85
86/* methods and variables shared between source files */
84struct tiler_ops { 87struct tiler_ops {
85 /* block operations */ 88 /* block operations */
86 s32 (*alloc) (enum tiler_fmt fmt, u32 width, u32 height, 89 s32 (*alloc) (enum tiler_fmt fmt, u32 width, u32 height,
@@ -93,7 +96,7 @@ struct tiler_ops {
93 void (*reserve_nv12) (u32 n, u32 width, u32 height, u32 align, u32 offs, 96 void (*reserve_nv12) (u32 n, u32 width, u32 height, u32 align, u32 offs,
94 u32 gid, struct process_info *pi); 97 u32 gid, struct process_info *pi);
95 void (*reserve) (u32 n, enum tiler_fmt fmt, u32 width, u32 height, 98 void (*reserve) (u32 n, enum tiler_fmt fmt, u32 width, u32 height,
96 u32 align, u32 offs, u32 gid, struct process_info *pi); 99 u32 align, u32 offs, u32 gid, struct process_info *pi);
97 void (*unreserve) (u32 gid, struct process_info *pi); 100 void (*unreserve) (u32 gid, struct process_info *pi);
98 101
99 /* block access operations */ 102 /* block access operations */
@@ -103,8 +106,8 @@ struct tiler_ops {
103 void (*unlock_free) (struct mem_info *mi, bool free); 106 void (*unlock_free) (struct mem_info *mi, bool free);
104 107
105 s32 (*lay_2d) (enum tiler_fmt fmt, u16 n, u16 w, u16 h, u16 band, 108 s32 (*lay_2d) (enum tiler_fmt fmt, u16 n, u16 w, u16 h, u16 band,
106 u16 align, u16 offs, struct gid_info *gi, 109 u16 align, u16 offs, struct gid_info *gi,
107 struct list_head *pos); 110 struct list_head *pos);
108 s32 (*lay_nv12) (int n, u16 w, u16 w1, u16 h, struct gid_info *gi, 111 s32 (*lay_nv12) (int n, u16 w, u16 w1, u16 h, struct gid_info *gi,
109 u8 *p); 112 u8 *p);
110 /* group operations */ 113 /* group operations */
@@ -118,8 +121,8 @@ struct tiler_ops {
118 121
119 /* area operations */ 122 /* area operations */
120 s32 (*analize) (enum tiler_fmt fmt, u32 width, u32 height, 123 s32 (*analize) (enum tiler_fmt fmt, u32 width, u32 height,
121 u16 *x_area, u16 *y_area, u16 *band, 124 u16 *x_area, u16 *y_area, u16 *band,
122 u16 *align, u16 *offs, u16 *in_offs); 125 u16 *align, u16 *offs, u16 *in_offs);
123 126
124 /* process operations */ 127 /* process operations */
125 void (*cleanup) (void); 128 void (*cleanup) (void);
diff --git a/drivers/media/video/tiler/dmm.c b/drivers/media/video/tiler/dmm.c
index 685a1935a7f..5ca5e7d5fa3 100644
--- a/drivers/media/video/tiler/dmm.c
+++ b/drivers/media/video/tiler/dmm.c
@@ -20,7 +20,6 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/platform_device.h> /* platform_device() */ 22#include <linux/platform_device.h> /* platform_device() */
23#include <linux/err.h> /* IS_ERR() */
24#include <linux/io.h> /* ioremap() */ 23#include <linux/io.h> /* ioremap() */
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
diff --git a/drivers/media/video/tiler/tcm.h b/drivers/media/video/tiler/tcm.h
index abeb99b6697..68b0d684dd5 100644
--- a/drivers/media/video/tiler/tcm.h
+++ b/drivers/media/video/tiler/tcm.h
@@ -2,7 +2,7 @@
2 * tcm.h 2 * tcm.h
3 * 3 *
4 * TILER container manager specification and support functions for TI 4 * TILER container manager specification and support functions for TI
5 * processors. 5 * TILER driver.
6 * 6 *
7 * Author: Lajos Molnar <molnar@ti.com> 7 * Author: Lajos Molnar <molnar@ti.com>
8 * 8 *
diff --git a/drivers/media/video/tiler/tiler-iface.c b/drivers/media/video/tiler/tiler-iface.c
index 688af6c8f71..a93cd486e09 100644
--- a/drivers/media/video/tiler/tiler-iface.c
+++ b/drivers/media/video/tiler/tiler-iface.c
@@ -1,7 +1,10 @@
1/* 1/*
2 * tiler-iface.c 2 * tiler-iface.c
3 * 3 *
4 * TILER driver interace functions for TI OMAP processors. 4 * TILER driver interace functions for TI TILER hardware block.
5 *
6 * Authors: Lajos Molnar <molnar@ti.com>
7 * David Sin <davidsin@ti.com>
5 * 8 *
6 * Copyright (C) 2009-2010 Texas Instruments, Inc. 9 * Copyright (C) 2009-2010 Texas Instruments, Inc.
7 * 10 *
@@ -22,7 +25,7 @@
22#include <linux/sched.h> /* current */ 25#include <linux/sched.h> /* current */
23#include <linux/mm.h> 26#include <linux/mm.h>
24#include <linux/mm_types.h> 27#include <linux/mm_types.h>
25#include <asm/mach/map.h> /* for ioremap_page */ 28#include <asm/mach/map.h> /* for ioremap_page */
26 29
27#include "_tiler.h" 30#include "_tiler.h"
28 31
@@ -41,8 +44,8 @@ MODULE_PARM_DESC(offset_lookup,
41 "Allow looking up a buffer by offset - This is a security risk"); 44 "Allow looking up a buffer by offset - This is a security risk");
42 45
43static struct mutex mtx; 46static struct mutex mtx;
44static struct list_head procs; 47static struct list_head procs; /* list of process info structs */
45static struct tiler_ops *ops; 48static struct tiler_ops *ops; /* shared methods and variables */
46 49
47/* 50/*
48 * Buffer handling methods 51 * Buffer handling methods
@@ -56,11 +59,10 @@ struct __buf_info {
56}; 59};
57 60
58/* check if an offset is used */ 61/* check if an offset is used */
59/* must have mutex */
60/*** register_buf */
61static bool _m_offs_in_use(u32 offs, u32 length, struct process_info *pi) 62static bool _m_offs_in_use(u32 offs, u32 length, struct process_info *pi)
62{ 63{
63 struct __buf_info *_b; 64 struct __buf_info *_b;
65 /* have mutex */
64 list_for_each_entry(_b, &pi->bufs, by_pid) 66 list_for_each_entry(_b, &pi->bufs, by_pid)
65 if (_b->buf_info.offset < offs + length && 67 if (_b->buf_info.offset < offs + length &&
66 _b->buf_info.offset + _b->buf_info.length > offs) 68 _b->buf_info.offset + _b->buf_info.length > offs)
@@ -69,8 +71,6 @@ static bool _m_offs_in_use(u32 offs, u32 length, struct process_info *pi)
69} 71}
70 72
71/* get an offset */ 73/* get an offset */
72/* must have mutex */
73/*** register_buf */
74static u32 _m_get_offs(struct process_info *pi, u32 length) 74static u32 _m_get_offs(struct process_info *pi, u32 length)
75{ 75{
76 static u32 offs = 0xda7a; 76 static u32 offs = 0xda7a;
@@ -78,6 +78,8 @@ static u32 _m_get_offs(struct process_info *pi, u32 length)
78 /* ensure no-one is using this offset */ 78 /* ensure no-one is using this offset */
79 while ((offs << PAGE_SHIFT) + length < length || 79 while ((offs << PAGE_SHIFT) + length < length ||
80 _m_offs_in_use(offs << PAGE_SHIFT, length, pi)) { 80 _m_offs_in_use(offs << PAGE_SHIFT, length, pi)) {
81 /* use a pseudo-random generator to get a new offset to try */
82
81 /* Galois LSF: 20, 17 */ 83 /* Galois LSF: 20, 17 */
82 offs = (offs >> 1) ^ (u32)((0 - (offs & 1u)) & 0x90000); 84 offs = (offs >> 1) ^ (u32)((0 - (offs & 1u)) & 0x90000);
83 } 85 }
@@ -86,14 +88,15 @@ static u32 _m_get_offs(struct process_info *pi, u32 length)
86} 88}
87 89
88/* find and lock a block. process_info is optional */ 90/* find and lock a block. process_info is optional */
89/* must have mutex */
90static struct mem_info * 91static struct mem_info *
91_m_lock_block(u32 key, u32 id, struct process_info *pi) { 92_m_lock_block(u32 key, u32 id, struct process_info *pi) {
92 struct gid_info *gi = NULL; 93 struct gid_info *gi;
93 struct mem_info *mi = NULL; 94 struct mem_info *mi;
94 95
95 /* if process_info is given, look there first */ 96 /* if process_info is given, look there first */
96 if (pi) { 97 if (pi) {
98 /* have mutex */
99
97 /* find block in process list and free it */ 100 /* find block in process list and free it */
98 list_for_each_entry(gi, &pi->groups, by_pid) { 101 list_for_each_entry(gi, &pi->groups, by_pid) {
99 mi = ops->lock(key, id, gi); 102 mi = ops->lock(key, id, gi);
@@ -107,15 +110,14 @@ _m_lock_block(u32 key, u32 id, struct process_info *pi) {
107} 110}
108 111
109/* register a buffer */ 112/* register a buffer */
110/* must have mutex */
111static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi) 113static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi)
112{ 114{
113 struct mem_info *mi = NULL; 115 struct mem_info *mi;
114 struct tiler_buf_info *b = &_b->buf_info; 116 struct tiler_buf_info *b = &_b->buf_info;
115 u32 i, num = b->num_blocks, offs; 117 u32 i, num = b->num_blocks, offs;
116 118
117 /* check validity */ 119 /* check validity */
118 if (num > TILER_MAX_NUM_BLOCKS) 120 if (num > TILER_MAX_NUM_BLOCKS || num == 0)
119 return -EINVAL; 121 return -EINVAL;
120 122
121 /* find each block */ 123 /* find each block */
@@ -129,6 +131,11 @@ static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi)
129 return -EACCES; 131 return -EACCES;
130 } 132 }
131 _b->mi[i] = mi; 133 _b->mi[i] = mi;
134
135 /* we don't keep track of ptr and 1D stride so clear them */
136 b->blocks[i].ptr = NULL;
137 b->blocks[i].stride = 0;
138
132 ops->describe(mi, b->blocks + i); 139 ops->describe(mi, b->blocks + i);
133 b->length += tiler_size(&mi->blk); 140 b->length += tiler_size(&mi->blk);
134 } 141 }
@@ -138,13 +145,13 @@ static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi)
138 b->offset = _m_get_offs(pi, b->length) + offs; 145 b->offset = _m_get_offs(pi, b->length) + offs;
139 b->length -= offs; 146 b->length -= offs;
140 147
148 /* have mutex */
141 list_add(&_b->by_pid, &pi->bufs); 149 list_add(&_b->by_pid, &pi->bufs);
142 150
143 return 0; 151 return 0;
144} 152}
145 153
146/* unregister a buffer */ 154/* unregister a buffer */
147/* must have mutex */
148static void _m_unregister_buf(struct __buf_info *_b) 155static void _m_unregister_buf(struct __buf_info *_b)
149{ 156{
150 u32 i; 157 u32 i;
@@ -164,15 +171,16 @@ static void _m_unregister_buf(struct __buf_info *_b)
164 * ========================================================================== 171 * ==========================================================================
165 */ 172 */
166 173
167
168/* get process info, and increment refs for device tracking */ 174/* get process info, and increment refs for device tracking */
169static struct process_info *__get_pi(pid_t pid, bool kernel) 175static struct process_info *__get_pi(pid_t pid, bool kernel)
170{ 176{
171 struct process_info *pi; 177 struct process_info *pi;
172 178
173 /* treat all processes as the same, kernel processes are still treated 179 /*
174 differently so not to free kernel allocated areas when a user process 180 * treat all processes as the same, kernel processes are still treated
175 closes the tiler driver */ 181 * differently so not to free kernel allocated areas when a user process
182 * closes the tiler driver
183 */
176 if (!security) 184 if (!security)
177 pid = 0; 185 pid = 0;
178 186
@@ -187,14 +195,15 @@ static struct process_info *__get_pi(pid_t pid, bool kernel)
187 pi = kmalloc(sizeof(*pi), GFP_KERNEL); 195 pi = kmalloc(sizeof(*pi), GFP_KERNEL);
188 if (!pi) 196 if (!pi)
189 goto done; 197 goto done;
190
191 memset(pi, 0, sizeof(*pi)); 198 memset(pi, 0, sizeof(*pi));
199
192 pi->pid = pid; 200 pi->pid = pid;
193 pi->kernel = kernel; 201 pi->kernel = kernel;
194 INIT_LIST_HEAD(&pi->groups); 202 INIT_LIST_HEAD(&pi->groups);
195 INIT_LIST_HEAD(&pi->bufs); 203 INIT_LIST_HEAD(&pi->bufs);
196 list_add(&pi->list, &procs); 204 list_add(&pi->list, &procs);
197done: 205done:
206 /* increment reference count */
198 if (pi && !kernel) 207 if (pi && !kernel)
199 pi->refs++; 208 pi->refs++;
200 mutex_unlock(&mtx); 209 mutex_unlock(&mtx);
@@ -202,20 +211,17 @@ done:
202} 211}
203 212
204/** 213/**
205 * Free all info kept by a process: 214 * Free all info kept by a process: all registered buffers, allocated blocks,
206 * 215 * and unreferenced blocks. Any blocks/areas still referenced will move to the
207 * all registered buffers, allocated blocks, and unreferenced 216 * orphaned lists to avoid issues if a new process is created with the same pid.
208 * blocks. Any blocks/areas still referenced will move to the
209 * orphaned lists to avoid issues if a new process is created
210 * with the same pid.
211 *
212 * (must have mutex)
213 */ 217 */
214void _m_free_process_info(struct process_info *pi) 218static void _m_free_process_info(struct process_info *pi)
215{ 219{
216 struct gid_info *gi, *gi_; 220 struct gid_info *gi, *gi_;
217 struct __buf_info *_b = NULL, *_b_ = NULL; 221 struct __buf_info *_b = NULL, *_b_ = NULL;
218 222
223 /* have mutex */
224
219 /* unregister all buffers */ 225 /* unregister all buffers */
220 list_for_each_entry_safe(_b, _b_, &pi->bufs, by_pid) 226 list_for_each_entry_safe(_b, _b_, &pi->bufs, by_pid)
221 _m_unregister_buf(_b); 227 _m_unregister_buf(_b);
@@ -223,15 +229,15 @@ void _m_free_process_info(struct process_info *pi)
223 BUG_ON(!list_empty(&pi->bufs)); 229 BUG_ON(!list_empty(&pi->bufs));
224 230
225 /* free all allocated blocks, and remove unreferenced ones */ 231 /* free all allocated blocks, and remove unreferenced ones */
226 list_for_each_entry_safe(gi, gi_, &pi->groups, by_pid) { 232 list_for_each_entry_safe(gi, gi_, &pi->groups, by_pid)
227 ops->destroy_group(gi); 233 ops->destroy_group(gi);
228 }
229 234
230 BUG_ON(!list_empty(&pi->groups)); 235 BUG_ON(!list_empty(&pi->groups));
231 list_del(&pi->list); 236 list_del(&pi->list);
232 kfree(pi); 237 kfree(pi);
233} 238}
234 239
240/* Free all info kept by all processes. Called on cleanup. */
235static void destroy_processes(void) 241static void destroy_processes(void)
236{ 242{
237 struct process_info *pi, *pi_; 243 struct process_info *pi, *pi_;
@@ -250,9 +256,10 @@ static void destroy_processes(void)
250 * ========================================================================== 256 * ==========================================================================
251 */ 257 */
252 258
259/* mmap tiler buffer into user's virtual space */
253static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma) 260static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma)
254{ 261{
255 struct __buf_info *_b = NULL; 262 struct __buf_info *_b;
256 struct tiler_buf_info *b = NULL; 263 struct tiler_buf_info *b = NULL;
257 u32 i, map_offs, map_size, blk_offs, blk_size, mapped_size; 264 u32 i, map_offs, map_size, blk_offs, blk_size, mapped_size;
258 struct process_info *pi = filp->private_data; 265 struct process_info *pi = filp->private_data;
@@ -261,8 +268,10 @@ static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma)
261 268
262 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 269 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
263 270
271 /* find tiler buffer to mmap */
264 mutex_lock(&mtx); 272 mutex_lock(&mtx);
265 list_for_each_entry(_b, &pi->bufs, by_pid) { 273 list_for_each_entry(_b, &pi->bufs, by_pid) {
274 /* we support partial mmaping of a whole tiler buffer */
266 if (offs >= (_b->buf_info.offset & PAGE_MASK) && 275 if (offs >= (_b->buf_info.offset & PAGE_MASK) &&
267 offs + size <= PAGE_ALIGN(_b->buf_info.offset + 276 offs + size <= PAGE_ALIGN(_b->buf_info.offset +
268 _b->buf_info.length)) { 277 _b->buf_info.length)) {
@@ -271,44 +280,55 @@ static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma)
271 } 280 }
272 } 281 }
273 mutex_unlock(&mtx); 282 mutex_unlock(&mtx);
283
284 /* we use b to detect if we found the bufffer */
274 if (!b) 285 if (!b)
275 return -ENXIO; 286 return -ENXIO;
276 287
277 /* mmap relevant blocks */ 288 /* mmap relevant blocks */
278 blk_offs = _b->buf_info.offset; 289 blk_offs = _b->buf_info.offset;
290
291 /* start at the beginning of the region */
279 mapped_size = 0; 292 mapped_size = 0;
280 for (i = 0; i < b->num_blocks; i++, blk_offs += blk_size) { 293 for (i = 0; i < b->num_blocks; i++, blk_offs += blk_size) {
281 blk_size = tiler_size(&_b->mi[i]->blk); 294 blk_size = tiler_size(&_b->mi[i]->blk);
295 /* see if tiler block is inside the requested region */
282 if (offs >= blk_offs + blk_size || offs + size < blk_offs) 296 if (offs >= blk_offs + blk_size || offs + size < blk_offs)
283 continue; 297 continue;
298 /* get the offset and map size for this particular block */
284 map_offs = max(offs, blk_offs) - blk_offs; 299 map_offs = max(offs, blk_offs) - blk_offs;
285 map_size = min(size - mapped_size, blk_size); 300 map_size = min(size - mapped_size, blk_size);
301
302 /* mmap block */
286 if (tiler_mmap_blk(&_b->mi[i]->blk, map_offs, map_size, vma, 303 if (tiler_mmap_blk(&_b->mi[i]->blk, map_offs, map_size, vma,
287 mapped_size)) 304 mapped_size))
288 return -EAGAIN; 305 return -EAGAIN;
306
307 /* update mmap region pointer */
289 mapped_size += map_size; 308 mapped_size += map_size;
290 } 309 }
291 return 0; 310 return 0;
292} 311}
293 312
313/* ioctl handler */
294static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, 314static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
295 unsigned long arg) 315 unsigned long arg)
296{ 316{
297 pgd_t *pgd = NULL; 317 pgd_t *pgd;
298 pmd_t *pmd = NULL; 318 pmd_t *pmd;
299 pte_t *ptep = NULL, pte = 0x0; 319 pte_t *ptep, pte;
300 s32 r = -1; 320 s32 r;
321 void __user *data = (void __user *)arg;
301 struct process_info *pi = filp->private_data; 322 struct process_info *pi = filp->private_data;
302 323 struct __buf_info *_b;
303 struct __buf_info *_b = NULL;
304 struct tiler_buf_info buf_info = {0}; 324 struct tiler_buf_info buf_info = {0};
305 struct tiler_block_info block_info = {0}; 325 struct tiler_block_info block_info = {0};
306 struct mem_info *mi = NULL; 326 struct mem_info *mi;
307 327
308 switch (cmd) { 328 switch (cmd) {
329 /* allocate block */
309 case TILIOC_GBLK: 330 case TILIOC_GBLK:
310 if (copy_from_user(&block_info, (void __user *)arg, 331 if (copy_from_user(&block_info, data, sizeof(block_info)))
311 sizeof(block_info)))
312 return -EFAULT; 332 return -EFAULT;
313 333
314 switch (block_info.fmt) { 334 switch (block_info.fmt) {
@@ -317,8 +337,6 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
317 block_info.align, block_info.offs, 337 block_info.align, block_info.offs,
318 block_info.key, block_info.group_id, 338 block_info.key, block_info.group_id,
319 pi, &mi); 339 pi, &mi);
320 if (r)
321 return r;
322 break; 340 break;
323 case TILFMT_8BIT: 341 case TILFMT_8BIT:
324 case TILFMT_16BIT: 342 case TILFMT_16BIT:
@@ -329,45 +347,38 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
329 block_info.align, block_info.offs, 347 block_info.align, block_info.offs,
330 block_info.key, block_info.group_id, 348 block_info.key, block_info.group_id,
331 pi, &mi); 349 pi, &mi);
332 if (r)
333 return r;
334 break; 350 break;
335 default: 351 default:
336 return -EINVAL; 352 return -EINVAL;
337 } 353 }
354 if (r)
355 return r;
338 356
357 /* fill out block info */
339 if (mi) { 358 if (mi) {
340 block_info.id = mi->blk.id; 359 block_info.ptr = NULL;
341 block_info.stride = tiler_vstride(&mi->blk); 360 ops->describe(mi, &block_info);
342 block_info.offs = mi->blk.phys & ~PAGE_MASK;
343 block_info.align = PAGE_SIZE;
344#ifdef CONFIG_TILER_EXPOSE_SSPTR
345 block_info.ssptr = mi->blk.phys;
346#endif
347 } 361 }
348 if (copy_to_user((void __user *)arg, &block_info, 362
349 sizeof(block_info))) 363 if (copy_to_user(data, &block_info, sizeof(block_info)))
350 return -EFAULT; 364 return -EFAULT;
351 break; 365 break;
366 /* free/unmap block */
352 case TILIOC_FBLK: 367 case TILIOC_FBLK:
353 case TILIOC_UMBLK: 368 case TILIOC_UMBLK:
354 if (copy_from_user(&block_info, (void __user *)arg, 369 if (copy_from_user(&block_info, data, sizeof(block_info)))
355 sizeof(block_info)))
356 return -EFAULT; 370 return -EFAULT;
357 371
358 /* search current process first, then all processes */ 372 /* search current process first, then all processes */
359 mutex_lock(&mtx); 373 mutex_lock(&mtx);
360 mi = _m_lock_block(block_info.key, block_info.id, pi); 374 mi = _m_lock_block(block_info.key, block_info.id, pi);
361 mutex_unlock(&mtx); 375 mutex_unlock(&mtx);
362 if (mi) { 376 if (mi)
363 ops->unlock_free(mi, true); 377 ops->unlock_free(mi, true);
364 r = 0;
365 }
366 r = -EACCES;
367 378
368 /* free always succeeds */ 379 /* free always succeeds */
369 break; 380 break;
370 381 /* get physical address */
371 case TILIOC_GSSP: 382 case TILIOC_GSSP:
372 pgd = pgd_offset(current->mm, arg); 383 pgd = pgd_offset(current->mm, arg);
373 if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { 384 if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
@@ -382,12 +393,12 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
382 } 393 }
383 } 394 }
384 } 395 }
385 /* va not in page table */ 396 /* va not in page table, return NULL */
386 return 0x0; 397 return (s32) NULL;
387 break; 398 break;
399 /* map block */
388 case TILIOC_MBLK: 400 case TILIOC_MBLK:
389 if (copy_from_user(&block_info, (void __user *)arg, 401 if (copy_from_user(&block_info, data, sizeof(block_info)))
390 sizeof(block_info)))
391 return -EFAULT; 402 return -EFAULT;
392 403
393 if (!block_info.ptr) 404 if (!block_info.ptr)
@@ -399,30 +410,26 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
399 if (r) 410 if (r)
400 return r; 411 return r;
401 412
402 if (mi) { 413 /* fill out block info */
403 block_info.id = mi->blk.id; 414 if (mi)
404 block_info.stride = tiler_vstride(&mi->blk); 415 ops->describe(mi, &block_info);
405 block_info.offs = mi->blk.phys & ~PAGE_MASK; 416
406 block_info.align = PAGE_SIZE; 417 if (copy_to_user(data, &block_info, sizeof(block_info)))
407#ifdef CONFIG_TILER_EXPOSE_SSPTR
408 block_info.ssptr = mi->blk.phys;
409#endif
410 }
411 if (copy_to_user((void __user *)arg, &block_info,
412 sizeof(block_info)))
413 return -EFAULT; 418 return -EFAULT;
414 break; 419 break;
415#ifndef CONFIG_TILER_SECURE 420#ifndef CONFIG_TILER_SECURE
421 /* query buffer information by offset */
416 case TILIOC_QBUF: 422 case TILIOC_QBUF:
417 if (!offset_lookup) 423 if (!offset_lookup)
418 return -EPERM; 424 return -EPERM;
419 425
420 if (copy_from_user(&buf_info, (void __user *)arg, 426 if (copy_from_user(&buf_info, data, sizeof(buf_info)))
421 sizeof(buf_info)))
422 return -EFAULT; 427 return -EFAULT;
423 428
429 /* find buffer */
424 mutex_lock(&mtx); 430 mutex_lock(&mtx);
425 r = -ENOENT; 431 r = -ENOENT;
432 /* buffer registration is per process */
426 list_for_each_entry(_b, &pi->bufs, by_pid) { 433 list_for_each_entry(_b, &pi->bufs, by_pid) {
427 if (buf_info.offset == _b->buf_info.offset) { 434 if (buf_info.offset == _b->buf_info.offset) {
428 memcpy(&buf_info, &_b->buf_info, 435 memcpy(&buf_info, &_b->buf_info,
@@ -436,21 +443,21 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
436 if (r) 443 if (r)
437 return r; 444 return r;
438 445
439 if (copy_to_user((void __user *)arg, &_b->buf_info, 446 if (copy_to_user(data, &_b->buf_info, sizeof(_b->buf_info)))
440 sizeof(_b->buf_info)))
441 return -EFAULT; 447 return -EFAULT;
442 break; 448 break;
443#endif 449#endif
450 /* register buffer */
444 case TILIOC_RBUF: 451 case TILIOC_RBUF:
452 /* save buffer information */
445 _b = kmalloc(sizeof(*_b), GFP_KERNEL); 453 _b = kmalloc(sizeof(*_b), GFP_KERNEL);
446 if (!_b) 454 if (!_b)
447 return -ENOMEM; 455 return -ENOMEM;
456 memset(_b, 0, sizeof(*_b));
448 457
449 memset(_b, 0x0, sizeof(*_b)); 458 if (copy_from_user(&_b->buf_info, data, sizeof(_b->buf_info))) {
450 459 kfree(_b);
451 if (copy_from_user(&_b->buf_info, (void __user *)arg, 460 return -EFAULT;
452 sizeof(_b->buf_info))) {
453 kfree(_b); return -EFAULT;
454 } 461 }
455 462
456 mutex_lock(&mtx); 463 mutex_lock(&mtx);
@@ -458,28 +465,31 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
458 mutex_unlock(&mtx); 465 mutex_unlock(&mtx);
459 466
460 if (r) { 467 if (r) {
461 kfree(_b); return -EACCES; 468 kfree(_b);
469 return -EACCES;
462 } 470 }
463 471
464 if (copy_to_user((void __user *)arg, &_b->buf_info, 472 /* undu registration on failure */
465 sizeof(_b->buf_info))) { 473 if (copy_to_user(data, &_b->buf_info, sizeof(_b->buf_info))) {
466 mutex_lock(&mtx); 474 mutex_lock(&mtx);
467 _m_unregister_buf(_b); 475 _m_unregister_buf(_b);
468 mutex_unlock(&mtx); 476 mutex_unlock(&mtx);
469 return -EFAULT; 477 return -EFAULT;
470 } 478 }
471 break; 479 break;
480 /* unregister a buffer */
472 case TILIOC_URBUF: 481 case TILIOC_URBUF:
473 if (copy_from_user(&buf_info, (void __user *)arg, 482 if (copy_from_user(&buf_info, data, sizeof(buf_info)))
474 sizeof(buf_info)))
475 return -EFAULT; 483 return -EFAULT;
476 484
485 /* find buffer */
477 r = -EFAULT; 486 r = -EFAULT;
478 mutex_lock(&mtx); 487 mutex_lock(&mtx);
479 /* buffer registration is per process */ 488 /* buffer registration is per process */
480 list_for_each_entry(_b, &pi->bufs, by_pid) { 489 list_for_each_entry(_b, &pi->bufs, by_pid) {
481 if (buf_info.offset == _b->buf_info.offset) { 490 if (buf_info.offset == _b->buf_info.offset) {
482 _m_unregister_buf(_b); 491 _m_unregister_buf(_b);
492 /* only retrieve buffer length */
483 buf_info.length = _b->buf_info.length; 493 buf_info.length = _b->buf_info.length;
484 r = 0; 494 r = 0;
485 break; 495 break;
@@ -487,25 +497,25 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
487 } 497 }
488 mutex_unlock(&mtx); 498 mutex_unlock(&mtx);
489 499
490 if (copy_to_user((void __user *)arg, &buf_info, 500 if (r)
491 sizeof(_b->buf_info))) 501 return r;
492 return -EFAULT;
493 502
494 return r; 503 if (copy_to_user(data, &buf_info, sizeof(_b->buf_info)))
504 return -EFAULT;
495 break; 505 break;
506 /* prereserv blocks */
496 case TILIOC_PRBLK: 507 case TILIOC_PRBLK:
497 if (copy_from_user(&block_info, (void __user *)arg, 508 if (copy_from_user(&block_info, data, sizeof(block_info)))
498 sizeof(block_info)))
499 return -EFAULT; 509 return -EFAULT;
500 510
501 if (block_info.fmt == TILFMT_8AND16) { 511 if (block_info.fmt == TILFMT_8AND16)
502 ops->reserve_nv12(block_info.key, 512 ops->reserve_nv12(block_info.key,
503 block_info.dim.area.width, 513 block_info.dim.area.width,
504 block_info.dim.area.height, 514 block_info.dim.area.height,
505 block_info.align, 515 block_info.align,
506 block_info.offs, 516 block_info.offs,
507 block_info.group_id, pi); 517 block_info.group_id, pi);
508 } else { 518 else
509 ops->reserve(block_info.key, 519 ops->reserve(block_info.key,
510 block_info.fmt, 520 block_info.fmt,
511 block_info.dim.area.width, 521 block_info.dim.area.width,
@@ -513,14 +523,14 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
513 block_info.align, 523 block_info.align,
514 block_info.offs, 524 block_info.offs,
515 block_info.group_id, pi); 525 block_info.group_id, pi);
516 }
517 break; 526 break;
527 /* unreserve blocks */
518 case TILIOC_URBLK: 528 case TILIOC_URBLK:
519 ops->unreserve(arg, pi); 529 ops->unreserve(arg, pi);
520 break; 530 break;
531 /* query a tiler block */
521 case TILIOC_QBLK: 532 case TILIOC_QBLK:
522 if (copy_from_user(&block_info, (void __user *)arg, 533 if (copy_from_user(&block_info, data, sizeof(block_info)))
523 sizeof(block_info)))
524 return -EFAULT; 534 return -EFAULT;
525 535
526 if (block_info.id) { 536 if (block_info.id) {
@@ -537,24 +547,26 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd,
537#endif 547#endif
538 return -EPERM; 548 return -EPERM;
539 549
540 if (mi) {
541 ops->describe(mi, &block_info);
542 ops->unlock_free(mi, false);
543 }
544
545 if (!mi) 550 if (!mi)
546 return -EFAULT; 551 return -EFAULT;
547 552
548 if (copy_to_user((void __user *)arg, &block_info, 553 /* we don't keep track of ptr and 1D stride so clear them */
549 sizeof(block_info))) 554 block_info.ptr = NULL;
555 block_info.stride = 0;
556
557 ops->describe(mi, &block_info);
558 ops->unlock_free(mi, false);
559
560 if (copy_to_user(data, &block_info, sizeof(block_info)))
550 return -EFAULT; 561 return -EFAULT;
551 break; 562 break;
552 default: 563 default:
553 return -EINVAL; 564 return -EINVAL;
554 } 565 }
555 return 0x0; 566 return 0;
556} 567}
557 568
569/* open tiler driver */
558static s32 tiler_open(struct inode *ip, struct file *filp) 570static s32 tiler_open(struct inode *ip, struct file *filp)
559{ 571{
560 struct process_info *pi = __get_pi(current->tgid, false); 572 struct process_info *pi = __get_pi(current->tgid, false);
@@ -562,9 +574,10 @@ static s32 tiler_open(struct inode *ip, struct file *filp)
562 return -ENOMEM; 574 return -ENOMEM;
563 575
564 filp->private_data = pi; 576 filp->private_data = pi;
565 return 0x0; 577 return 0;
566} 578}
567 579
580/* close tiler driver */
568static s32 tiler_release(struct inode *ip, struct file *filp) 581static s32 tiler_release(struct inode *ip, struct file *filp)
569{ 582{
570 struct process_info *pi = filp->private_data; 583 struct process_info *pi = filp->private_data;
@@ -576,16 +589,18 @@ static s32 tiler_release(struct inode *ip, struct file *filp)
576 589
577 mutex_unlock(&mtx); 590 mutex_unlock(&mtx);
578 591
579 return 0x0; 592 return 0;
580} 593}
581 594
582const struct file_operations tiler_fops = { 595/* tiler driver file operations */
596static const struct file_operations tiler_fops = {
583 .open = tiler_open, 597 .open = tiler_open,
584 .ioctl = tiler_ioctl, 598 .ioctl = tiler_ioctl,
585 .release = tiler_release, 599 .release = tiler_release,
586 .mmap = tiler_mmap, 600 .mmap = tiler_mmap,
587}; 601};
588 602
603/* initialize tiler interface */
589void tiler_iface_init(struct tiler_ops *tiler) 604void tiler_iface_init(struct tiler_ops *tiler)
590{ 605{
591 ops = tiler; 606 ops = tiler;
@@ -606,41 +621,36 @@ void tiler_iface_init(struct tiler_ops *tiler)
606 * ========================================================================== 621 * ==========================================================================
607 */ 622 */
608 623
609s32 tiler_reservex(u32 n, enum tiler_fmt fmt, u32 width, u32 height, 624void tiler_reservex(u32 n, enum tiler_fmt fmt, u32 width, u32 height,
610 u32 align, u32 offs, u32 gid, pid_t pid) 625 u32 align, u32 offs, u32 gid, pid_t pid)
611{ 626{
612 struct process_info *pi = __get_pi(pid, true); 627 struct process_info *pi = __get_pi(pid, true);
613 628
614 if (pi) 629 if (pi)
615 ops->reserve(n, fmt, width, height, align, offs, gid, pi); 630 ops->reserve(n, fmt, width, height, align, offs, gid, pi);
616 return 0;
617} 631}
618EXPORT_SYMBOL(tiler_reservex); 632EXPORT_SYMBOL(tiler_reservex);
619 633
620s32 tiler_reserve(u32 n, enum tiler_fmt fmt, u32 width, u32 height, 634void tiler_reserve(u32 n, enum tiler_fmt fmt, u32 width, u32 height,
621 u32 align, u32 offs) 635 u32 align, u32 offs)
622{ 636{
623 return tiler_reservex(n, fmt, width, height, align, offs, 637 tiler_reservex(n, fmt, width, height, align, offs, 0, current->tgid);
624 0, current->tgid);
625} 638}
626EXPORT_SYMBOL(tiler_reserve); 639EXPORT_SYMBOL(tiler_reserve);
627 640
628/* reserve area for n identical buffers */ 641void tiler_reservex_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs,
629s32 tiler_reservex_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs,
630 u32 gid, pid_t pid) 642 u32 gid, pid_t pid)
631{ 643{
632 struct process_info *pi = __get_pi(pid, true); 644 struct process_info *pi = __get_pi(pid, true);
633 645
634 if (pi) 646 if (pi)
635 ops->reserve_nv12(n, width, height, align, offs, gid, pi); 647 ops->reserve_nv12(n, width, height, align, offs, gid, pi);
636 return 0;
637} 648}
638EXPORT_SYMBOL(tiler_reservex_nv12); 649EXPORT_SYMBOL(tiler_reservex_nv12);
639 650
640s32 tiler_reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs) 651void tiler_reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs)
641{ 652{
642 return tiler_reservex_nv12(n, width, height, align, offs, 653 tiler_reservex_nv12(n, width, height, align, offs, 0, current->tgid);
643 0, current->tgid);
644} 654}
645EXPORT_SYMBOL(tiler_reserve_nv12); 655EXPORT_SYMBOL(tiler_reserve_nv12);
646 656
@@ -651,8 +661,7 @@ s32 tiler_allocx(struct tiler_block_t *blk, enum tiler_fmt fmt,
651 struct process_info *pi; 661 struct process_info *pi;
652 s32 res; 662 s32 res;
653 663
654 if (!blk || blk->phys) 664 BUG_ON(!blk || blk->phys);
655 BUG();
656 665
657 pi = __get_pi(pid, true); 666 pi = __get_pi(pid, true);
658 if (!pi) 667 if (!pi)
@@ -682,8 +691,7 @@ s32 tiler_mapx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 gid,
682 struct process_info *pi; 691 struct process_info *pi;
683 s32 res; 692 s32 res;
684 693
685 if (!blk || blk->phys) 694 BUG_ON(!blk || blk->phys);
686 BUG();
687 695
688 pi = __get_pi(pid, true); 696 pi = __get_pi(pid, true);
689 if (!pi) 697 if (!pi)
@@ -709,22 +717,18 @@ EXPORT_SYMBOL(tiler_map);
709s32 tiler_mmap_blk(struct tiler_block_t *blk, u32 offs, u32 size, 717s32 tiler_mmap_blk(struct tiler_block_t *blk, u32 offs, u32 size,
710 struct vm_area_struct *vma, u32 voffs) 718 struct vm_area_struct *vma, u32 voffs)
711{ 719{
712 u32 v, p; 720 u32 v, p, len;
713 u32 len; /* area to map */
714 721
715 /* don't allow mremap */ 722 /* don't allow mremap */
716 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; 723 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
717 724
718 /* mapping must fit into vma */ 725 /* mapping must fit into vma */
719 if (vma->vm_start > vma->vm_start + voffs || 726 BUG_ON(vma->vm_start > vma->vm_start + voffs ||
720 vma->vm_start + voffs > vma->vm_start + voffs + size || 727 vma->vm_start + voffs > vma->vm_start + voffs + size ||
721 vma->vm_start + voffs + size > vma->vm_end) 728 vma->vm_start + voffs + size > vma->vm_end);
722 BUG();
723 729
724 /* mapping must fit into block */ 730 /* mapping must fit into block */
725 if (offs > offs + size || 731 BUG_ON(offs > offs + size || offs + size > tiler_size(blk));
726 offs + size > tiler_size(blk))
727 BUG();
728 732
729 v = tiler_vstride(blk); 733 v = tiler_vstride(blk);
730 p = tiler_pstride(blk); 734 p = tiler_pstride(blk);
@@ -732,6 +736,7 @@ s32 tiler_mmap_blk(struct tiler_block_t *blk, u32 offs, u32 size,
732 /* remap block portion */ 736 /* remap block portion */
733 len = v - (offs % v); /* initial area to map */ 737 len = v - (offs % v); /* initial area to map */
734 while (size) { 738 while (size) {
739 /* restrict to size still needs mapping */
735 if (len > size) 740 if (len > size)
736 len = size; 741 len = size;
737 742
@@ -756,13 +761,10 @@ s32 tiler_ioremap_blk(struct tiler_block_t *blk, u32 offs, u32 size,
756 const struct mem_type *type = get_mem_type(mtype); 761 const struct mem_type *type = get_mem_type(mtype);
757 762
758 /* mapping must fit into address space */ 763 /* mapping must fit into address space */
759 if (addr > addr + size) 764 BUG_ON(addr > addr + size);
760 BUG();
761 765
762 /* mapping must fit into block */ 766 /* mapping must fit into block */
763 if (offs > offs + size || 767 BUG_ON(offs > offs + size || offs + size > tiler_size(blk));
764 offs + size > tiler_size(blk))
765 BUG();
766 768
767 v = tiler_vstride(blk); 769 v = tiler_vstride(blk);
768 p = tiler_pstride(blk); 770 p = tiler_pstride(blk);
diff --git a/drivers/media/video/tiler/tiler-main.c b/drivers/media/video/tiler/tiler-main.c
index c755567edd5..19e838f9ec3 100644
--- a/drivers/media/video/tiler/tiler-main.c
+++ b/drivers/media/video/tiler/tiler-main.c
@@ -1,7 +1,10 @@
1/* 1/*
2 * tiler-main.c 2 * tiler-main.c
3 * 3 *
4 * TILER driver support functions for TI OMAP processors. 4 * TILER driver main support functions for TI TILER hardware block.
5 *
6 * Authors: Lajos Molnar <molnar@ti.com>
7 * David Sin <davidsin@ti.com>
5 * 8 *
6 * Copyright (C) 2009-2010 Texas Instruments, Inc. 9 * Copyright (C) 2009-2010 Texas Instruments, Inc.
7 * 10 *
@@ -16,39 +19,39 @@
16 19
17#include <linux/init.h> 20#include <linux/init.h>
18#include <linux/module.h> 21#include <linux/module.h>
19#include <linux/cdev.h> /* struct cdev */ 22#include <linux/cdev.h> /* struct cdev */
20#include <linux/kdev_t.h> /* MKDEV() */ 23#include <linux/kdev_t.h> /* MKDEV() */
21#include <linux/fs.h> /* register_chrdev_region() */ 24#include <linux/fs.h> /* register_chrdev_region() */
22#include <linux/device.h> /* struct class */ 25#include <linux/device.h> /* struct class */
23#include <linux/platform_device.h> /* platform_device() */ 26#include <linux/platform_device.h> /* platform_device() */
24#include <linux/err.h> /* IS_ERR() */ 27#include <linux/err.h> /* IS_ERR() */
25/* #include <linux/sched.h> */
26#include <linux/errno.h> 28#include <linux/errno.h>
27#include <linux/mutex.h> 29#include <linux/mutex.h>
28#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h> /* dma_alloc_coherent */
29#include <linux/pagemap.h> /* page_cache_release() */ 31#include <linux/pagemap.h> /* page_cache_release() */
30#include <linux/slab.h> 32#include <linux/slab.h>
31 33
32#include <mach/dmm.h> 34#include <mach/dmm.h>
33#include "tmm.h" 35#include "tmm.h"
34#include "_tiler.h" 36#include "_tiler.h"
35#include "tcm/tcm-sita.h" /* Algo Specific header */ 37#include "tcm/tcm-sita.h" /* TCM algorithm */
36
37#include <linux/syscalls.h>
38 38
39static bool ssptr_id = CONFIG_TILER_SSPTR_ID; 39static bool ssptr_id = CONFIG_TILER_SSPTR_ID;
40static uint default_align = CONFIG_TILER_ALIGNMENT; 40static uint default_align = CONFIG_TILER_ALIGNMENT;
41static uint granularity = CONFIG_TILER_GRANULARITY; 41static uint granularity = CONFIG_TILER_GRANULARITY;
42 42
43module_param(ssptr_id, bool, 0644); 43/*
44 * We can only change ssptr_id if there are no blocks allocated, so that
45 * pseudo-random ids and ssptrs do not potentially clash. For now make it
46 * read-only.
47 */
48module_param(ssptr_id, bool, 0444);
44MODULE_PARM_DESC(ssptr_id, "Use ssptr as block ID"); 49MODULE_PARM_DESC(ssptr_id, "Use ssptr as block ID");
45module_param_named(align, default_align, uint, 0644); 50module_param_named(align, default_align, uint, 0644);
46MODULE_PARM_DESC(align, "Default block ssptr alignment"); 51MODULE_PARM_DESC(align, "Default block ssptr alignment");
47module_param_named(grain, granularity, uint, 0644); 52module_param_named(grain, granularity, uint, 0644);
48MODULE_PARM_DESC(grain, "Granularity (bytes)"); 53MODULE_PARM_DESC(grain, "Granularity (bytes)");
49 54
50struct tiler_ops tiler;
51
52struct tiler_dev { 55struct tiler_dev {
53 struct cdev cdev; 56 struct cdev cdev;
54}; 57};
@@ -63,9 +66,11 @@ struct platform_driver tiler_driver_ldm = {
63 .remove = NULL, 66 .remove = NULL,
64}; 67};
65 68
66static struct list_head blocks; 69static struct tiler_ops tiler; /* shared methods and variables */
67static struct list_head orphan_areas; 70
68static struct list_head orphan_onedim; 71static struct list_head blocks; /* all tiler blocks */
72static struct list_head orphan_areas; /* orphaned 2D areas */
73static struct list_head orphan_onedim; /* orphaned 1D areas */
69 74
70static s32 tiler_major; 75static s32 tiler_major;
71static s32 tiler_minor; 76static s32 tiler_minor;
@@ -81,6 +86,7 @@ static dma_addr_t dmac_pa;
81 * TMM connectors 86 * TMM connectors
82 * ========================================================================== 87 * ==========================================================================
83 */ 88 */
89/* wrapper around tmm_map */
84static s32 refill_pat(struct tmm *tmm, struct tcm_area *area, u32 *ptr) 90static s32 refill_pat(struct tmm *tmm, struct tcm_area *area, u32 *ptr)
85{ 91{
86 s32 res = 0; 92 s32 res = 0;
@@ -105,6 +111,7 @@ static s32 refill_pat(struct tmm *tmm, struct tcm_area *area, u32 *ptr)
105 return res; 111 return res;
106} 112}
107 113
114/* wrapper around tmm_clear */
108static void clear_pat(struct tmm *tmm, struct tcm_area *area) 115static void clear_pat(struct tmm *tmm, struct tcm_area *area)
109{ 116{
110 struct pat_area p_area = {0}; 117 struct pat_area p_area = {0};
@@ -142,6 +149,8 @@ static u32 _m_get_id(void)
142 149
143 /* ensure noone is using this id */ 150 /* ensure noone is using this id */
144 while (_m_id_in_use(id)) { 151 while (_m_id_in_use(id)) {
152 /* generate a new pseudo-random ID */
153
145 /* Galois LSFR: 32, 22, 2, 1 */ 154 /* Galois LSFR: 32, 22, 2, 1 */
146 id = (id >> 1) ^ (u32)((0 - (id & 1u)) & 0x80200003u); 155 id = (id >> 1) ^ (u32)((0 - (id & 1u)) & 0x80200003u);
147 } 156 }
@@ -154,11 +163,13 @@ static u32 _m_get_id(void)
154 * ========================================================================== 163 * ==========================================================================
155 */ 164 */
156 165
157/* must have mutex */ 166/* get or create new gid_info object */
158static struct gid_info *_m_get_gi(struct process_info *pi, u32 gid) 167static struct gid_info *_m_get_gi(struct process_info *pi, u32 gid)
159{ 168{
160 struct gid_info *gi; 169 struct gid_info *gi;
161 170
171 /* have mutex */
172
162 /* see if group already exist */ 173 /* see if group already exist */
163 list_for_each_entry(gi, &pi->groups, by_pid) { 174 list_for_each_entry(gi, &pi->groups, by_pid) {
164 if (gi->gid == gid) 175 if (gi->gid == gid)
@@ -186,9 +197,10 @@ done:
186 return gi; 197 return gi;
187} 198}
188 199
189/* (must have mutex) */ 200/* free gid_info object if empty */
190static void _m_try_free_group(struct gid_info *gi) 201static void _m_try_free_group(struct gid_info *gi)
191{ 202{
203 /* have mutex */
192 if (gi && list_empty(&gi->areas) && list_empty(&gi->onedim) && 204 if (gi && list_empty(&gi->areas) && list_empty(&gi->onedim) &&
193 /* also ensure noone is still using this group */ 205 /* also ensure noone is still using this group */
194 !gi->refs) { 206 !gi->refs) {
@@ -277,11 +289,11 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height,
277 289
278 /* width and height must be positive */ 290 /* width and height must be positive */
279 if (!width || !height) 291 if (!width || !height)
280 return -1; 292 return -EINVAL;
281 293
282 /* align must be 2 power */ 294 /* align must be 2 power */
283 if (*align & (*align - 1)) 295 if (*align & (*align - 1))
284 return -1; 296 return -EINVAL;
285 297
286 if (fmt == TILFMT_PAGE) { 298 if (fmt == TILFMT_PAGE) {
287 /* adjust size to accomodate offset, only do page alignment */ 299 /* adjust size to accomodate offset, only do page alignment */
@@ -294,7 +306,7 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height,
294 *y_area = *band = 1; 306 *y_area = *band = 1;
295 307
296 if (*x_area * *y_area > tiler.width * tiler.height) 308 if (*x_area * *y_area > tiler.width * tiler.height)
297 return -1; 309 return -ENOMEM;
298 return 0; 310 return 0;
299 } 311 }
300 312
@@ -310,9 +322,13 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height,
310 *band = PAGE_SIZE / slot_row; 322 *band = PAGE_SIZE / slot_row;
311 323
312 /* minimum alignment is at least 1 slot. Use default if needed */ 324 /* minimum alignment is at least 1 slot. Use default if needed */
313 min_align = MAX(slot_row, granularity); 325 min_align = max(slot_row, granularity);
314 *align = ALIGN(*align ? : default_align, min_align); 326 *align = ALIGN(*align ? : default_align, min_align);
315 327
328 /* align must still be 2 power (in case default_align is wrong) */
329 if (*align & (*align - 1))
330 return -EAGAIN;
331
316 /* offset must be multiple of bpp */ 332 /* offset must be multiple of bpp */
317 if (*offs & (g->bpp - 1) || *offs >= *align) 333 if (*offs & (g->bpp - 1) || *offs >= *align)
318 return -EINVAL; 334 return -EINVAL;
@@ -334,8 +350,8 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height,
334 *offs /= slot_row; 350 *offs /= slot_row;
335 351
336 if (*x_area > tiler.width || *y_area > tiler.height) 352 if (*x_area > tiler.width || *y_area > tiler.height)
337 return -1; 353 return -ENOMEM;
338 return 0x0; 354 return 0;
339} 355}
340 356
341/** 357/**
@@ -811,13 +827,12 @@ found:
811/* find a block by ssptr */ 827/* find a block by ssptr */
812static void fill_block_info(struct mem_info *i, struct tiler_block_info *blk) 828static void fill_block_info(struct mem_info *i, struct tiler_block_info *blk)
813{ 829{
814 blk->ptr = NULL;
815 blk->fmt = tiler_fmt(i->blk.phys); 830 blk->fmt = tiler_fmt(i->blk.phys);
831#ifdef CONFIG_TILER_EXPOSE_SSPTR
816 blk->ssptr = i->blk.phys; 832 blk->ssptr = i->blk.phys;
817 833#endif
818 if (blk->fmt == TILFMT_PAGE) { 834 if (blk->fmt == TILFMT_PAGE) {
819 blk->dim.len = i->blk.width; 835 blk->dim.len = i->blk.width;
820 blk->stride = 0;
821 blk->group_id = ((struct gid_info *) i->parent)->gid; 836 blk->group_id = ((struct gid_info *) i->parent)->gid;
822 } else { 837 } else {
823 blk->stride = tiler_vstride(&i->blk); 838 blk->stride = tiler_vstride(&i->blk);
@@ -1248,7 +1263,7 @@ static void __exit tiler_exit(void)
1248} 1263}
1249 1264
1250MODULE_LICENSE("GPL v2"); 1265MODULE_LICENSE("GPL v2");
1251MODULE_AUTHOR("David Sin <davidsin@ti.com>");
1252MODULE_AUTHOR("Lajos Molnar <molnar@ti.com>"); 1266MODULE_AUTHOR("Lajos Molnar <molnar@ti.com>");
1267MODULE_AUTHOR("David Sin <davidsin@ti.com>");
1253module_init(tiler_init); 1268module_init(tiler_init);
1254module_exit(tiler_exit); 1269module_exit(tiler_exit);
diff --git a/drivers/media/video/tiler/tmm-pat.c b/drivers/media/video/tiler/tmm-pat.c
index bfef67cbe39..d33866b125e 100644
--- a/drivers/media/video/tiler/tmm-pat.c
+++ b/drivers/media/video/tiler/tmm-pat.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * tmm-pat.c 2 * tmm-pat.c
3 * 3 *
4 * DMM driver support functions for TI OMAP processors. 4 * DMM driver support functions for TI TILER hardware block.
5 * 5 *
6 * Author: Lajos Molnar <molnar@ti.com>, David Sin <dsin@ti.com> 6 * Author: Lajos Molnar <molnar@ti.com>, David Sin <dsin@ti.com>
7 * 7 *
diff --git a/drivers/media/video/tiler/tmm.h b/drivers/media/video/tiler/tmm.h
index 31470b3e44d..fbdc1e23d0e 100644
--- a/drivers/media/video/tiler/tmm.h
+++ b/drivers/media/video/tiler/tmm.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * tmm.h 2 * tmm.h
3 * 3 *
4 * TMM interface definition for TI TILER. 4 * TMM interface definition for TI TILER driver.
5 * 5 *
6 * Author: Lajos Molnar <molnar@ti.com> 6 * Author: Lajos Molnar <molnar@ti.com>
7 * 7 *