diff options
author | Lajos Molnar <molnar@ti.com> | 2010-06-29 04:31:17 -0400 |
---|---|---|
committer | Paolo Pisati <paolo.pisati@canonical.com> | 2012-08-17 04:18:57 -0400 |
commit | 23fcdd17c25413d244fb68ab78a7703a6d72c528 (patch) | |
tree | e7db7beebaa2bd95e056d504c1f0cfbf834626b7 | |
parent | bdaecc435e668cc39db7dd9fffe850bf36ce8927 (diff) |
TILER: Added support for granularity and in-tile offset.
Offset was cropped to tile boundaries. Now supporting full offset.
Granularity and alignment was combined as the same concept. Now
we support (min.) granularity even for larger aligmnents.
Granularity is the minimum TILER block size, which could be aligned
to a larger alignment value. This prevents allocating too much
TILER space in this case.
Signed-off-by: Lajos Molnar <molnar@ti.com>
-rw-r--r-- | drivers/media/video/tiler/tiler.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/media/video/tiler/tiler.c b/drivers/media/video/tiler/tiler.c index 6fdd409fc2e..ed0baa63468 100644 --- a/drivers/media/video/tiler/tiler.c +++ b/drivers/media/video/tiler/tiler.c | |||
@@ -195,13 +195,13 @@ static inline void _m_area_free(struct area_info *ai) | |||
195 | 195 | ||
196 | static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, | 196 | static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, |
197 | u16 *x_area, u16 *y_area, u16 *band, | 197 | u16 *x_area, u16 *y_area, u16 *band, |
198 | u16 *align, u16 *offs) | 198 | u16 *align, u16 *offs, u16 *in_offs) |
199 | { | 199 | { |
200 | /* input: width, height is in pixels, align, offs in bytes */ | 200 | /* input: width, height is in pixels, align, offs in bytes */ |
201 | /* output: x_area, y_area, band, align, offs in slots */ | 201 | /* output: x_area, y_area, band, align, offs in slots */ |
202 | 202 | ||
203 | /* slot width, height, and row size */ | 203 | /* slot width, height, and row size */ |
204 | u32 slot_w, slot_h, slot_row, bpp; | 204 | u32 slot_w, slot_h, slot_row, bpp, min_align; |
205 | 205 | ||
206 | /* align must be 2 power */ | 206 | /* align must be 2 power */ |
207 | if (*align & (*align - 1)) | 207 | if (*align & (*align - 1)) |
@@ -243,8 +243,9 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, | |||
243 | /* how many slots are can be accessed via one physical page */ | 243 | /* how many slots are can be accessed via one physical page */ |
244 | *band = PAGE_SIZE / slot_row; | 244 | *band = PAGE_SIZE / slot_row; |
245 | 245 | ||
246 | /* minimum alignment is 1 slot, default alignment is page size */ | 246 | /* minimum alignment is at least 1 slot. Use default if needed */ |
247 | *align = ALIGN(*align ? : PAGE_SIZE, slot_row); | 247 | min_align = slot_row; |
248 | *align = ALIGN(*align ? : PAGE_SIZE, min_align); | ||
248 | 249 | ||
249 | /* offset must be multiple of bpp */ | 250 | /* offset must be multiple of bpp */ |
250 | if (*offs & (bpp - 1)) | 251 | if (*offs & (bpp - 1)) |
@@ -252,8 +253,13 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, | |||
252 | 253 | ||
253 | /* round down the offset to the nearest slot size, and increase width | 254 | /* round down the offset to the nearest slot size, and increase width |
254 | to allow space for having the correct offset */ | 255 | to allow space for having the correct offset */ |
255 | width += (*offs & (*align - 1)) / bpp; | 256 | width += (*offs & (min_align - 1)) / bpp; |
256 | *offs &= ~(*align - 1); | 257 | if (in_offs) |
258 | *in_offs = *offs & (min_align - 1); | ||
259 | *offs &= ~(min_align - 1); | ||
260 | |||
261 | /* expand width to block size */ | ||
262 | width = ALIGN(width, min_align / bpp); | ||
257 | 263 | ||
258 | /* adjust to slots */ | 264 | /* adjust to slots */ |
259 | *x_area = DIV_ROUND_UP(width, slot_w); | 265 | *x_area = DIV_ROUND_UP(width, slot_w); |
@@ -438,6 +444,7 @@ static s32 _m_free(struct mem_info *mi) | |||
438 | kfree(mi->pg_ptr); | 444 | kfree(mi->pg_ptr); |
439 | } else if (mi->mem) { | 445 | } else if (mi->mem) { |
440 | tmm_free(TMM_SS(mi->sys_addr), mi->mem); | 446 | tmm_free(TMM_SS(mi->sys_addr), mi->mem); |
447 | clear_pat(TMM_SS(mi->sys_addr), &mi->area); | ||
441 | } | 448 | } |
442 | 449 | ||
443 | /* safe deletion as list may not have been assigned */ | 450 | /* safe deletion as list may not have been assigned */ |
@@ -452,7 +459,6 @@ static s32 _m_free(struct mem_info *mi) | |||
452 | 459 | ||
453 | /* check to see if area needs removing also */ | 460 | /* check to see if area needs removing also */ |
454 | if (ai && !--ai->nblocks) { | 461 | if (ai && !--ai->nblocks) { |
455 | clear_pat(TMM_SS(mi->sys_addr), &ai->area); | ||
456 | res = tcm_free(&ai->area); | 462 | res = tcm_free(&ai->area); |
457 | list_del(&ai->by_gid); | 463 | list_del(&ai->by_gid); |
458 | /* try to remove parent if it became empty */ | 464 | /* try to remove parent if it became empty */ |
@@ -462,7 +468,6 @@ static s32 _m_free(struct mem_info *mi) | |||
462 | } | 468 | } |
463 | } else { | 469 | } else { |
464 | /* remove 1D area */ | 470 | /* remove 1D area */ |
465 | clear_pat(TMM_SS(mi->sys_addr), &mi->area); | ||
466 | res = tcm_free(&mi->area); | 471 | res = tcm_free(&mi->area); |
467 | /* try to remove parent if it became empty */ | 472 | /* try to remove parent if it became empty */ |
468 | _m_try_free_group(mi->parent); | 473 | _m_try_free_group(mi->parent); |
@@ -732,11 +737,12 @@ done: | |||
732 | static struct mem_info *__get_area(enum tiler_fmt fmt, u32 width, u32 height, | 737 | static struct mem_info *__get_area(enum tiler_fmt fmt, u32 width, u32 height, |
733 | u16 align, u16 offs, struct gid_info *gi) | 738 | u16 align, u16 offs, struct gid_info *gi) |
734 | { | 739 | { |
735 | u16 x, y, band; | 740 | u16 x, y, band, in_offs = 0; |
736 | struct mem_info *mi = NULL; | 741 | struct mem_info *mi = NULL; |
737 | 742 | ||
738 | /* calculate dimensions, band, offs and alignment in slots */ | 743 | /* calculate dimensions, band, offs and alignment in slots */ |
739 | if (__analize_area(fmt, width, height, &x, &y, &band, &align, &offs)) | 744 | if (__analize_area(fmt, width, height, &x, &y, &band, &align, &offs, |
745 | &in_offs)) | ||
740 | return NULL; | 746 | return NULL; |
741 | 747 | ||
742 | if (fmt == TILFMT_PAGE) { | 748 | if (fmt == TILFMT_PAGE) { |
@@ -768,7 +774,8 @@ static struct mem_info *__get_area(enum tiler_fmt fmt, u32 width, u32 height, | |||
768 | gi->refs--; | 774 | gi->refs--; |
769 | mutex_unlock(&mtx); | 775 | mutex_unlock(&mtx); |
770 | 776 | ||
771 | mi->sys_addr = __get_alias_addr(fmt, mi->area.p0.x, mi->area.p0.y); | 777 | mi->sys_addr = __get_alias_addr(fmt, mi->area.p0.x, mi->area.p0.y) |
778 | + in_offs; | ||
772 | return mi; | 779 | return mi; |
773 | } | 780 | } |
774 | 781 | ||