summaryrefslogtreecommitdiff
path: root/drivers/mxc/vpu/mxc_vpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/vpu/mxc_vpu.c')
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 0e0e03835e87..20d523aac9e1 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -45,6 +45,10 @@
#include <mach/mxc_vpu.h>
+/* Define one new pgprot which combined uncached and XN(never executable) */
+#define pgprot_noncachedxn(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
+
struct vpu_priv {
struct fasync_struct *async_queue;
struct work_struct work;
@@ -511,7 +515,13 @@ static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
unsigned long pfn;
vm->vm_flags |= VM_IO | VM_RESERVED;
- vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ /*
+ * Since vpu registers have been mapped with ioremap() at probe
+ * which L_PTE_XN is 1, and the same physical address must be
+ * mapped multiple times with same type, so set L_PTE_XN to 1 here.
+ * Otherwise, there may be unexpected result in video codec.
+ */
+ vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
pfn = phy_vpu_base_addr >> PAGE_SHIFT;
pr_debug("size=0x%x, page no.=0x%x\n",
(int)(vm->vm_end - vm->vm_start), (int)pfn);