1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
|
/*
* tiler.h
*
* TILER driver support functions for TI TILER hardware block.
*
* Authors: Lajos Molnar <molnar@ti.com>
* David Sin <davidsin@ti.com>
*
* Copyright (C) 2009-2011 Texas Instruments, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TILER_H
#define TILER_H
#include <linux/mm.h>
/*
* ----------------------------- API Definitions -----------------------------
*/
/* return true if physical address is in the tiler container */
bool is_tiler_addr(u32 phys);
enum tiler_fmt {
TILFMT_MIN = -2,
TILFMT_INVALID = -2,
TILFMT_NONE = -1,
TILFMT_8BIT = 0,
TILFMT_16BIT = 1,
TILFMT_32BIT = 2,
TILFMT_PAGE = 3,
TILFMT_MAX = 3,
TILFMT_8AND16 = 4, /* used to mark NV12 reserve block */
};
/* tiler block info */
struct tiler_block_t {
u32 phys; /* system space (L3) tiler addr */
u32 width; /* width */
u32 height; /* height */
u32 key; /* secret key */
u32 id; /* unique block ID */
};
/* tiler (image/video frame) view */
struct tiler_view_t {
u32 tsptr; /* tiler space addr */
u32 width; /* width */
u32 height; /* height */
u32 bpp; /* bytes per pixel */
s32 h_inc; /* horizontal increment */
s32 v_inc; /* vertical increment */
};
/* get the tiler format for a physical address or TILFMT_INVALID */
enum tiler_fmt tiler_fmt(u32 phys);
/* get the modified (1 for page mode) bytes-per-pixel for a tiler block */
u32 tiler_bpp(const struct tiler_block_t *b);
/* get tiler block physical stride */
u32 tiler_pstride(const struct tiler_block_t *b);
/* get tiler block virtual stride */
static inline u32 tiler_vstride(const struct tiler_block_t *b)
{
return PAGE_ALIGN((b->phys & ~PAGE_MASK) + tiler_bpp(b) * b->width);
}
/* returns the virtual size of the block (for mmap) */
static inline u32 tiler_size(const struct tiler_block_t *b)
{
return b->height * tiler_vstride(b);
}
/* Event types */
#define TILER_DEVICE_CLOSE 0
/**
* Registers a notifier block with TILER driver.
*
* @param nb notifier_block
*
* @return error status
*/
s32 tiler_reg_notifier(struct notifier_block *nb);
/**
* Un-registers a notifier block with TILER driver.
*
* @param nb notifier_block
*
* @return error status
*/
s32 tiler_unreg_notifier(struct notifier_block *nb);
/**
* Get the physical address for a given user va.
*
* @param usr user virtual address
*
* @return valid pa or 0 for error
*/
u32 tiler_virt2phys(u32 usr);
/**
* Reserves a 1D or 2D TILER block area and memory for the
* current process with group ID 0.
*
* @param blk pointer to tiler block data. This must be set up ('phys' member
* must be 0) with the tiler block information. 'height' must be 1
* for 1D block.
* @param fmt TILER block format
* @param align block alignment (default: normally PAGE_SIZE)
* @param offs block offset
*
* @return error status
*/
s32 tiler_alloc(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 align,
u32 offs);
/**
* Reserves a 1D or 2D TILER block area and memory for a set process and group
* ID.
*
* @param blk pointer to tiler block data. This must be set up ('phys' member
* must be 0) with the tiler block information. 'height' must be 1
* for 1D block.
* @param fmt TILER block format
* @param align block alignment (default: normally PAGE_SIZE)
* @param offs block offset
* @param gid group ID
* @param pid process ID
*
* @return error status
*/
s32 tiler_allocx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 align,
u32 offs, u32 gid, pid_t pid);
/**
* Mmaps a portion of a tiler block to a virtual address. Use this method in
* your driver's mmap function to potentially combine multiple tiler blocks as
* one virtual buffer.
*
* @param blk pointer to tiler block data
* @param offs offset from where to map (must be page aligned)
* @param size size of area to map (must be page aligned)
* @param vma VMM memory area to map to
* @param voffs offset (from vm_start) in the VMM memory area to start
* mapping at
*
* @return error status
*/
s32 tiler_mmap_blk(struct tiler_block_t *blk, u32 offs, u32 size,
struct vm_area_struct *vma, u32 voffs);
/**
* Ioremaps a portion of a tiler block. Use this method in your driver instead
* of ioremap to potentially combine multiple tiler blocks as one virtual
* buffer.
*
* @param blk pointer to tiler block data
* @param offs offset from where to map (must be page aligned)
* @param size size of area to map (must be page aligned)
* @param addr virtual address
* @param mtype ioremap memory type (e.g. MT_DEVICE)
*
* @return error status
*/
s32 tiler_ioremap_blk(struct tiler_block_t *blk, u32 offs, u32 size, u32 addr,
u32 mtype);
/**
* Maps an existing buffer to a 1D or 2D TILER area for the
* current process with group ID 0.
*
* Currently, only 1D area mapping is supported.
*
* NOTE: alignment is always PAGE_SIZE and offset is 0 as full pages are mapped
* into tiler container.
*
* @param blk pointer to tiler block data. This must be set up
* ('phys' member must be 0) with the tiler block
* information. 'height' must be 1 for 1D block.
* @param fmt TILER format
* @param usr_addr user space address of existing buffer.
*
* @return error status
*/
s32 tiler_map(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 usr_addr);
/**
* Maps an existing buffer to a 1D or 2D TILER area for a set process and group
* ID.
*
* Currently, only 1D area mapping is supported.
*
* NOTE: alignment is always PAGE_SIZE and offset is 0 as full pages are mapped
* into tiler container.
*
* @param blk pointer to tiler block data. This must be set up
* ('phys' member must be 0) with the tiler block
* information. 'height' must be 1 for 1D block.
* @param fmt TILER format
* @param gid group ID
* @param pid process ID
* @param usr_addr user space address of existing buffer.
*
* @return error status
*/
s32 tiler_mapx(struct tiler_block_t *blk, enum tiler_fmt fmt,
u32 gid, pid_t pid, u32 usr_addr);
/**
* Frees TILER memory. Since there may be multiple references for the same area
* if duplicated by tiler_dup, the area is only actually freed if all references
* have been freed.
*
* @param blk pointer to a tiler block data as filled by tiler_alloc,
* tiler_map or tiler_dup. 'phys' and 'id' members will be set to
* 0 on success.
*/
void tiler_free(struct tiler_block_t *blk);
/**
* Reserves tiler area for n identical blocks for the current process. Use this
* method to get optimal placement of multiple identical tiler blocks; however,
* it may not reserve area if tiler_alloc is equally efficient.
*
* @param n number of identical set of blocks
* @param fmt TILER format
* @param width block width
* @param height block height (must be 1 for 1D)
* @param align block alignment (default: PAGE_SIZE)
* @param offs block offset
*/
void tiler_reserve(u32 n, enum tiler_fmt fmt, u32 width, u32 height, u32 align,
u32 offs);
/**
* Reserves tiler area for n identical blocks. Use this method to get optimal
* placement of multiple identical tiler blocks; however, it may not reserve
* area if tiler_alloc is equally efficient.
*
* @param n number of identical set of blocks
* @param fmt TILER bit mode
* @param width block width
* @param height block height (must be 1 for 1D)
* @param align block alignment (default: PAGE_SIZE)
* @param offs block offset
* @param gid group ID
* @param pid process ID
*/
void tiler_reservex(u32 n, enum tiler_fmt fmt, u32 width, u32 height,
u32 align, u32 offs, u32 gid, pid_t pid);
/**
* Reserves tiler area for n identical NV12 blocks for the current process. Use
* this method to get optimal placement of multiple identical NV12 tiler blocks;
* however, it may not reserve area if tiler_alloc is equally efficient.
*
* @param n number of identical set of blocks
* @param width block width (Y)
* @param height block height (Y)
* @param align block alignment (default: PAGE_SIZE)
* @param offs block offset
*/
void tiler_reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs);
/**
* Reserves tiler area for n identical NV12 blocks. Use this method to get
* optimal placement of multiple identical NV12 tiler blocks; however, it may
* not reserve area if tiler_alloc is equally efficient.
*
* @param n number of identical set of blocks
* @param width block width (Y)
* @param height block height (Y)
* @param align block alignment (default: PAGE_SIZE)
* @param offs block offset
* @param gid group ID
* @param pid process ID
*/
void tiler_reservex_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs,
u32 gid, pid_t pid);
/**
* Create a view based on a tiler address and width and height
*
* This method should only be used as a last resort, e.g. if tilview object
* cannot be passed because of incoherence with other view 2D objects that must
* be supported.
*
* @param view Pointer to a view where the information will be stored
* @param ssptr MUST BE a tiler address
* @param width view width
* @param height view height
*/
void tilview_create(struct tiler_view_t *view, u32 phys, u32 width, u32 height);
/**
* Obtains the view information for a tiler block
*
* @param view Pointer to a view where the information will be stored
* @param blk Pointer to an existing allocated tiler block
*/
void tilview_get(struct tiler_view_t *view, struct tiler_block_t *blk);
/**
* Crops a tiler view to a rectangular portion. Crop area must be fully within
* the orginal tiler view: 0 <= left <= left + width <= view->width, also:
* 0 <= top <= top + height <= view->height.
*
* @param view Pointer to tiler view to be cropped
* @param left x of top-left corner
* @param top y of top-left corner
* @param width crop width
* @param height crop height
*
* @return error status. The view will be reduced to the crop region if the
* crop region is correct. Otherwise, no modifications are made.
*/
s32 tilview_crop(struct tiler_view_t *view, u32 left, u32 top, u32 width,
u32 height);
/**
* Rotates a tiler view clockwise by a specified degree.
*
* @param view Pointer to tiler view to be cropped
* @param rotate Degree of rotation (clockwise). Must be a multiple of
* 90.
* @return error status. View is not modified on error; otherwise, it is
* updated in place.
*/
s32 tilview_rotate(struct tiler_view_t *view, s32 rotation);
/**
* Mirrors a tiler view horizontally and/or vertically.
*
* @param view Pointer to tiler view to be cropped
* @param flip_x Mirror horizontally (left-to-right)
* @param flip_y Mirror vertically (top-to-bottom)
*
* @return error status. View is not modified on error; otherwise, it is
* updated in place.
*/
s32 tilview_flip(struct tiler_view_t *view, bool flip_x, bool flip_y);
/*
* -------------------- TILER hooks for ION/HWC migration --------------------
*/
/* type of tiler memory */
enum tiler_memtype {
TILER_MEM_ALLOCED, /* tiler allocated the memory */
TILER_MEM_GOT_PAGES, /* tiler used get_user_pages */
TILER_MEM_USING, /* tiler is using the pages */
};
/* physical pages to pin - mem must be kmalloced */
struct tiler_pa_info {
u32 num_pg; /* number of pages in page-list */
u32 *mem; /* list of phys page addresses */
enum tiler_memtype memtype; /* how we got physical pages */
};
typedef struct mem_info *tiler_blk_handle;
/* NOTE: this will take ownership pa->mem (will free it) */
tiler_blk_handle tiler_map_1d_block(struct tiler_pa_info *pa);
void tiler_free_block(tiler_blk_handle block);
/*
* ---------------------------- IOCTL Definitions ----------------------------
*/
/* ioctls */
#define TILIOC_GBLK _IOWR('z', 100, struct tiler_block_info)
#define TILIOC_FBLK _IOW('z', 101, struct tiler_block_info)
#define TILIOC_GSSP _IOWR('z', 102, u32)
#define TILIOC_MBLK _IOWR('z', 103, struct tiler_block_info)
#define TILIOC_UMBLK _IOW('z', 104, struct tiler_block_info)
#define TILIOC_QBUF _IOWR('z', 105, struct tiler_buf_info)
#define TILIOC_RBUF _IOWR('z', 106, struct tiler_buf_info)
#define TILIOC_URBUF _IOWR('z', 107, struct tiler_buf_info)
#define TILIOC_QBLK _IOWR('z', 108, struct tiler_block_info)
#define TILIOC_PRBLK _IOW('z', 109, struct tiler_block_info)
#define TILIOC_URBLK _IOW('z', 110, u32)
struct area {
u16 width;
u16 height;
};
/* userspace tiler block info */
struct tiler_block_info {
enum tiler_fmt fmt;
union {
struct area area;
u32 len;
} dim;
u32 stride; /* stride is not maintained for 1D blocks */
void *ptr; /* userspace address for mapping existing buffer */
u32 id;
u32 key;
u32 group_id;
u32 align; /* alignment requirements for ssptr */
u32 offs; /* offset (ssptr & (align - 1) will equal offs) */
u32 ssptr; /* physical address, may not exposed by default */
};
#define TILER_MAX_NUM_BLOCKS 16
/* userspace tiler buffer info */
struct tiler_buf_info {
u32 num_blocks;
struct tiler_block_info blocks[TILER_MAX_NUM_BLOCKS];
u32 offset;
u32 length; /* also used as number of buffers for reservation */
};
#endif
|