summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Artamonov <kartamonov@nvidia.com>2012-06-12 19:00:58 +0300
committerSimone Willett <swillett@nvidia.com>2012-08-28 12:40:48 -0700
commit1fecf8089ef4bc65e92f341684b3c541eecd5eab (patch)
tree44c69c83fc02bc9dce49b99ca392a07552c5938e
parent9b55075dfad2224545aef164f63869453face3fd (diff)
video: tegra: nvmap: implement full L2 clean/flush
When allocation is bigger than L2 size it is more optimal to flush or writeback whole L2 instead of doing maintenance for each allocated page. bug 983964 Signed-off-by: Kirill Artamonov <kartamonov@nvidia.com> Change-Id: Ieaa70875b92920567ad7cd75eca6eac8197f46de Reviewed-on: http://git-master/r/108511 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
-rw-r--r--drivers/video/tegra/Kconfig10
-rw-r--r--drivers/video/tegra/nvmap/nvmap_common.h3
-rw-r--r--drivers/video/tegra/nvmap/nvmap_dev.c2
-rw-r--r--drivers/video/tegra/nvmap/nvmap_ioctl.c42
4 files changed, 45 insertions, 12 deletions
diff --git a/drivers/video/tegra/Kconfig b/drivers/video/tegra/Kconfig
index 650c418ccb52..68cf54264403 100644
--- a/drivers/video/tegra/Kconfig
+++ b/drivers/video/tegra/Kconfig
@@ -119,7 +119,7 @@ config NVMAP_PAGE_POOL_SIZE
default 0x0
config NVMAP_CACHE_MAINT_BY_SET_WAYS
- bool "Enalbe cache maintenance by set/ways"
+ bool "Enable cache maintenance by set/ways"
depends on TEGRA_NVMAP
help
Say Y here to reduce cache maintenance overhead by MVA.
@@ -127,6 +127,14 @@ config NVMAP_CACHE_MAINT_BY_SET_WAYS
where inner cache includes only L1. For the systems, where inner cache
includes L1 and L2, keep this option disabled.
+config NVMAP_OUTER_CACHE_MAINT_BY_SET_WAYS
+ bool "Enable outer cache maintenance by set/ways"
+ depends on TEGRA_NVMAP
+ help
+ Say Y here if you want to optimize cache maintenance for ranges
+ bigger than size of outer cache. This option has no effect on
+ system without outer cache.
+
config NVMAP_VPR
bool "Enable VPR Heap."
depends on TEGRA_NVMAP
diff --git a/drivers/video/tegra/nvmap/nvmap_common.h b/drivers/video/tegra/nvmap/nvmap_common.h
index 6da010720bb2..2a1e2b4b3c4b 100644
--- a/drivers/video/tegra/nvmap/nvmap_common.h
+++ b/drivers/video/tegra/nvmap/nvmap_common.h
@@ -23,7 +23,8 @@
extern void v7_flush_kern_cache_all(void *);
extern void v7_clean_kern_cache_all(void *);
-#define FLUSH_CLEAN_BY_SET_WAY_THRESHOLD (8 * PAGE_SIZE)
+#define FLUSH_CLEAN_BY_SET_WAY_THRESHOLD_INNER (8 * PAGE_SIZE)
+#define FLUSH_CLEAN_BY_SET_WAY_THRESHOLD_OUTER (1024 * 1024)
static inline void inner_flush_cache_all(void)
{
diff --git a/drivers/video/tegra/nvmap/nvmap_dev.c b/drivers/video/tegra/nvmap/nvmap_dev.c
index 02ccaeec4965..0c12348db88e 100644
--- a/drivers/video/tegra/nvmap/nvmap_dev.c
+++ b/drivers/video/tegra/nvmap/nvmap_dev.c
@@ -290,7 +290,7 @@ int nvmap_flush_heap_block(struct nvmap_client *client,
if (prot == NVMAP_HANDLE_UNCACHEABLE || prot == NVMAP_HANDLE_WRITE_COMBINE)
goto out;
- if (len >= FLUSH_CLEAN_BY_SET_WAY_THRESHOLD) {
+ if (len >= FLUSH_CLEAN_BY_SET_WAY_THRESHOLD_INNER) {
inner_flush_cache_all();
if (prot != NVMAP_HANDLE_INNER_CACHEABLE)
outer_flush_range(block->base, block->base + len);
diff --git a/drivers/video/tegra/nvmap/nvmap_ioctl.c b/drivers/video/tegra/nvmap/nvmap_ioctl.c
index e3adc0abc174..da974b2c6846 100644
--- a/drivers/video/tegra/nvmap/nvmap_ioctl.c
+++ b/drivers/video/tegra/nvmap/nvmap_ioctl.c
@@ -550,14 +550,32 @@ static void heap_page_cache_maint(struct nvmap_client *client,
}
}
+static bool fast_cache_maint_outer(unsigned long start,
+ unsigned long end, unsigned int op)
+{
+ bool result = false;
+#if defined(CONFIG_NVMAP_OUTER_CACHE_MAINT_BY_SET_WAYS)
+ if (end - start >= FLUSH_CLEAN_BY_SET_WAY_THRESHOLD_OUTER) {
+ if (op == NVMAP_CACHE_OP_WB_INV) {
+ outer_flush_all();
+ result = true;
+ }
+ if (op == NVMAP_CACHE_OP_WB) {
+ outer_clean_all();
+ result = true;
+ }
+ }
+#endif
+ return result;
+}
+
static bool fast_cache_maint(struct nvmap_client *client, struct nvmap_handle *h,
unsigned long start, unsigned long end, unsigned int op)
{
int ret = false;
-
#if defined(CONFIG_NVMAP_CACHE_MAINT_BY_SET_WAYS)
if ((op == NVMAP_CACHE_OP_INV) ||
- ((end - start) < FLUSH_CLEAN_BY_SET_WAY_THRESHOLD))
+ ((end - start) < FLUSH_CLEAN_BY_SET_WAY_THRESHOLD_INNER))
goto out;
if (op == NVMAP_CACHE_OP_WB_INV)
@@ -565,13 +583,19 @@ static bool fast_cache_maint(struct nvmap_client *client, struct nvmap_handle *h
else if (op == NVMAP_CACHE_OP_WB)
inner_clean_cache_all();
- if (h->heap_pgalloc && (h->flags != NVMAP_HANDLE_INNER_CACHEABLE)) {
- heap_page_cache_maint(client, h, start, end, op,
- false, true, NULL, 0, 0);
- } else if (h->flags != NVMAP_HANDLE_INNER_CACHEABLE) {
- start += h->carveout->base;
- end += h->carveout->base;
- outer_cache_maint(op, start, end - start);
+ /* outer maintenance */
+ if (h->flags != NVMAP_HANDLE_INNER_CACHEABLE ) {
+ if(!fast_cache_maint_outer(start, end, op))
+ {
+ if (h->heap_pgalloc) {
+ heap_page_cache_maint(client, h, start,
+ end, op, false, true, NULL, 0, 0);
+ } else {
+ start += h->carveout->base;
+ end += h->carveout->base;
+ outer_cache_maint(op, start, end - start);
+ }
+ }
}
ret = true;
out: