diff options
author | Lajos Molnar <molnar@ti.com> | 2011-04-07 08:41:28 +0100 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2011-04-07 08:41:28 +0100 |
commit | 67d891bca67ab1537cf99210677f79af11b996a6 (patch) | |
tree | 255d90d91872551d86b4039c01a4d5ac28250491 /drivers/media/video/tiler | |
parent | d16edfb337d41f717345a1e149f6039afa239f5e (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.h | 16 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-def.h | 50 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-geom.c | 273 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-main.c | 79 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-reserve.c | 44 |
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; } |