diff options
author | Lajos Molnar <molnar@ti.com> | 2011-04-07 08:41:25 +0100 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2011-04-07 08:41:25 +0100 |
commit | ad30a7c4f0b692183c9ea0970e5457ab0a64fc87 (patch) | |
tree | 62d4c98789dd74d8d82ad20655dd0f36422f75e9 /drivers/media/video/tiler | |
parent | 86ff971f7ec1db3ffe0e335f662668b61779d275 (diff) |
TILER: Use function table for non-static methods.
Moved all non-static internal functions into a function table.
Also renamed tiler-ioctl.c to tiler-iface.c as it contains multiple
external interfaces (file & API).
Signed-off-by: Lajos Molnar <molnar@ti.com>
Signed-off-by: David Sin <davidsin@ti.com>
Diffstat (limited to 'drivers/media/video/tiler')
-rw-r--r-- | drivers/media/video/tiler/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/video/tiler/_tiler.h | 104 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-geom.c | 28 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-iface.c (renamed from drivers/media/video/tiler/tiler-ioctl.c) | 84 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-main.c | 80 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-reserve.c | 56 |
6 files changed, 208 insertions, 146 deletions
diff --git a/drivers/media/video/tiler/Makefile b/drivers/media/video/tiler/Makefile index c617c4cc09d..b3276440304 100644 --- a/drivers/media/video/tiler/Makefile +++ b/drivers/media/video/tiler/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_TI_TILER) += tcm/ obj-$(CONFIG_TI_TILER) += tiler.o -tiler-objs = tiler-geom.o tiler-main.o tiler-ioctl.o tiler-reserve.o tmm-pat.o +tiler-objs = tiler-geom.o tiler-main.o tiler-iface.o tiler-reserve.o tmm-pat.o obj-$(CONFIG_TI_TILER) += tiler_dmm.o tiler_dmm-objs = dmm.o diff --git a/drivers/media/video/tiler/_tiler.h b/drivers/media/video/tiler/_tiler.h index 474b181b99d..2dd0903d939 100644 --- a/drivers/media/video/tiler/_tiler.h +++ b/drivers/media/video/tiler/_tiler.h @@ -4,8 +4,6 @@ #include <linux/kernel.h> #include "tcm.h" -extern const struct file_operations tiler_fops; - /* per process (thread group) info */ struct process_info { struct list_head list; /* other processes */ @@ -52,51 +50,61 @@ struct mem_info { void *parent; /* area info for 2D, else group info */ }; -/* tiler-main.c */ -struct mem_info *find_n_lock(u32 key, u32 id, struct gid_info *gi); -s32 alloc_block(enum tiler_fmt fmt, u32 width, u32 height, - u32 align, u32 offs, u32 key, u32 gid, struct process_info *pi, - struct mem_info **info); -s32 map_block(enum tiler_fmt fmt, u32 width, u32 height, - u32 key, u32 gid, struct process_info *pi, - struct mem_info **info, u32 usr_addr); - -void destroy_group(struct gid_info *pi); - -struct mem_info *find_block_by_ssptr(u32 sys_addr); -void fill_block_info(struct mem_info *i, struct tiler_block_info *blk); - -void unlock_n_free(struct mem_info *mi, bool free); - -s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, - u16 *x_area, u16 *y_area, u16 *band, - u16 *align, u16 *offs, u16 *in_offs); - -struct gid_info *get_gi(struct process_info *pi, u32 gid); -void release_gi(struct gid_info *gi); - -void add_reserved_blocks(struct list_head *reserved, struct gid_info *gi); -void release_blocks(struct list_head *reserved); - -/* tiler-reserve.c */ -void reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs, - u32 gid, struct process_info *pi, bool can_together); -void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, - u32 align, u32 offs, u32 gid, - struct process_info *pi); -void unreserve_blocks(struct process_info *pi, u32 gid); - -s32 reserve_2d(enum tiler_fmt fmt, u16 n, u16 w, u16 h, u16 band, - u16 align, u16 offs, struct gid_info *gi, - struct list_head *pos); -s32 pack_nv12(int n, u16 w, u16 w1, u16 h, struct gid_info *gi, - u8 *p); -void destroy_processes(void); -void tiler_proc_init(void); -/*** __get_area */ -u32 tiler_get_address(struct tiler_view_orient orient, - enum tiler_fmt fmt, u32 x, u32 y); -/*** find block */ -void tiler_get_natural_xy(u32 tsptr, u32 *x, u32 *y); +struct tiler_ops { + /* block operations */ + s32 (*alloc) (enum tiler_fmt fmt, u32 width, u32 height, + u32 align, u32 offs, u32 key, + u32 gid, struct process_info *pi, + struct mem_info **info); + s32 (*map) (enum tiler_fmt fmt, u32 width, u32 height, + u32 key, u32 gid, struct process_info *pi, + struct mem_info **info, u32 usr_addr); + + struct mem_info * (*lock) (u32 key, u32 id, struct gid_info *gi); + void (*unlock_free) (struct mem_info *mi, bool free); + + struct mem_info * (*get_by_ssptr) (u32 sys_addr); + void (*describe) (struct mem_info *i, struct tiler_block_info *blk); + + void (*add_reserved) (struct list_head *reserved, struct gid_info *gi); + void (*release) (struct list_head *reserved); + + /* group operations */ + struct gid_info * (*get_gi) (struct process_info *pi, u32 gid); + void (*release_gi) (struct gid_info *gi); + void (*destroy_group) (struct gid_info *pi); + + + s32 (*analize) (enum tiler_fmt fmt, u32 width, u32 height, + u16 *x_area, u16 *y_area, u16 *band, + u16 *align, u16 *offs, u16 *in_offs); + + + /* process operations */ + void (*cleanup) (void); + + /* geometry operations */ + void (*xy) (u32 tsptr, u32 *x, u32 *y); + u32 (*addr) (struct tiler_view_orient orient, enum tiler_fmt fmt, + u32 x, u32 y); + + /* reservation operations */ + void (*reserve_nv12) (u32 n, u32 width, u32 height, u32 align, u32 offs, + u32 gid, struct process_info *pi, bool can_together); + void (*reserve) (u32 n, enum tiler_fmt fmt, u32 width, u32 height, + u32 align, u32 offs, u32 gid, struct process_info *pi); + void (*unreserve) (u32 gid, struct process_info *pi); + + s32 (*lay_2d) (enum tiler_fmt fmt, u16 n, u16 w, u16 h, u16 band, + u16 align, u16 offs, struct gid_info *gi, + struct list_head *pos); + s32 (*lay_nv12) (int n, u16 w, u16 w1, u16 h, struct gid_info *gi, + u8 *p); + const struct file_operations *fops; +}; + +void tiler_iface_init(struct tiler_ops *tiler); +void tiler_geom_init(struct tiler_ops *tiler); +void tiler_reserve_init(struct tiler_ops *tiler); #endif diff --git a/drivers/media/video/tiler/tiler-geom.c b/drivers/media/video/tiler/tiler-geom.c index 6dad0c974d2..6258d75b926 100644 --- a/drivers/media/video/tiler/tiler-geom.c +++ b/drivers/media/video/tiler/tiler-geom.c @@ -20,6 +20,7 @@ #include "tiler-def.h" #include <mach/dmm.h> /* TEMP */ #include "tcm.h" +#include "_tiler.h" #define DMM_SHIFT_PER_X_8 0 #define DMM_SHIFT_PER_Y_8 0 @@ -68,9 +69,9 @@ /* * TILER Memory model query method */ -bool is_tiler_addr(u32 addr) +bool is_tiler_addr(u32 phys) { - return addr >= TILVIEW_8BIT && addr < TILVIEW_END; + return phys >= TILVIEW_8BIT && phys < TILVIEW_END; } /* @@ -82,29 +83,32 @@ static const u32 tiler_strides[TILER_FORMATS] = { 16384, 32768, 32768, 0 }; u32 tiler_bpp(const struct tiler_block_t *b) { - enum tiler_fmt fmt = tiler_fmt(b); + enum tiler_fmt fmt = tiler_fmt(b->phys); BUG_ON(fmt == TILFMT_INVALID); return tiler_bpps[fmt - TILFMT_8BIT]; } +EXPORT_SYMBOL(tiler_bpp); u32 tiler_pstride(const struct tiler_block_t *b) { - enum tiler_fmt fmt = tiler_fmt(b); + enum tiler_fmt fmt = tiler_fmt(b->phys); BUG_ON(fmt == TILFMT_INVALID); return tiler_strides[fmt - TILFMT_8BIT] ? : tiler_vstride(b); } +EXPORT_SYMBOL(tiler_pstride); -enum tiler_fmt tiler_fmt(const struct tiler_block_t *b) +enum tiler_fmt tiler_fmt(u32 phys) { - if (!is_tiler_addr(b->phys)) + if (!is_tiler_addr(phys)) return TILFMT_INVALID; - return TILER_GET_ACC_MODE(b->phys); + return TILER_GET_ACC_MODE(phys); } +EXPORT_SYMBOL(tiler_fmt); -void tiler_get_natural_xy(u32 tsptr, u32 *x, u32 *y) +static void tiler_get_natural_xy(u32 tsptr, u32 *x, u32 *y) { u32 x_bits, y_bits, offset; enum tiler_fmt fmt; @@ -149,7 +153,7 @@ void tiler_get_natural_xy(u32 tsptr, u32 *x, u32 *y) *y ^= DMM_TILER_MASK(y_bits); } -u32 tiler_get_address(struct tiler_view_orient orient, +static u32 tiler_get_address(struct tiler_view_orient orient, enum tiler_fmt fmt, u32 x, u32 y) { u32 x_bits, y_bits, tmp, x_mask, y_mask, alignment; @@ -199,6 +203,12 @@ u32 tiler_get_address(struct tiler_view_orient orient, fmt); } +void tiler_geom_init(struct tiler_ops *tiler) +{ + tiler->xy = tiler_get_natural_xy; + tiler->addr = tiler_get_address; +} + u32 tiler_reorient_addr(u32 tsptr, struct tiler_view_orient orient) { u32 x, y; diff --git a/drivers/media/video/tiler/tiler-ioctl.c b/drivers/media/video/tiler/tiler-iface.c index dd82e12494a..15f4a3f55d6 100644 --- a/drivers/media/video/tiler/tiler-ioctl.c +++ b/drivers/media/video/tiler/tiler-iface.c @@ -28,6 +28,7 @@ MODULE_PARM_DESC(offset_lookup, static struct mutex mtx; static struct list_head procs; +static struct tiler_ops *ops; /* * Buffer handling methods @@ -81,14 +82,14 @@ _m_lock_block(u32 key, u32 id, struct process_info *pi) { if (pi) { /* find block in process list and free it */ list_for_each_entry(gi, &pi->groups, by_pid) { - mi = find_n_lock(key, id, gi); + mi = ops->lock(key, id, gi); if (mi) return mi; } } /* if not found or no process_info given, find block in global list */ - return find_n_lock(key, id, NULL); + return ops->lock(key, id, NULL); } /* register a buffer */ @@ -110,7 +111,7 @@ static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi) if (!mi) { /* unlock any blocks already found */ while (i--) - unlock_n_free(_b->mi[i], false); + ops->unlock_free(_b->mi[i], false); return -EACCES; } _b->mi[i] = mi; @@ -125,6 +126,17 @@ static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi) return 0; } +static s32 register_buf(struct __buf_info *_b, struct process_info *pi) +{ + s32 r; + + mutex_lock(&mtx); + r = _m_register_buf(_b, pi); + mutex_unlock(&mtx); + + return r; +} + /* unregister a buffer */ /* must have mutex */ static void _m_unregister_buf(struct __buf_info *_b) @@ -136,7 +148,7 @@ static void _m_unregister_buf(struct __buf_info *_b) /* no longer using the blocks */ for (i = 0; i < _b->buf_info.num_blocks; i++) - unlock_n_free(_b->mi[i], false); + ops->unlock_free(_b->mi[i], false); kfree(_b); } @@ -206,7 +218,7 @@ void _m_free_process_info(struct process_info *pi) /* free all allocated blocks, and remove unreferenced ones */ list_for_each_entry_safe(gi, gi_, &pi->groups, by_pid) { - destroy_group(gi); + ops->destroy_group(gi); } BUG_ON(!list_empty(&pi->groups)); @@ -214,7 +226,7 @@ void _m_free_process_info(struct process_info *pi) kfree(pi); } -void destroy_processes(void) +static void destroy_processes(void) { struct process_info *pi, *pi_; @@ -227,17 +239,6 @@ void destroy_processes(void) mutex_unlock(&mtx); } -void tiler_proc_init(void) -{ -#ifdef CONFIG_TILER_SECURE - security = true; - offset_lookup = ssptr_lookup = false; -#endif - - mutex_init(&mtx); - INIT_LIST_HEAD(&procs); -} - /* * File operations (mmap, ioctl, open, close) * ========================================================================== @@ -305,7 +306,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, switch (block_info.fmt) { case TILFMT_PAGE: - r = alloc_block(block_info.fmt, block_info.dim.len, 1, + r = ops->alloc(block_info.fmt, block_info.dim.len, 1, block_info.align, block_info.offs, block_info.key, block_info.group_id, pi, &mi); @@ -315,7 +316,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, case TILFMT_8BIT: case TILFMT_16BIT: case TILFMT_32BIT: - r = alloc_block(block_info.fmt, + r = ops->alloc(block_info.fmt, block_info.dim.area.width, block_info.dim.area.height, block_info.align, block_info.offs, @@ -350,7 +351,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, mi = _m_lock_block(block_info.key, block_info.id, pi); mutex_unlock(&mtx); if (mi) { - unlock_n_free(mi, true); + ops->unlock_free(mi, true); r = 0; } r = -EACCES; @@ -383,7 +384,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, if (!block_info.ptr) return -EFAULT; - r = map_block(block_info.fmt, block_info.dim.len, 1, + r = ops->map(block_info.fmt, block_info.dim.len, 1, block_info.key, block_info.group_id, pi, &mi, (u32)block_info.ptr); if (r) @@ -439,9 +440,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, kfree(_b); return -EFAULT; } - mutex_lock(&mtx); - r = _m_register_buf(_b, pi); - mutex_unlock(&mtx); + r = register_buf(_b, pi); if (r) { kfree(_b); return -EACCES; } @@ -475,7 +474,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, return -EFAULT; if (block_info.fmt == TILFMT_8AND16) { - reserve_nv12(block_info.key, + ops->reserve_nv12(block_info.key, block_info.dim.area.width, block_info.dim.area.height, block_info.align, @@ -483,7 +482,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, block_info.group_id, pi, true /* :TODO: get can_together */); } else { - reserve_blocks(block_info.key, + ops->reserve(block_info.key, block_info.fmt, block_info.dim.area.width, block_info.dim.area.height, @@ -493,7 +492,7 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, } break; case TILIOC_URBLK: - unreserve_blocks(pi, arg); + ops->unreserve(arg, pi); break; #ifndef CONFIG_TILER_SECURE case TILIOC_QBLK: @@ -504,9 +503,9 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, sizeof(block_info))) return -EFAULT; - mi = find_block_by_ssptr(block_info.ssptr); + mi = ops->get_by_ssptr(block_info.ssptr); if (mi) - fill_block_info(mi, &block_info); + ops->describe(mi, &block_info); else return -EFAULT; @@ -552,6 +551,21 @@ const struct file_operations tiler_fops = { .mmap = tiler_mmap, }; +void tiler_iface_init(struct tiler_ops *tiler) +{ + ops = tiler; + ops->cleanup = destroy_processes; + ops->fops = &tiler_fops; + +#ifdef CONFIG_TILER_SECURE + security = true; + offset_lookup = ssptr_lookup = false; +#endif + + mutex_init(&mtx); + INIT_LIST_HEAD(&procs); +} + /* * Kernel APIs * ========================================================================== @@ -563,7 +577,7 @@ s32 tiler_reservex(u32 n, enum tiler_fmt fmt, u32 width, u32 height, struct process_info *pi = __get_pi(pid, true); if (pi) - reserve_blocks(n, fmt, width, height, align, offs, gid, pi); + ops->reserve(n, fmt, width, height, align, offs, gid, pi); return 0; } EXPORT_SYMBOL(tiler_reservex); @@ -583,7 +597,7 @@ s32 tiler_reservex_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs, struct process_info *pi = __get_pi(pid, true); if (pi) - reserve_nv12(n, width, height, align, offs, gid, pi, + ops->reserve_nv12(n, width, height, align, offs, gid, pi, true /* :TODO: get can_together */); return 0; } @@ -610,7 +624,7 @@ s32 tiler_allocx(struct tiler_block_t *blk, enum tiler_fmt fmt, if (!pi) return -ENOMEM; - res = alloc_block(fmt, blk->width, blk->height, align, offs, blk->key, + res = ops->alloc(fmt, blk->width, blk->height, align, offs, blk->key, gid, pi, &mi); if (mi) blk->phys = mi->blk.phys; @@ -639,7 +653,7 @@ s32 tiler_mapx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 gid, if (!pi) return -ENOMEM; - res = map_block(fmt, blk->width, blk->height, blk->key, gid, pi, &mi, + res = ops->map(fmt, blk->width, blk->height, blk->key, gid, pi, &mi, usr_addr); if (mi) blk->phys = mi->blk.phys; @@ -738,8 +752,8 @@ EXPORT_SYMBOL(tiler_ioremap_blk); void tiler_free(struct tiler_block_t *blk) { /* find block */ - struct mem_info *mi = find_n_lock(blk->key, blk->id, NULL); + struct mem_info *mi = ops->lock(blk->key, blk->id, NULL); if (mi) - unlock_n_free(mi, true); + ops->unlock_free(mi, true); } EXPORT_SYMBOL(tiler_free); diff --git a/drivers/media/video/tiler/tiler-main.c b/drivers/media/video/tiler/tiler-main.c index 05e675b464f..a909aa2481b 100644 --- a/drivers/media/video/tiler/tiler-main.c +++ b/drivers/media/video/tiler/tiler-main.c @@ -50,6 +50,8 @@ MODULE_PARM_DESC(align, "Default block ssptr alignment"); module_param_named(grain, granularity, uint, 0644); MODULE_PARM_DESC(grain, "Granularity (bytes)"); +struct tiler_ops tiler; + struct tiler_dev { struct cdev cdev; }; @@ -224,7 +226,7 @@ static void _m_try_free_group(struct gid_info *gi) /* --- external versions --- */ -struct gid_info *get_gi(struct process_info *pi, u32 gid) +static struct gid_info *get_gi(struct process_info *pi, u32 gid) { struct gid_info *gi; mutex_lock(&mtx); @@ -233,7 +235,7 @@ struct gid_info *get_gi(struct process_info *pi, u32 gid) return gi; } -void release_gi(struct gid_info *gi) +static void release_gi(struct gid_info *gi) { mutex_lock(&mtx); gi->refs--; @@ -280,7 +282,7 @@ static inline void _m_area_free(struct area_info *ai) } } -s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, +static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, u16 *x_area, u16 *y_area, u16 *band, u16 *align, u16 *offs, u16 *in_offs) { @@ -478,9 +480,9 @@ done: return mi; } -/* layout reserved 2d areas in a larger area */ +/* layout reserved 2d blocks in a larger area */ /* NOTE: band, w, h, a(lign), o(ffs) is in slots */ -s32 reserve_2d(enum tiler_fmt fmt, u16 n, u16 w, u16 h, u16 band, +static s32 lay_2d(enum tiler_fmt fmt, u16 n, u16 w, u16 h, u16 band, u16 align, u16 offs, struct gid_info *gi, struct list_head *pos) { @@ -515,13 +517,11 @@ s32 reserve_2d(enum tiler_fmt fmt, u16 n, u16 w, u16 h, u16 band, return n; } -/* reserve nv12 blocks if standard allocator is inefficient */ -/* TILER is designed so that a (w * h) * 8bit area is twice as wide as a - (w/2 * h/2) * 16bit area. Since having pairs of such 8-bit and 16-bit - blocks is a common usecase for TILER, we optimize packing these into a - TILER area */ -s32 pack_nv12(int n, u16 w, u16 w1, u16 h, struct gid_info *gi, - u8 *p) +/* layout reserved nv12 blocks in a larger area */ +/* NOTE: area w(idth), w1 (8-bit block width), h(eight) are in slots */ +/* p is a pointer to a packing description, which is a list of offsets in + the area for consecutive 8-bit and 16-bit blocks */ +static s32 lay_nv12(int n, u16 w, u16 w1, u16 h, struct gid_info *gi, u8 *p) { u16 wh = (w1 + 1) >> 1, width, x0; int m; @@ -657,7 +657,7 @@ static inline bool _m_try_free(struct mem_info *mi) /* --- external methods --- */ /* find a block by key/id and lock it */ -struct mem_info * +static struct mem_info * find_n_lock(u32 key, u32 id, struct gid_info *gi) { struct area_info *ai = NULL; struct mem_info *mi = NULL; @@ -705,7 +705,7 @@ done: } /* unlock a block, and optionally free it */ -void unlock_n_free(struct mem_info *mi, bool free) +static void unlock_n_free(struct mem_info *mi, bool free) { mutex_lock(&mtx); @@ -725,7 +725,7 @@ void unlock_n_free(struct mem_info *mi, bool free) * * (must have mutex) */ -void destroy_group(struct gid_info *gi) +static void destroy_group(struct gid_info *gi) { struct area_info *ai, *ai_; struct mem_info *mi, *mi_; @@ -775,7 +775,7 @@ void destroy_group(struct gid_info *gi) } /* release (reserved) blocks */ -void release_blocks(struct list_head *reserved) +static void release_blocks(struct list_head *reserved) { struct mem_info *mi, *mi_; @@ -790,7 +790,7 @@ void release_blocks(struct list_head *reserved) } /* add reserved blocks to a group */ -void add_reserved_blocks(struct list_head *reserved, struct gid_info *gi) +static void add_reserved_blocks(struct list_head *reserved, struct gid_info *gi) { mutex_lock(&mtx); list_splice_init(reserved, &gi->reserved); @@ -798,28 +798,25 @@ void add_reserved_blocks(struct list_head *reserved, struct gid_info *gi) } /* find a block by ssptr */ -struct mem_info *find_block_by_ssptr(u32 sys_addr) +static struct mem_info *find_block_by_ssptr(u32 sys_addr) { struct mem_info *i; struct tcm_pt pt; u32 x, y; enum tiler_fmt fmt; - struct tiler_block_t blk = {0}; - if (!is_tiler_addr(sys_addr)) + fmt = tiler_fmt(sys_addr); + if (fmt == TILFMT_INVALID) return NULL; - blk.phys = sys_addr; - fmt = tiler_fmt(&blk); - /* convert x & y pixel coordinates to slot coordinates */ - tiler_get_natural_xy(sys_addr, &x, &y); + tiler.xy(sys_addr, &x, &y); pt.x = x / (fmt == TILFMT_PAGE ? 1 : fmt == TILFMT_32BIT ? 32 : 64); pt.y = y / (fmt == TILFMT_PAGE ? 1 : fmt == TILFMT_8BIT ? 64 : 32); mutex_lock(&mtx); list_for_each_entry(i, &blocks, global) { - if (tiler_fmt(&i->blk) == TILER_GET_ACC_MODE(sys_addr) && + if (tiler_fmt(i->blk.phys) == TILER_GET_ACC_MODE(sys_addr) && tcm_is_in(pt, i->area)) goto found; } @@ -831,7 +828,7 @@ found: } /* find a block by ssptr */ -void fill_block_info(struct mem_info *i, struct tiler_block_info *blk) +static void fill_block_info(struct mem_info *i, struct tiler_block_info *blk) { blk->ptr = NULL; blk->fmt = TILER_GET_ACC_MODE(i->blk.phys); @@ -899,7 +896,7 @@ static struct mem_info *__get_area(enum tiler_fmt fmt, u32 width, u32 height, gi->refs--; mutex_unlock(&mtx); - mi->blk.phys = tiler_get_address(orient, fmt, + mi->blk.phys = tiler.addr(orient, fmt, mi->area.p0.x * (fmt == TILFMT_PAGE ? 1 : fmt == TILFMT_32BIT ? 32 : 64), mi->area.p0.y * (fmt == TILFMT_PAGE ? 1 : @@ -908,7 +905,7 @@ static struct mem_info *__get_area(enum tiler_fmt fmt, u32 width, u32 height, return mi; } -s32 alloc_block(enum tiler_fmt fmt, u32 width, u32 height, +static s32 alloc_block(enum tiler_fmt fmt, u32 width, u32 height, u32 align, u32 offs, u32 key, u32 gid, struct process_info *pi, struct mem_info **info) { @@ -976,7 +973,7 @@ cleanup: } -s32 map_block(enum tiler_fmt fmt, u32 width, u32 height, +static s32 map_block(enum tiler_fmt fmt, u32 width, u32 height, u32 key, u32 gid, struct process_info *pi, struct mem_info **info, u32 usr_addr) { @@ -1125,6 +1122,24 @@ static s32 __init tiler_init(void) struct tcm *sita = NULL; struct tmm *tmm_pat = NULL; + tiler.alloc = alloc_block; + tiler.map = map_block; + tiler.lock = find_n_lock; + tiler.unlock_free = unlock_n_free; + tiler.lay_2d = lay_2d; + tiler.lay_nv12 = lay_nv12; + tiler.destroy_group = destroy_group; + tiler.get_by_ssptr = find_block_by_ssptr; + tiler.describe = fill_block_info; + tiler.get_gi = get_gi; + tiler.release_gi = release_gi; + tiler.release = release_blocks; + tiler.add_reserved = add_reserved_blocks; + tiler.analize = __analize_area; + tiler_geom_init(&tiler); + tiler_reserve_init(&tiler); + tiler_iface_init(&tiler); + /* check module parameters for correctness */ if (default_align > PAGE_SIZE || default_align & (default_align - 1) || @@ -1164,9 +1179,9 @@ static s32 __init tiler_init(void) tiler_major = MAJOR(dev); } - cdev_init(&tiler_device->cdev, &tiler_fops); + cdev_init(&tiler_device->cdev, tiler.fops); tiler_device->cdev.owner = THIS_MODULE; - tiler_device->cdev.ops = &tiler_fops; + tiler_device->cdev.ops = tiler.fops; r = cdev_add(&tiler_device->cdev, dev, 1); if (r) @@ -1187,7 +1202,6 @@ static s32 __init tiler_init(void) mutex_init(&mtx); INIT_LIST_HEAD(&blocks); - tiler_proc_init(); INIT_LIST_HEAD(&orphan_areas); INIT_LIST_HEAD(&orphan_onedim); @@ -1209,7 +1223,7 @@ static void __exit tiler_exit(void) mutex_lock(&mtx); /* free all process data */ - destroy_processes(); + tiler.cleanup(); /* all lists should have cleared */ BUG_ON(!list_empty(&blocks)); diff --git a/drivers/media/video/tiler/tiler-reserve.c b/drivers/media/video/tiler/tiler-reserve.c index 268a15806f9..1ca4cec82f8 100644 --- a/drivers/media/video/tiler/tiler-reserve.c +++ b/drivers/media/video/tiler/tiler-reserve.c @@ -21,6 +21,13 @@ #include "tiler-def.h" #include "_tiler.h" +static struct tiler_ops *ops; + +/* TILER is designed so that a (w * h) * 8bit area is twice as wide as a + (w/2 * h/2) * 16bit area. Since having pairs of such 8-bit and 16-bit + blocks is a common usecase for TILER, we optimize packing these into a + TILER area */ + /* we want to find the most effective packing for the smallest area */ /* we have two algorithms for packing nv12 blocks */ @@ -300,7 +307,7 @@ static u16 nv12_together(u16 o, u16 w, u16 a, u16 n, u16 *area, u8 *packing) } /* can_together: 8-bit and 16-bit views are in the same container */ -void reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs, +static void reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs, u32 gid, struct process_info *pi, bool can_together) { /* adjust alignment to at least 128 bytes (16-bit slot width) */ @@ -319,12 +326,12 @@ void reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs, return; /* calculate dimensions, band, offs and alignment in slots */ - if (__analize_area(TILFMT_8BIT, width, height, &w, &h, &band, &a, &o, + if (ops->analize(TILFMT_8BIT, width, height, &w, &h, &band, &a, &o, NULL)) return; /* get group context */ - gi = get_gi(pi, gid); + gi = ops->get_gi(pi, gid); if (!gi) return; @@ -346,8 +353,8 @@ void reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs, /* reserve blocks separately into a temporary list, so that we can free them if unsuccessful */ - res = reserve_2d(TILFMT_8BIT, n_s, w, h, band, a, o, gi, - &reserved); + res = ops->lay_2d(TILFMT_8BIT, n_s, w, h, band, a, o, + gi, &reserved); /* only reserve 16-bit blocks if 8-bit was successful, as we will try to match 16-bit areas to an already @@ -355,30 +362,30 @@ void reserve_nv12(u32 n, u32 width, u32 height, u32 align, u32 offs, an unreserved 8-bit area will match the offset of a singly reserved 16-bit area. */ res2 = (res < 0 ? res : - reserve_2d(TILFMT_16BIT, n_s, (w + 1) / 2, h, + ops->lay_2d(TILFMT_16BIT, n_s, (w + 1) / 2, h, band / 2, a / 2, o / 2, gi, &reserved)); if (res2 < 0 || res != res2) { /* clean up */ - release_blocks(&reserved); + ops->release(&reserved); res = -1; } else { /* add list to reserved */ - add_reserved_blocks(&reserved, gi); + ops->add_reserved(&reserved, gi); } } /* if separate packing failed, still try to pack together */ if (res < 0 && can_together && n_t) { /* pack together */ - res = pack_nv12(n_t, area_t, w, h, gi, packing); + res = ops->lay_nv12(n_t, area_t, w, h, gi, packing); } } - release_gi(gi); + ops->release_gi(gi); } /* reserve 2d blocks (if standard allocator is inefficient) */ -void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, +static void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, u32 align, u32 offs, u32 gid, struct process_info *pi) { @@ -401,11 +408,11 @@ void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, the default allocation is sufficient. Also check for basic area info. */ if (width * bpp * 2 <= PAGE_SIZE || - __analize_area(fmt, width, height, &w, &h, &band, &a, &o, NULL)) + ops->analize(fmt, width, height, &w, &h, &band, &a, &o, NULL)) return; /* get group id */ - gi = get_gi(pi, gid); + gi = ops->get_gi(pi, gid); if (!gi) return; @@ -419,8 +426,8 @@ void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, res = -1; while (n_try > 1) { - res = reserve_2d(fmt, n_try, w, h, band, a, o, gi, - &gi->reserved); + res = ops->lay_2d(fmt, n_try, w, h, band, a, o, + gi, &gi->reserved); if (res >= 0) break; @@ -430,18 +437,27 @@ void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, } /* keep reserved blocks even if failed to reserve all */ - release_gi(gi); + ops->release_gi(gi); } -void unreserve_blocks(struct process_info *pi, u32 gid) +static void unreserve_blocks(u32 gid, struct process_info *pi) { struct gid_info *gi; - gi = get_gi(pi, gid); + gi = ops->get_gi(pi, gid); if (!gi) return; - release_blocks(&gi->reserved); + ops->release(&gi->reserved); + + ops->release_gi(gi); +} + +void tiler_reserve_init(struct tiler_ops *tiler) +{ + ops = tiler; - release_gi(gi); + ops->reserve_nv12 = reserve_nv12; + ops->reserve = reserve_blocks; + ops->unreserve = unreserve_blocks; } |