summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/nvmap
diff options
context:
space:
mode:
authorKrishna Reddy <vdumpa@nvidia.com>2011-08-30 10:15:44 -0700
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-15 11:52:44 +0530
commit65e8c13a3b1c0259b80a36afbefc9b2d443216b4 (patch)
tree9021d5ceb2f0aa81e514bd8484fadb77bd331c3f /drivers/video/tegra/nvmap
parent041b12a14e1849d92c03b0df99ee9b90e3acafdd (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>
Diffstat (limited to 'drivers/video/tegra/nvmap')
-rw-r--r--drivers/video/tegra/nvmap/nvmap_handle.c31
-rw-r--r--drivers/video/tegra/nvmap/nvmap_ioctl.c18
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))