diff options
author | Krishna Reddy <vdumpa@nvidia.com> | 2011-08-30 10:15:44 -0700 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2011-12-15 11:52:44 +0530 |
commit | 65e8c13a3b1c0259b80a36afbefc9b2d443216b4 (patch) | |
tree | 9021d5ceb2f0aa81e514bd8484fadb77bd331c3f | |
parent | 041b12a14e1849d92c03b0df99ee9b90e3acafdd (diff) |
video: tegra: nvmap: Update page attributes as per request.
After allocating pages, Update page attributes in kernel
page table as per mem type requested.
Bug 865816
Reviewed-on: http://git-master/r/56334
Reviewed-by: Lokesh Pathak <lpathak@nvidia.com>
Tested-by: Lokesh Pathak <lpathak@nvidia.com>
(cherry picked from commit bea4d449f4ff7090e0c2797693d2348f4586d8f6)
Reviewed-on: http://git-master/r/62720
Tested-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-by: Hiro Sugawara <hsugawara@nvidia.com>
Reviewed-by: Kaz Fukuoka <kfukuoka@nvidia.com>
Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
(cherry picked from commit 975fb95585543124de282faa4481433b147f61c6)
Change-Id: Iee71f8b37c405731314a1441cdb30ca848b41399
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-on: http://git-master/r/68744
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_handle.c | 31 | ||||
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap_ioctl.c | 18 |
2 files changed, 33 insertions, 16 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap_handle.c b/drivers/video/tegra/nvmap/nvmap_handle.c index 4a0709c55581..924952932c85 100644 --- a/drivers/video/tegra/nvmap/nvmap_handle.c +++ b/drivers/video/tegra/nvmap/nvmap_handle.c @@ -106,6 +106,12 @@ void _nvmap_handle_free(struct nvmap_handle *h) nvmap_mru_remove(nvmap_get_share_from_dev(dev), h); + /* Restore page attributes. */ + if (h->flags == NVMAP_HANDLE_WRITE_COMBINE || + h->flags == NVMAP_HANDLE_UNCACHEABLE || + h->flags == NVMAP_HANDLE_INNER_CACHEABLE) + set_pages_array_wb(h->pgalloc.pages, nr_page); + if (h->pgalloc.area) tegra_iovmm_free_vm(h->pgalloc.area); @@ -146,7 +152,6 @@ static int handle_page_alloc(struct nvmap_client *client, pgprot_t prot; unsigned int i = 0; struct page **pages; - bool flush_inner = true; unsigned long base; pages = altalloc(nr_page * sizeof(*pages)); @@ -189,18 +194,26 @@ static int handle_page_alloc(struct nvmap_client *client, #endif } - /* Flush the cache for allocated pages*/ - if (size >= FLUSH_CLEAN_BY_SET_WAY_THRESHOLD) { - inner_flush_cache_all(); - flush_inner = false; - } + /* Update the pages mapping in kernel page table. */ + if (h->flags == NVMAP_HANDLE_WRITE_COMBINE) + set_pages_array_wc(pages, nr_page); + else if (h->flags == NVMAP_HANDLE_UNCACHEABLE) + set_pages_array_uc(pages, nr_page); + else if (h->flags == NVMAP_HANDLE_INNER_CACHEABLE) + set_pages_array_iwb(pages, nr_page); + else + goto skip_cache_flush; + + /* Flush the cache for allocated high mem pages only */ for (i = 0; i < nr_page; i++) { - if (flush_inner) + if (PageHighMem(pages[i])) { __flush_dcache_page(page_mapping(pages[i]), pages[i]); - base = page_to_phys(pages[i]); - outer_flush_range(base, base + PAGE_SIZE); + base = page_to_phys(pages[i]); + outer_flush_range(base, base + PAGE_SIZE); + } } +skip_cache_flush: h->size = size; h->pgalloc.pages = pages; h->pgalloc.contig = contiguous; diff --git a/drivers/video/tegra/nvmap/nvmap_ioctl.c b/drivers/video/tegra/nvmap/nvmap_ioctl.c index 8e64584b5e50..222e57083230 100644 --- a/drivers/video/tegra/nvmap/nvmap_ioctl.c +++ b/drivers/video/tegra/nvmap/nvmap_ioctl.c @@ -285,17 +285,24 @@ int nvmap_map_into_caller_ptr(struct file *filp, void __user *arg) vpriv->offs = op.offset; cache_flags = op.flags & NVMAP_HANDLE_CACHE_FLAG; - if (cache_flags == NVMAP_HANDLE_INNER_CACHEABLE || - cache_flags == NVMAP_HANDLE_CACHEABLE) { + if ((cache_flags == NVMAP_HANDLE_INNER_CACHEABLE || + cache_flags == NVMAP_HANDLE_CACHEABLE) && + (h->flags == NVMAP_HANDLE_UNCACHEABLE || + h->flags == NVMAP_HANDLE_WRITE_COMBINE)) { if (h->size & ~PAGE_MASK) { pr_err("\n%s:attempt to convert a buffer from uc/wc to" " wb, whose size is not a multiple of page size." " request ignored.\n", __func__); } else { + unsigned int nr_page = h->size >> PAGE_SHIFT; wmb(); /* override allocation time cache coherency attributes. */ h->flags &= ~NVMAP_HANDLE_CACHE_FLAG; h->flags |= cache_flags; + if (cache_flags == NVMAP_HANDLE_INNER_CACHEABLE) + set_pages_array_iwb(h->pgalloc.pages, nr_page); + else + set_pages_array_wb(h->pgalloc.pages, nr_page); } } vma->vm_page_prot = nvmap_pgprot(h, vma->vm_page_prot); @@ -569,11 +576,8 @@ static int cache_maint(struct nvmap_client *client, struct nvmap_handle *h, } wmb(); -#if defined(CONFIG_ARCH_TEGRA_2x_SOC) - if (h->flags == NVMAP_HANDLE_WRITE_COMBINE) - goto out; -#endif - if (h->flags == NVMAP_HANDLE_UNCACHEABLE || start == end) + if (h->flags == NVMAP_HANDLE_UNCACHEABLE || + h->flags == NVMAP_HANDLE_WRITE_COMBINE || start == end) goto out; if (fast_cache_maint(client, h, start, end, op)) |