summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLajos Molnar <molnar@ti.com>2011-04-07 08:41:25 +0100
committerAndy Green <andy.green@linaro.org>2011-04-07 08:41:25 +0100
commitad30a7c4f0b692183c9ea0970e5457ab0a64fc87 (patch)
tree62d4c98789dd74d8d82ad20655dd0f36422f75e9 /drivers
parent86ff971f7ec1db3ffe0e335f662668b61779d275 (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')
-rw-r--r--drivers/media/video/tiler/Makefile2
-rw-r--r--drivers/media/video/tiler/_tiler.h104
-rw-r--r--drivers/media/video/tiler/tiler-geom.c28
-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.c80
-rw-r--r--drivers/media/video/tiler/tiler-reserve.c56
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;
}