aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Gross <andy.gross@ti.com>2011-06-10 00:25:33 -0500
committerSuman Anna <s-anna@ti.com>2011-06-17 22:39:58 -0500
commit2bf390d33eae05a6a8c44970852b15760d169103 (patch)
treec371a9c2137ef27f99a36bd29b97f7f41ab7f24f
parent36cbfc3594048f2cd10b3cd231b2b6f000fbaf53 (diff)
downloadkernel_samsung_tuna-2bf390d33eae05a6a8c44970852b15760d169103.zip
kernel_samsung_tuna-2bf390d33eae05a6a8c44970852b15760d169103.tar.gz
kernel_samsung_tuna-2bf390d33eae05a6a8c44970852b15760d169103.tar.bz2
TILER: Add ION APIs and refactor existing functions to use helper functions
Refactored alloc_block to use pin_memory(). Standardized ION API to the following functions: tiler_alloc_block_area tiler_free_block_area tiler_pin_block tiler_unpin_block Additional APIs: tiler_map_1d_block tiler_alloc_1d_block_area tiler_pin_memory Change-Id: I9132863d342e0a21ceac00adaba9386d174fc285 Signed-off-by: Andy Gross <andy.gross@ti.com> Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r--arch/arm/mach-omap2/include/mach/tiler.h87
-rw-r--r--drivers/media/video/tiler/tiler-main.c135
2 files changed, 193 insertions, 29 deletions
diff --git a/arch/arm/mach-omap2/include/mach/tiler.h b/arch/arm/mach-omap2/include/mach/tiler.h
index 6e25dcc..1bdc6bd 100644
--- a/arch/arm/mach-omap2/include/mach/tiler.h
+++ b/arch/arm/mach-omap2/include/mach/tiler.h
@@ -41,6 +41,7 @@
#define TILER_H
#include <linux/mm.h>
+#include <linux/scatterlist.h>
/*
* ----------------------------- API Definitions -----------------------------
@@ -378,9 +379,91 @@ struct tiler_pa_info {
typedef struct mem_info *tiler_blk_handle;
-/* NOTE: this will take ownership pa->mem (will free it) */
+/**
+ * Allocate a 1D area of container space in the Tiler
+ *
+ * @param pa ptr to tiler_pa_info structure
+ *
+ * @return handle Handle to tiler block information. NULL on error.
+ *
+ * NOTE: this will take ownership pa->mem (will free it)
+ *
+ */
tiler_blk_handle tiler_map_1d_block(struct tiler_pa_info *pa);
-void tiler_free_block(tiler_blk_handle block);
+
+/**
+ * Allocate an area of container space in the Tiler
+ *
+ * @param fmt Tiler bpp mode
+ * @param width Width in pixels
+ * @param height Height in pixels
+ * @param ssptr Value of tiler physical address of allocation
+ *
+ * @return handle Handle to tiler block information. NULL on error.
+ *
+ * NOTE: For 1D allocations, specify the full size in the width field, and
+ * specify a height of 1.
+ */
+tiler_blk_handle tiler_alloc_block_area(enum tiler_fmt fmt, u32 width,
+ u32 height, u32 *ssptr);
+
+/**
+ * Free a reserved area in the Tiler
+ *
+ * @param handle Handle to tiler block information
+ *
+ */
+void tiler_free_block_area(tiler_blk_handle block);
+
+/**
+ * Pins a set of physical pages into the Tiler using the area defined in a
+ * handle
+ *
+ * @param handle Handle to tiler block information
+ * @param sg Scatterlist of physical pages
+ * @param nents Number of entries in scatterlist
+ *
+ * @return error status.
+ */
+s32 tiler_pin_block(tiler_blk_handle handle, struct scatterlist *sg, u32 nents);
+
+/**
+ * Unpins a set of physical pages from the Tiler
+ *
+ * @param handle Handle to tiler block information
+ *
+ */
+void tiler_unpin_block(tiler_blk_handle handle);
+
+
+/**
+ * Gives Tiler physical address for a given tiler_blk_handle
+ *
+ * @param handle Handle to tiler block information
+ *
+ * @return phsyical address. NULL on error.
+ */
+u32 tiler_handle_to_phys(tiler_blk_handle handle);
+
+/**
+ * Gives memory requirements for a given container allocation
+ *
+ * @param fmt Tiler bpp mode
+ * @param width Width in pixels
+ * @param height Height in pixels
+ *
+ * @return Number of pages required. On error, returns 0
+ */
+u32 tiler_memsize(enum tiler_fmt fmt, u32 width, u32 height);
+
+/**
+ * Returns virtual stride of a tiler block
+ *
+ * @param handle Handle to tiler block allocation
+ *
+ * @return Size of virtual stride
+ */
+u32 tiler_block_vstride(tiler_blk_handle handle);
/*
* ---------------------------- IOCTL Definitions ----------------------------
diff --git a/drivers/media/video/tiler/tiler-main.c b/drivers/media/video/tiler/tiler-main.c
index e972196..d1d3c6e 100644
--- a/drivers/media/video/tiler/tiler-main.c
+++ b/drivers/media/video/tiler/tiler-main.c
@@ -889,7 +889,7 @@ static struct mem_info *alloc_block_area(enum tiler_fmt fmt, u32 width,
struct mem_info *mi = NULL;
struct gid_info *gi = NULL;
- /* only support up to page alignment */
+ /* validate parameters */
if (!pi)
return ERR_PTR(-EINVAL);
@@ -987,7 +987,7 @@ static s32 alloc_block(enum tiler_fmt fmt, u32 width, u32 height,
{
struct mem_info *mi;
struct tiler_pa_info *pa = NULL;
- s32 res;
+ int res;
*info = NULL;
@@ -996,20 +996,19 @@ static s32 alloc_block(enum tiler_fmt fmt, u32 width, u32 height,
if (IS_ERR_OR_NULL(mi))
return mi ? -ENOMEM : PTR_ERR(mi);
- /* allocate and map if mapping is supported */
- if (tmm_can_pin(tmm[fmt])) {
- /* allocate back memory */
- pa = get_new_pa(tmm[fmt], tcm_sizeof(mi->area));
- if (!pa)
- goto cleanup;
-
- /* pin memory */
- res = pin_memory(mi, pa);
- free_pa(pa);
- if (res)
- goto cleanup;
+ /* allocate memory */
+ pa = get_new_pa(tmm[fmt], tcm_sizeof(mi->area));
+ if (IS_ERR_OR_NULL(pa)) {
+ res = -ENOMEM;
+ goto cleanup;
}
+ /* pin memory */
+ res = pin_memory(mi, pa);
+ free_pa(pa);
+ if (res)
+ goto cleanup;
+
*info = mi;
return 0;
@@ -1017,7 +1016,36 @@ cleanup:
mutex_lock(&mtx);
_m_free(mi);
mutex_unlock(&mtx);
- return -ENOMEM;
+ return res;
+}
+
+/* gets physical pages from scatterlist */
+static struct tiler_pa_info *scatterlist_to_pa(struct scatterlist *sglist,
+ u32 nents)
+{
+ int i;
+ struct scatterlist *sg;
+ struct tiler_pa_info *pa = NULL;
+ u32 *mem = NULL;
+
+ pa = kzalloc(sizeof(*pa), GFP_KERNEL);
+ if (!pa)
+ return NULL;
+
+ mem = kzalloc(nents * sizeof(*mem), GFP_KERNEL);
+ if (!mem) {
+ kfree(pa);
+ return NULL;
+ }
+
+ /* iterate over scatterlist and build up mem information */
+ for_each_sg(sglist, sg, nents, i)
+ mem[i] = sg_phys(sg);
+
+ pa->mem = mem;
+ pa->memtype = TILER_MEM_USING;
+ pa->num_pg = nents;
+ return pa;
}
/* get physical pages of a user block */
@@ -1116,6 +1144,7 @@ static struct tiler_pa_info *user_block_to_pa(u32 usr_addr, u32 num_pg)
return pa;
}
+/* allocate area from container and pin memory */
static s32 pin_any_block(enum tiler_fmt fmt, u32 width, u32 height,
u32 key, u32 gid, struct process_info *pi,
struct mem_info **info, struct tiler_pa_info *pa)
@@ -1125,10 +1154,6 @@ static s32 pin_any_block(enum tiler_fmt fmt, u32 width, u32 height,
*info = NULL;
- /* we only support mapping a user buffer in page mode */
- if (fmt != TILFMT_PAGE)
- goto done;
-
/* check if mapping is supported by tmm */
if (!tmm_can_pin(tmm[fmt]))
goto done;
@@ -1162,6 +1187,10 @@ static s32 pin_block(enum tiler_fmt fmt, u32 width, u32 height,
{
struct tiler_pa_info *pa = NULL;
+ /* we only support mapping a user buffer in page mode */
+ if (fmt != TILFMT_PAGE)
+ return -ENOMEM;
+
/* get user pages */
pa = user_block_to_pa(usr_addr, DIV_ROUND_UP(width, PAGE_SIZE));
if (IS_ERR_OR_NULL(pa))
@@ -1170,6 +1199,23 @@ static s32 pin_block(enum tiler_fmt fmt, u32 width, u32 height,
return pin_any_block(fmt, width, height, key, gid, pi, info, pa);
}
+s32 tiler_pin_block(tiler_blk_handle block, struct scatterlist *sg, u32 nents)
+{
+ struct tiler_pa_info *pa = NULL;
+ int res;
+
+ /* get user pages */
+ pa = scatterlist_to_pa(sg, nents);
+ if (IS_ERR_OR_NULL(pa))
+ return pa ? PTR_ERR(pa) : -ENOMEM;
+
+ res = pin_memory(block, pa);
+ free_pa(pa);
+
+ return res;
+}
+EXPORT_SYMBOL(tiler_pin_block);
+
/*
* Driver code
* ==========================================================================
@@ -1357,37 +1403,72 @@ tiler_blk_handle tiler_map_1d_block(struct tiler_pa_info *pa)
}
EXPORT_SYMBOL(tiler_map_1d_block);
-void tiler_free_block(tiler_blk_handle block)
+void tiler_free_block_area(tiler_blk_handle block)
{
mutex_lock(&mtx);
_m_try_free(block);
mutex_unlock(&mtx);
}
-EXPORT_SYMBOL(tiler_free_block);
+EXPORT_SYMBOL(tiler_free_block_area);
-tiler_blk_handle tiler_alloc_block_area(u32 size)
+tiler_blk_handle tiler_alloc_block_area(enum tiler_fmt fmt, u32 width,
+ u32 height, u32 *ssptr)
{
- return alloc_block_area(TILFMT_PAGE, size >> PAGE_SHIFT, 1, 0, 0,
- __get_pi(0, true));
+ struct mem_info *mi;
+ *ssptr = 0;
+
+ mi = alloc_block_area(fmt, width, height, 0, 0, __get_pi(0, true));
+
+ if (IS_ERR_OR_NULL(mi))
+ goto done;
+
+ *ssptr = mi->blk.phys;
+
+done:
+ return mi;
}
EXPORT_SYMBOL(tiler_alloc_block_area);
-void tiler_unpin_memory(tiler_blk_handle block)
+tiler_blk_handle tiler_alloc_1d_block_area(u32 size)
+{
+ return alloc_block_area(TILFMT_PAGE, size >> PAGE_SHIFT, 1, 0, 0,
+ __get_pi(0, true));
+}
+EXPORT_SYMBOL(tiler_alloc_1d_block_area);
+
+void tiler_unpin_block(tiler_blk_handle block)
{
mutex_lock(&mtx);
_m_unpin(block);
mutex_unlock(&mtx);
}
-EXPORT_SYMBOL(tiler_unpin_memory);
+EXPORT_SYMBOL(tiler_unpin_block);
s32 tiler_pin_memory(tiler_blk_handle block, struct tiler_pa_info *pa)
{
struct tiler_pa_info *pa_tmp = kmemdup(pa, sizeof(*pa), GFP_KERNEL);
- tiler_unpin_memory(block);
+ tiler_unpin_block(block);
return pin_memory(block, pa_tmp);
}
EXPORT_SYMBOL(tiler_pin_memory);
+u32 tiler_memsize(enum tiler_fmt fmt, u32 width, u32 height)
+{
+ u16 x, y, band, align;
+
+ if (tiler.analize(fmt, width, height, &x, &y, &align, &band))
+ return 0;
+ else
+ return x*y;
+}
+EXPORT_SYMBOL(tiler_memsize);
+
+u32 tiler_block_vstride(tiler_blk_handle block)
+{
+ return tiler_vstride(&block->blk);
+}
+EXPORT_SYMBOL(tiler_block_vstride);
+
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Lajos Molnar <molnar@ti.com>");
MODULE_AUTHOR("David Sin <davidsin@ti.com>");