diff options
author | Kirill Artamonov <kartamonov@nvidia.com> | 2012-06-12 19:00:58 +0300 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-08-28 12:40:48 -0700 |
commit | 1fecf8089ef4bc65e92f341684b3c541eecd5eab (patch) | |
tree | 44c69c83fc02bc9dce49b99ca392a07552c5938e | |
parent | 9b55075dfad2224545aef164f63869453face3fd (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/Kconfig | 10 | ||||
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_common.h | 3 | ||||
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_dev.c | 2 | ||||
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_ioctl.c | 42 |
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: |