summaryrefslogtreecommitdiff
path: root/drivers/media/video/tiler
diff options
context:
space:
mode:
authorLajos Molnar <molnar@ti.com>2011-04-07 08:41:28 +0100
committerAndy Green <andy.green@linaro.org>2011-04-07 08:41:28 +0100
commit67d891bca67ab1537cf99210677f79af11b996a6 (patch)
tree255d90d91872551d86b4039c01a4d5ac28250491 /drivers/media/video/tiler
parentd16edfb337d41f717345a1e149f6039afa239f5e (diff)
TILER: Removed redundant hardcoded TILER constants.
tiler-geom.c now calculates most tiler-geometry related constants, and exposes them to other functions via a tiler_geom structure. Removed unused TILER calculation macros. 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/_tiler.h16
-rw-r--r--drivers/media/video/tiler/tiler-def.h50
-rw-r--r--drivers/media/video/tiler/tiler-geom.c273
-rw-r--r--drivers/media/video/tiler/tiler-main.c79
-rw-r--r--drivers/media/video/tiler/tiler-reserve.c44
5 files changed, 210 insertions, 252 deletions
diff --git a/drivers/media/video/tiler/_tiler.h b/drivers/media/video/tiler/_tiler.h
index 149f3002730..ab6bfec8cf5 100644
--- a/drivers/media/video/tiler/_tiler.h
+++ b/drivers/media/video/tiler/_tiler.h
@@ -50,6 +50,15 @@ struct mem_info {
void *parent; /* area info for 2D, else group info */
};
+struct tiler_geom {
+ u32 x_shft; /* unused X-bits (as part of bpp) */
+ u32 y_shft; /* unused Y-bits (as part of bpp) */
+ u32 bpp; /* bytes per pixel */
+ u32 slot_w; /* width of each slot (in pixels) */
+ u32 slot_h; /* height of each slot (in pixels) */
+ u32 bpp_m; /* modified bytes per pixel (=1 for page mode) */
+};
+
struct tiler_ops {
/* block operations */
s32 (*alloc) (enum tiler_fmt fmt, u32 width, u32 height,
@@ -97,10 +106,15 @@ struct tiler_ops {
void (*xy) (u32 tsptr, u32 *x, u32 *y);
u32 (*addr) (struct tiler_view_orient orient, enum tiler_fmt fmt,
u32 x, u32 y);
+ const struct tiler_geom * (*geom) (enum tiler_fmt fmt);
/* additional info */
const struct file_operations *fops;
- bool nv12_packed;
+
+ bool nv12_packed; /* whether NV12 is packed into same container */
+ u32 page; /* page size */
+ u32 width; /* container width */
+ u32 height; /* container height */
};
void tiler_iface_init(struct tiler_ops *tiler);
diff --git a/drivers/media/video/tiler/tiler-def.h b/drivers/media/video/tiler/tiler-def.h
index 8e34811e3b4..611b81dc60b 100644
--- a/drivers/media/video/tiler/tiler-def.h
+++ b/drivers/media/video/tiler/tiler-def.h
@@ -17,56 +17,10 @@
#ifndef TILER_DEF_H
#define TILER_DEF_H
-#define ROUND_UP_2P(a, b) (((a) + (b) - 1) & ~((b) - 1))
-#define DIVIDE_UP(a, b) (((a) + (b) - 1) / (b))
-#define ROUND_UP(a, b) (DIVIDE_UP(a, b) * (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#define TILER_ACC_MODE_SHIFT (27)
-#define TILER_ACC_MODE_MASK (3)
-#define TILER_GET_ACC_MODE(x) ((enum tiler_fmt) (TILFMT_8BIT + \
-(((u32)x & (TILER_ACC_MODE_MASK<<TILER_ACC_MODE_SHIFT))>>TILER_ACC_MODE_SHIFT)))
-
-#define TILER_FORMATS 4
-
-#define TILER_ALIAS_BASE 0x60000000u
-#define TILVIEW_8BIT TILER_ALIAS_BASE
-#define TILVIEW_16BIT (TILVIEW_8BIT + 0x08000000u)
-#define TILVIEW_32BIT (TILVIEW_16BIT + 0x08000000u)
-#define TILVIEW_PAGE (TILVIEW_32BIT + 0x08000000u)
-#define TILVIEW_END (TILVIEW_PAGE + 0x08000000u)
-
-#define TIL_ADDR(x, r, yi, xi, a)\
-((void *)((u32)x | (r << DMM_ROTATION_SHIFT) |\
-(yi << DMM_Y_INVERT_SHIFT) | (xi << DMM_X_INVERT_SHIFT) |\
-(a << TILER_ACC_MODE_SHIFT)))
-
-#define DMM_X_INVERT_SHIFT (29)
-#define DMM_IS_X_INVERTED(x) ((x >> DMM_X_INVERT_SHIFT) & 1)
-#define DMM_Y_INVERT_SHIFT (30)
-#define DMM_IS_Y_INVERTED(x) ((x >> DMM_Y_INVERT_SHIFT) & 1)
-#define DMM_ROTATION_SHIFT (31)
-#define DMM_IS_ROTATED(x) ((x >> DMM_ROTATION_SHIFT) & 1)
-
-#define DMM_ALIAS_VIEW_CLEAR (~0xE0000000)
-
-#define DMM_TILE_DIMM_X_MODE_8 (32)
-#define DMM_TILE_DIMM_Y_MODE_8 (32)
-
-#define DMM_TILE_DIMM_X_MODE_16 (32)
-#define DMM_TILE_DIMM_Y_MODE_16 (16)
-
-#define DMM_TILE_DIMM_X_MODE_32 (16)
-#define DMM_TILE_DIMM_Y_MODE_32 (16)
-
-#define DMM_PAGE_DIMM_X_MODE_8 (DMM_TILE_DIMM_X_MODE_8*2)
-#define DMM_PAGE_DIMM_Y_MODE_8 (DMM_TILE_DIMM_Y_MODE_8*2)
-
-#define DMM_PAGE_DIMM_X_MODE_16 (DMM_TILE_DIMM_X_MODE_16*2)
-#define DMM_PAGE_DIMM_Y_MODE_16 (DMM_TILE_DIMM_Y_MODE_16*2)
-
-#define DMM_PAGE_DIMM_X_MODE_32 (DMM_TILE_DIMM_X_MODE_32*2)
-#define DMM_PAGE_DIMM_Y_MODE_32 (DMM_TILE_DIMM_Y_MODE_32*2)
+#define TILER_FORMATS (TILFMT_MAX - TILFMT_MIN + 1)
+#define TILER_ALIAS_BASE 0x60000000u
#endif
diff --git a/drivers/media/video/tiler/tiler-geom.c b/drivers/media/video/tiler/tiler-geom.c
index 3423301ef84..6f7bdacb450 100644
--- a/drivers/media/video/tiler/tiler-geom.c
+++ b/drivers/media/video/tiler/tiler-geom.c
@@ -22,49 +22,64 @@
#include "tcm.h"
#include "_tiler.h"
-#define DMM_SHIFT_PER_X_8 0
-#define DMM_SHIFT_PER_Y_8 0
-#define DMM_SHIFT_PER_X_16 0
-#define DMM_SHIFT_PER_Y_16 1
-#define DMM_SHIFT_PER_X_32 1
-#define DMM_SHIFT_PER_Y_32 1
-#define DMM_SHIFT_PER_X_PAGE 6
-#define DMM_SHIFT_PER_Y_PAGE 6
-
-#define DMM_TILER_THE(NAME) (1 << DMM_TILER_##NAME##_BITS)
-#define DMM_TILER_THE_(N, NAME) (1 << DMM_TILER_##NAME##_BITS_(N))
-
-#define DMM_TILER_CONT_WIDTH_BITS 14
-#define DMM_TILER_CONT_HEIGHT_BITS 13
-
-#define DMM_SHIFT_PER_P_(N) (DMM_SHIFT_PER_X_##N + DMM_SHIFT_PER_Y_##N)
-
-#define DMM_TILER_CONT_HEIGHT_BITS_(N) \
- (DMM_TILER_CONT_HEIGHT_BITS - DMM_SHIFT_PER_Y_##N)
-#define DMM_TILER_CONT_WIDTH_BITS_(N) \
- (DMM_TILER_CONT_WIDTH_BITS - DMM_SHIFT_PER_X_##N)
-
-#define DMM_TILER_MASK(bits) ((1 << (bits)) - 1)
-
-#define DMM_TILER_GET_OFFSET_(N, var) \
- ((((u32) var) & DMM_TILER_MASK(DMM_TILER_CONT_WIDTH_BITS + \
- DMM_TILER_CONT_HEIGHT_BITS)) >> DMM_SHIFT_PER_P_(N))
-
-#define DMM_TILER_GET_0_X_(N, var) \
- (DMM_TILER_GET_OFFSET_(N, var) & \
- DMM_TILER_MASK(DMM_TILER_CONT_WIDTH_BITS_(N)))
-#define DMM_TILER_GET_0_Y_(N, var) \
- (DMM_TILER_GET_OFFSET_(N, var) >> DMM_TILER_CONT_WIDTH_BITS_(N))
-#define DMM_TILER_GET_90_X_(N, var) \
- (DMM_TILER_GET_OFFSET_(N, var) & \
- DMM_TILER_MASK(DMM_TILER_CONT_HEIGHT_BITS_(N)))
-#define DMM_TILER_GET_90_Y_(N, var) \
- (DMM_TILER_GET_OFFSET_(N, var) >> DMM_TILER_CONT_HEIGHT_BITS_(N))
-
-#define DMM_TILER_STRIDE_0_(N) \
- (DMM_TILER_THE(CONT_WIDTH) << DMM_SHIFT_PER_Y_##N)
-#define DMM_TILER_STRIDE_90_(N) \
- (DMM_TILER_THE(CONT_HEIGHT) << DMM_SHIFT_PER_X_##N)
+#define SLOT_WIDTH_BITS 6
+#define SLOT_HEIGHT_BITS 6
+
+static struct tiler_geom geom[TILER_FORMATS] = {
+ {
+ .x_shft = 0,
+ .y_shft = 0,
+ },
+ {
+ .x_shft = 0,
+ .y_shft = 1,
+ },
+ {
+ .x_shft = 1,
+ .y_shft = 1,
+ },
+ {
+ .x_shft = SLOT_WIDTH_BITS,
+ .y_shft = SLOT_HEIGHT_BITS,
+ },
+};
+
+#define DMM_ROTATION_SHIFT 31
+#define DMM_Y_INVERT_SHIFT 30
+#define DMM_X_INVERT_SHIFT 29
+#define DMM_ACC_MODE_SHIFT 27
+#define DMM_ACC_MODE_MASK 3
+#define CONT_WIDTH_BITS 14
+#define CONT_HEIGHT_BITS 13
+
+#define TILER_PAGE (1 << (SLOT_WIDTH_BITS + SLOT_HEIGHT_BITS))
+#define TILER_WIDTH (1 << (CONT_WIDTH_BITS - SLOT_WIDTH_BITS))
+#define TILER_HEIGHT (1 << (CONT_HEIGHT_BITS - SLOT_HEIGHT_BITS))
+
+#define VIEW_SIZE (1u << (CONT_WIDTH_BITS + CONT_HEIGHT_BITS))
+#define VIEW_MASK (VIEW_SIZE - 1u)
+
+#define MASK(bits) ((1 << (bits)) - 1)
+
+#define TILER_GET_ACC_MODE(x) ((enum tiler_fmt) (TILFMT_8BIT + \
+((x >> DMM_ACC_MODE_SHIFT) & DMM_ACC_MODE_MASK)))
+#define DMM_IS_X_INVERTED(x) ((x >> DMM_X_INVERT_SHIFT) & 1)
+#define DMM_IS_Y_INVERTED(x) ((x >> DMM_Y_INVERT_SHIFT) & 1)
+#define DMM_IS_ROTATED(x) ((x >> DMM_ROTATION_SHIFT) & 1)
+
+#define DMM_ALIAS_VIEW_CLEAR (~((1 << DMM_X_INVERT_SHIFT) | \
+ (1 << DMM_Y_INVERT_SHIFT) | (1 << DMM_ROTATION_SHIFT)))
+
+#define TILVIEW_8BIT TILER_ALIAS_BASE
+#define TILVIEW_16BIT (TILVIEW_8BIT + VIEW_SIZE)
+#define TILVIEW_32BIT (TILVIEW_16BIT + VIEW_SIZE)
+#define TILVIEW_PAGE (TILVIEW_32BIT + VIEW_SIZE)
+#define TILVIEW_END (TILVIEW_PAGE + VIEW_SIZE)
+
+#define TIL_ADDR(x, r, yi, xi, a)\
+ ((u32) x | (((r) ? 1 : 0) << DMM_ROTATION_SHIFT) | \
+ (((yi) ? 1 : 0) << DMM_Y_INVERT_SHIFT) | \
+ (((xi) ? 1 : 0) << DMM_X_INVERT_SHIFT) | ((a) << DMM_ACC_MODE_SHIFT))
/*
* TILER Memory model query method
@@ -78,24 +93,36 @@ bool is_tiler_addr(u32 phys)
* TILER block query method
*/
-static const u32 tiler_bpps[TILER_FORMATS] = { 1, 2, 4, 1 };
-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->phys);
BUG_ON(fmt == TILFMT_INVALID);
- return tiler_bpps[fmt - TILFMT_8BIT];
+ /* return modified bpp */
+ return geom[fmt - TILFMT_8BIT].bpp_m;
}
EXPORT_SYMBOL(tiler_bpp);
+static inline u32 tiler_stride(enum tiler_fmt fmt, bool rotated)
+{
+ if (fmt == TILFMT_PAGE)
+ return 0;
+
+ return rotated ?
+ 1 << (CONT_HEIGHT_BITS + geom[fmt].x_shft) :
+ 1 << (CONT_WIDTH_BITS + geom[fmt].y_shft);
+}
+
u32 tiler_pstride(const struct tiler_block_t *b)
{
enum tiler_fmt fmt = tiler_fmt(b->phys);
BUG_ON(fmt == TILFMT_INVALID);
- return tiler_strides[fmt - TILFMT_8BIT] ? : tiler_vstride(b);
+ /* return the virtual stride for page mode */
+ if (fmt == TILFMT_PAGE)
+ return tiler_vstride(b);
+
+ return tiler_stride(fmt, 0);
}
EXPORT_SYMBOL(tiler_pstride);
@@ -108,6 +135,13 @@ enum tiler_fmt tiler_fmt(u32 phys)
}
EXPORT_SYMBOL(tiler_fmt);
+static const struct tiler_geom *get_geom(enum tiler_fmt fmt)
+{
+ if (fmt >= TILFMT_MIN && fmt <= TILFMT_MAX)
+ return geom + fmt;
+ return NULL;
+}
+
static void tiler_get_natural_xy(u32 tsptr, u32 *x, u32 *y)
{
u32 x_bits, y_bits, offset;
@@ -115,42 +149,22 @@ static void tiler_get_natural_xy(u32 tsptr, u32 *x, u32 *y)
fmt = TILER_GET_ACC_MODE(tsptr);
- switch (fmt) {
- case TILFMT_8BIT:
- x_bits = DMM_TILER_CONT_WIDTH_BITS_(8);
- y_bits = DMM_TILER_CONT_HEIGHT_BITS_(8);
- offset = DMM_TILER_GET_OFFSET_(8, tsptr);
- break;
- case TILFMT_16BIT:
- x_bits = DMM_TILER_CONT_WIDTH_BITS_(16);
- y_bits = DMM_TILER_CONT_HEIGHT_BITS_(16);
- offset = DMM_TILER_GET_OFFSET_(16, tsptr);
- break;
- case TILFMT_32BIT:
- x_bits = DMM_TILER_CONT_WIDTH_BITS_(32);
- y_bits = DMM_TILER_CONT_HEIGHT_BITS_(32);
- offset = DMM_TILER_GET_OFFSET_(32, tsptr);
- break;
- case TILFMT_PAGE:
- default:
- x_bits = DMM_TILER_CONT_WIDTH_BITS_(PAGE);
- y_bits = DMM_TILER_CONT_HEIGHT_BITS_(PAGE);
- offset = DMM_TILER_GET_OFFSET_(PAGE, tsptr);
- break;
- }
+ x_bits = CONT_WIDTH_BITS - geom[fmt].x_shft;
+ y_bits = CONT_HEIGHT_BITS - geom[fmt].y_shft;
+ offset = (tsptr & VIEW_MASK) >> (geom[fmt].x_shft + geom[fmt].y_shft);
if (DMM_IS_ROTATED(tsptr)) {
*x = offset >> y_bits;
- *y = offset & DMM_TILER_MASK(y_bits);
+ *y = offset & MASK(y_bits);
} else {
- *x = offset & DMM_TILER_MASK(x_bits);
+ *x = offset & MASK(x_bits);
*y = offset >> x_bits;
}
if (DMM_IS_X_INVERTED(tsptr))
- *x ^= DMM_TILER_MASK(x_bits);
+ *x ^= MASK(x_bits);
if (DMM_IS_Y_INVERTED(tsptr))
- *y ^= DMM_TILER_MASK(y_bits);
+ *y ^= MASK(y_bits);
}
static u32 tiler_get_address(struct tiler_view_orient orient,
@@ -158,32 +172,12 @@ static u32 tiler_get_address(struct tiler_view_orient orient,
{
u32 x_bits, y_bits, tmp, x_mask, y_mask, alignment;
- switch (fmt) {
- case TILFMT_8BIT:
- x_bits = DMM_TILER_CONT_WIDTH_BITS_(8);
- y_bits = DMM_TILER_CONT_HEIGHT_BITS_(8);
- alignment = DMM_SHIFT_PER_P_(8);
- break;
- case TILFMT_16BIT:
- x_bits = DMM_TILER_CONT_WIDTH_BITS_(16);
- y_bits = DMM_TILER_CONT_HEIGHT_BITS_(16);
- alignment = DMM_SHIFT_PER_P_(16);
- break;
- case TILFMT_32BIT:
- x_bits = DMM_TILER_CONT_WIDTH_BITS_(32);
- y_bits = DMM_TILER_CONT_HEIGHT_BITS_(32);
- alignment = DMM_SHIFT_PER_P_(32);
- break;
- case TILFMT_PAGE:
- default:
- x_bits = DMM_TILER_CONT_WIDTH_BITS_(PAGE);
- y_bits = DMM_TILER_CONT_HEIGHT_BITS_(PAGE);
- alignment = DMM_SHIFT_PER_P_(PAGE);
- break;
- }
+ x_bits = CONT_WIDTH_BITS - geom[fmt].x_shft;
+ y_bits = CONT_HEIGHT_BITS - geom[fmt].y_shft;
+ alignment = geom[fmt].x_shft + geom[fmt].y_shft;
- x_mask = DMM_TILER_MASK(x_bits);
- y_mask = DMM_TILER_MASK(y_bits);
+ x_mask = MASK(x_bits);
+ y_mask = MASK(y_bits);
if (x < 0 || x > x_mask || y < 0 || y > y_mask)
return 0;
@@ -197,16 +191,8 @@ static u32 tiler_get_address(struct tiler_view_orient orient,
else
tmp = ((y << x_bits) + x);
- return (u32)
- TIL_ADDR((tmp << alignment), (orient.rotate_90 ? 1 : 0),
- (orient.y_invert ? 1 : 0), (orient.x_invert ? 1 : 0),
- fmt);
-}
-
-void tiler_geom_init(struct tiler_ops *tiler)
-{
- tiler->xy = tiler_get_natural_xy;
- tiler->addr = tiler_get_address;
+ return TIL_ADDR((tmp << alignment), orient.rotate_90,
+ orient.y_invert, orient.x_invert, fmt);
}
u32 tiler_reorient_addr(u32 tsptr, struct tiler_view_orient orient)
@@ -224,51 +210,35 @@ u32 tiler_get_natural_addr(void *sys_ptr)
}
EXPORT_SYMBOL(tiler_get_natural_addr);
-u32 tiler_reorient_topleft(u32 tsptr, struct tiler_view_orient orient,
- u32 width, u32 height)
+u32 tiler_topleft(u32 tsptr, u32 width, u32 height)
{
- enum tiler_fmt fmt;
u32 x, y;
-
- fmt = TILER_GET_ACC_MODE(tsptr);
+ enum tiler_fmt fmt = TILER_GET_ACC_MODE(tsptr);
+ struct tiler_view_orient orient;
+ orient.x_invert = DMM_IS_X_INVERTED(tsptr);
+ orient.y_invert = DMM_IS_Y_INVERTED(tsptr);
+ orient.rotate_90 = DMM_IS_ROTATED(tsptr);
tiler_get_natural_xy(tsptr, &x, &y);
if (DMM_IS_X_INVERTED(tsptr))
- x -= width - 1;
- if (DMM_IS_Y_INVERTED(tsptr))
- y -= height - 1;
-
- if (orient.x_invert)
x += width - 1;
- if (orient.y_invert)
+ if (DMM_IS_Y_INVERTED(tsptr))
y += height - 1;
+
return tiler_get_address(orient, fmt, x, y);
}
-EXPORT_SYMBOL(tiler_reorient_topleft);
+EXPORT_SYMBOL(tiler_topleft);
-u32 tiler_stride(u32 tsptr)
+u32 tiler_offset_addr(u32 tsptr, u32 x, u32 y)
{
- enum tiler_fmt fmt;
+ enum tiler_fmt fmt = TILER_GET_ACC_MODE(tsptr);
+ bool rotated = DMM_IS_ROTATED(tsptr);
- fmt = TILER_GET_ACC_MODE(tsptr);
-
- switch (fmt) {
- case TILFMT_8BIT:
- return DMM_IS_ROTATED(tsptr) ?
- DMM_TILER_STRIDE_90_(8) : DMM_TILER_STRIDE_0_(8);
- case TILFMT_16BIT:
- return DMM_IS_ROTATED(tsptr) ?
- DMM_TILER_STRIDE_90_(16) : DMM_TILER_STRIDE_0_(16);
- case TILFMT_32BIT:
- return DMM_IS_ROTATED(tsptr) ?
- DMM_TILER_STRIDE_90_(32) : DMM_TILER_STRIDE_0_(32);
- default:
- return 0;
- }
+ return tsptr + x * geom[fmt].bpp_m + y * tiler_stride(fmt, rotated);
}
-EXPORT_SYMBOL(tiler_stride);
+EXPORT_SYMBOL(tiler_offset_addr);
void tiler_rotate_view(struct tiler_view_orient *orient, u32 rotation)
{
@@ -288,3 +258,26 @@ void tiler_rotate_view(struct tiler_view_orient *orient, u32 rotation)
}
}
EXPORT_SYMBOL(tiler_rotate_view);
+
+void tiler_geom_init(struct tiler_ops *tiler)
+{
+ struct tiler_geom *g;
+
+ tiler->xy = tiler_get_natural_xy;
+ tiler->addr = tiler_get_address;
+ tiler->geom = get_geom;
+
+ tiler->page = TILER_PAGE;
+ tiler->width = TILER_WIDTH;
+ tiler->height = TILER_HEIGHT;
+
+ /* calculate geometry */
+ for (g = geom; g < geom + TILER_FORMATS; g++) {
+ g->bpp_m = g->bpp = 1 << (g->x_shft + g->y_shft);
+ g->slot_w = 1 << (SLOT_WIDTH_BITS - g->x_shft);
+ g->slot_h = 1 << (SLOT_HEIGHT_BITS - g->y_shft);
+ }
+
+ /* set bpp_m = 1 for page mode as most applications deal in byte data */
+ geom[TILFMT_PAGE].bpp_m = 1;
+}
diff --git a/drivers/media/video/tiler/tiler-main.c b/drivers/media/video/tiler/tiler-main.c
index 7c6e4ca83f2..8e6211edb94 100644
--- a/drivers/media/video/tiler/tiler-main.c
+++ b/drivers/media/video/tiler/tiler-main.c
@@ -79,10 +79,10 @@ static struct tcm *tcm[TILER_FORMATS];
static struct tmm *tmm[TILER_FORMATS];
#define TCM(fmt) tcm[(fmt) - TILFMT_8BIT]
-#define TCM_SS(ssptr) TCM(TILER_GET_ACC_MODE(ssptr))
+#define TCM_SS(ssptr) TCM(tiler_fmt(ssptr))
#define TCM_SET(fmt, i) tcm[(fmt) - TILFMT_8BIT] = i
#define TMM(fmt) tmm[(fmt) - TILFMT_8BIT]
-#define TMM_SS(ssptr) TMM(TILER_GET_ACC_MODE(ssptr))
+#define TMM_SS(ssptr) TMM(tiler_fmt(ssptr))
#define TMM_SET(fmt, i) tmm[(fmt) - TILFMT_8BIT] = i
/*
@@ -290,46 +290,33 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height,
/* output: x_area, y_area, band, align, offs in slots */
/* slot width, height, and row size */
- u32 slot_w, slot_h, slot_row, bpp, min_align;
+ u32 slot_row, min_align;
+ const struct tiler_geom *g;
/* align must be 2 power */
if (*align & (*align - 1))
return -1;
- switch (fmt) {
- case TILFMT_8BIT:
- slot_w = DMM_PAGE_DIMM_X_MODE_8;
- slot_h = DMM_PAGE_DIMM_Y_MODE_8;
- bpp = 1;
- break;
- case TILFMT_16BIT:
- slot_w = DMM_PAGE_DIMM_X_MODE_16;
- slot_h = DMM_PAGE_DIMM_Y_MODE_16;
- bpp = 2;
- break;
- case TILFMT_32BIT:
- slot_w = DMM_PAGE_DIMM_X_MODE_32;
- slot_h = DMM_PAGE_DIMM_Y_MODE_32;
- bpp = 4;
- break;
- case TILFMT_PAGE:
+ if (fmt == TILFMT_PAGE) {
/* adjust size to accomodate offset, only do page alignment */
*align = PAGE_SIZE;
width += *offs & (PAGE_SIZE - 1);
/* for 1D area keep the height (1), width is in tiler slots */
- *x_area = DIV_ROUND_UP(width, TILER_PAGE);
+ *x_area = DIV_ROUND_UP(width, tiler.page);
*y_area = *band = 1;
- if (*x_area * *y_area > TILER_WIDTH * TILER_HEIGHT)
+ if (*x_area * *y_area > tiler.width * tiler.height)
return -1;
return 0;
- default:
- return -EINVAL;
}
+ g = tiler.geom(fmt);
+ if (!g)
+ return -EINVAL;
+
/* get the # of bytes per row in 1 slot */
- slot_row = slot_w * bpp;
+ slot_row = g->slot_w * g->bpp;
/* how many slots are can be accessed via one physical page */
*band = PAGE_SIZE / slot_row;
@@ -339,26 +326,26 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height,
*align = ALIGN(*align ? : default_align, min_align);
/* offset must be multiple of bpp */
- if (*offs & (bpp - 1) || *offs >= *align)
+ if (*offs & (g->bpp - 1) || *offs >= *align)
return -EINVAL;
/* round down the offset to the nearest slot size, and increase width
to allow space for having the correct offset */
- width += (*offs & (min_align - 1)) / bpp;
+ width += (*offs & (min_align - 1)) / g->bpp;
if (in_offs)
*in_offs = *offs & (min_align - 1);
*offs &= ~(min_align - 1);
/* expand width to block size */
- width = ALIGN(width, min_align / bpp);
+ width = ALIGN(width, min_align / g->bpp);
/* adjust to slots */
- *x_area = DIV_ROUND_UP(width, slot_w);
- *y_area = DIV_ROUND_UP(height, slot_h);
+ *x_area = DIV_ROUND_UP(width, g->slot_w);
+ *y_area = DIV_ROUND_UP(height, g->slot_h);
*align /= slot_row;
*offs /= slot_row;
- if (*x_area > TILER_WIDTH || *y_area > TILER_HEIGHT)
+ if (*x_area > tiler.width || *y_area > tiler.height)
return -1;
return 0x0;
}
@@ -525,13 +512,14 @@ 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;
+ int a = PAGE_SIZE / tiler.geom(TILFMT_8BIT)->slot_w;
struct mem_info *mi = NULL;
struct area_info *ai = NULL;
struct list_head *pos;
/* reserve area */
- ai = area_new_m(w, h, 64, TILFMT_8BIT, gi);
+ ai = area_new_m(w, h, a, TILFMT_8BIT, gi);
if (!ai)
return -ENOMEM;
@@ -674,7 +662,7 @@ find_n_lock(u32 key, u32 id, struct gid_info *gi) {
/* is id is ssptr, we know if block is 1D or 2D by the address,
so we optimize lookup */
if (!ssptr_id ||
- TILER_GET_ACC_MODE(id) == TILFMT_PAGE) {
+ tiler_fmt(id) == TILFMT_PAGE) {
list_for_each_entry(mi, &gi->onedim, by_area) {
if (mi->blk.key == key && mi->blk.id == id)
goto done;
@@ -682,7 +670,7 @@ find_n_lock(u32 key, u32 id, struct gid_info *gi) {
}
if (!ssptr_id ||
- TILER_GET_ACC_MODE(id) != TILFMT_PAGE) {
+ tiler_fmt(id) != TILFMT_PAGE) {
list_for_each_entry(ai, &gi->areas, by_gid) {
list_for_each_entry(mi, &ai->blocks, by_area) {
if (mi->blk.key == key &&
@@ -804,19 +792,22 @@ static struct mem_info *find_block_by_ssptr(u32 sys_addr)
struct tcm_pt pt;
u32 x, y;
enum tiler_fmt fmt;
+ const struct tiler_geom *g;
fmt = tiler_fmt(sys_addr);
if (fmt == TILFMT_INVALID)
return NULL;
+ g = tiler.geom(fmt);
+
/* convert x & y pixel coordinates to slot coordinates */
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);
+ pt.x = x / g->slot_w;
+ pt.y = y / g->slot_h;
mutex_lock(&mtx);
list_for_each_entry(i, &blocks, global) {
- if (tiler_fmt(i->blk.phys) == TILER_GET_ACC_MODE(sys_addr) &&
+ if (tiler_fmt(i->blk.phys) == tiler_fmt(sys_addr) &&
tcm_is_in(pt, i->area)) {
i->refs++;
goto found;
@@ -833,7 +824,7 @@ found:
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);
+ blk->fmt = tiler_fmt(i->blk.phys);
blk->ssptr = i->blk.phys;
if (blk->fmt == TILFMT_PAGE) {
@@ -863,6 +854,7 @@ static struct mem_info *__get_area(enum tiler_fmt fmt, u32 width, u32 height,
u16 x, y, band, in_offs = 0;
struct mem_info *mi = NULL;
struct tiler_view_orient orient = {0};
+ const struct tiler_geom *g = tiler.geom(fmt);
/* calculate dimensions, band, offs and alignment in slots */
if (__analize_area(fmt, width, height, &x, &y, &band, &align, &offs,
@@ -899,10 +891,7 @@ static struct mem_info *__get_area(enum tiler_fmt fmt, u32 width, u32 height,
mutex_unlock(&mtx);
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 :
- fmt == TILFMT_8BIT ? 64 : 32))
+ mi->area.p0.x * g->slot_w, mi->area.p0.y * g->slot_h)
+ TILER_ALIAS_BASE + in_offs;
return mi;
}
@@ -1150,9 +1139,9 @@ static s32 __init tiler_init(void)
return -EINVAL;
/* Allocate tiler container manager (we share 1 on OMAP4) */
- div_pt.x = TILER_WIDTH; /* hardcoded default */
- div_pt.y = (3 * TILER_HEIGHT) / 4;
- sita = sita_init(TILER_WIDTH, TILER_HEIGHT, (void *)&div_pt);
+ div_pt.x = tiler.width; /* hardcoded default */
+ div_pt.y = (3 * tiler.height) / 4;
+ sita = sita_init(tiler.width, tiler.height, (void *)&div_pt);
TCM_SET(TILFMT_8BIT, sita);
TCM_SET(TILFMT_16BIT, sita);
diff --git a/drivers/media/video/tiler/tiler-reserve.c b/drivers/media/video/tiler/tiler-reserve.c
index 1ca4cec82f8..fd3e1734f4b 100644
--- a/drivers/media/video/tiler/tiler-reserve.c
+++ b/drivers/media/video/tiler/tiler-reserve.c
@@ -22,6 +22,8 @@
#include "_tiler.h"
static struct tiler_ops *ops;
+static int band_8; /* 8-bit band in slots */
+static int band_16; /* 16-bit band in slots */
/* 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
@@ -60,7 +62,7 @@ static u32 tiler_best2pack(u16 o, u16 w, u16 e, u16 b, u16 *n, u16 *area)
* == align(o + (n-1) * e + w, b) - trim((o + (n-1) * e, b) for all n
*/
while (m < max_n &&
- o + m * e + w <= TILER_WIDTH &&
+ o + m * e + w <= ops->width &&
stride == ALIGN(ar - o - m * e, b)) {
/* get efficiency */
m++;
@@ -84,8 +86,8 @@ static u32 tiler_best2pack(u16 o, u16 w, u16 e, u16 b, u16 *n, u16 *area)
/* assumptions: w > 0, o < a, 2 <= a */
static u16 nv12_separate(u16 o, u16 w, u16 a, u16 n, u16 *area)
{
- tiler_best2pack(o, w, ALIGN(w, a), 64, &n, area);
- tiler_best2pack(o / 2, (w + 1) / 2, ALIGN(w, a) / 2, 32, &n, area);
+ tiler_best2pack(o, w, ALIGN(w, a), band_8, &n, area);
+ tiler_best2pack(o / 2, (w + 1) / 2, ALIGN(w, a) / 2, band_16, &n, area);
*area *= 3;
return n;
}
@@ -104,7 +106,7 @@ static u16 nv12_separate(u16 o, u16 w, u16 a, u16 n, u16 *area)
static int nv12_A(u16 o, u16 w, u16 a, u16 *area, u16 n, u8 *p)
{
u16 x = o, u, l, m = 0;
- *area = 64;
+ *area = band_8;
while (x + w < *area && m < n) {
/* current 8bit upper bound (a) is next 8bit lower bound (B) */
@@ -149,7 +151,7 @@ static int nv12_B(u16 o, u16 w, u16 a, u16 *area, u16 n, u8 *p)
u16 o2 = o1 + (a >> 2); /* 2nd half offset */
u16 e2 = e1 + (a >> 2); /* 2nd half end offset */
u16 m = 0;
- *area = 64;
+ *area = band_8;
/* ensure 16-bit blocks don't overlap 8-bit blocks */
@@ -171,7 +173,7 @@ static int nv12_C(u16 o, u16 w, u16 a, u16 *area, u16 n, u8 *p)
{
int m = 0;
u16 o2, e = ALIGN(w, a), i = 0, j = 0;
- *area = 64;
+ *area = band_8;
o2 = *area - (a - (o + w) % a) % a; /* end of last possible block */
m = (min(o2 - 2 * o, 2 * o2 - o - *area) / 3 - w) / e + 1;
@@ -191,11 +193,11 @@ static int nv12_C(u16 o, u16 w, u16 a, u16 *area, u16 n, u8 *p)
static int nv12_D(u16 o, u16 w, u16 a, u16 *area, u16 n, u8 *p)
{
u16 o1, w1 = (w + 1) >> 1, d;
- *area = ALIGN(o + w, 64);
+ *area = ALIGN(o + w, band_8);
for (d = 0; n > 0 && d + o + w <= *area; d += a) {
/* fit 16-bit before 8-bit */
- o1 = ((o + d) % 64) >> 1;
+ o1 = ((o + d) % band_8) >> 1;
if (o1 + w1 <= o + d) {
*p++ = o + d;
*p++ = o1;
@@ -203,7 +205,7 @@ static int nv12_D(u16 o, u16 w, u16 a, u16 *area, u16 n, u8 *p)
}
/* fit 16-bit after 8-bit */
- o1 += ALIGN(d + o + w - o1, 32);
+ o1 += ALIGN(d + o + w - o1, band_16);
if (o1 + w1 <= *area) {
*p++ = o;
*p++ = o1;
@@ -310,19 +312,21 @@ static u16 nv12_together(u16 o, u16 w, u16 a, u16 n, u16 *area, u8 *packing)
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) */
- u16 w, h, band, a = MAX(128, align), o = offs, eff_w;
+ u16 w, h, band, a = align, o = offs, eff_w;
struct gid_info *gi;
int res = 0, res2, i;
u16 n_t, n_s, area_t, area_s;
u8 packing[2 * 21];
struct list_head reserved = LIST_HEAD_INIT(reserved);
+ /* adjust alignment to the largest slot width (128 bytes) */
+ a = MAX(PAGE_SIZE / MIN(band_8, band_16), a);
+
/* Check input parameters for correctness, and support */
if (!width || !height || !n ||
offs >= align || offs & 1 ||
align >= PAGE_SIZE ||
- n > TILER_WIDTH * TILER_HEIGHT / 2)
+ n > ops->width * ops->height / 2)
return;
/* calculate dimensions, band, offs and alignment in slots */
@@ -389,9 +393,10 @@ static void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height,
u32 align, u32 offs, u32 gid,
struct process_info *pi)
{
- u32 til_width, bpp, bpt, res = 0, i;
+ u32 bpt, res = 0, i;
u16 o = offs, a = align, band, w, h, e, n_try;
struct gid_info *gi;
+ const struct tiler_geom *g;
/* Check input parameters for correctness, and support */
if (!width || !height || !n ||
@@ -400,14 +405,13 @@ static void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height,
return;
/* tiler page width in pixels, bytes per pixel, tiler page in bytes */
- til_width = fmt == TILFMT_32BIT ? 32 : 64;
- bpp = 1 << (fmt - TILFMT_8BIT);
- bpt = til_width * bpp;
+ g = ops->geom(fmt);
+ bpt = g->slot_w * g->bpp;
/* check offset. Also, if block is less than half the mapping window,
the default allocation is sufficient. Also check for basic area
info. */
- if (width * bpp * 2 <= PAGE_SIZE ||
+ if (width * g->bpp * 2 <= PAGE_SIZE ||
ops->analize(fmt, width, height, &w, &h, &band, &a, &o, NULL))
return;
@@ -421,7 +425,7 @@ static void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height,
for (i = 0; i < n && res >= 0; i += res) {
/* blocks to allocate in one area */
- n_try = MIN(n - i, TILER_WIDTH);
+ n_try = MIN(n - i, ops->width);
tiler_best2pack(offs, w, e, band, &n_try, NULL);
res = -1;
@@ -460,4 +464,8 @@ void tiler_reserve_init(struct tiler_ops *tiler)
ops->reserve_nv12 = reserve_nv12;
ops->reserve = reserve_blocks;
ops->unreserve = unreserve_blocks;
+
+ band_8 = PAGE_SIZE / ops->geom(TILFMT_8BIT)->slot_w;
+ band_16 = PAGE_SIZE / ops->geom(TILFMT_16BIT)->slot_w
+ / ops->geom(TILFMT_16BIT)->bpp;
}