aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/devices.c2
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c2
-rw-r--r--arch/arm/plat-omap/include/plat/iommu2.h96
-rw-r--r--arch/arm/plat-omap/include/plat/iovmm.h89
-rw-r--r--drivers/iommu/Makefile1
-rw-r--r--drivers/iommu/omap-iommu-debug.c8
-rw-r--r--drivers/iommu/omap-iommu.c39
-rw-r--r--drivers/iommu/omap-iommu.h (renamed from arch/arm/plat-omap/include/plat/iommu.h)133
-rw-r--r--drivers/iommu/omap-iommu2.c (renamed from arch/arm/mach-omap2/iommu2.c)11
-rw-r--r--drivers/iommu/omap-iopgtable.h (renamed from arch/arm/plat-omap/include/plat/iopgtable.h)22
-rw-r--r--drivers/iommu/omap-iovmm.c50
-rw-r--r--drivers/media/platform/omap3isp/isp.c1
-rw-r--r--drivers/media/platform/omap3isp/isp.h4
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.c1
-rw-r--r--drivers/media/platform/omap3isp/ispstat.c1
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c2
-rw-r--r--include/linux/omap-iommu.h52
-rw-r--r--include/linux/platform_data/iommu-omap.h49
21 files changed, 280 insertions, 289 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index dd76ff77760b..11c57af01a88 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -202,8 +202,6 @@ obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o
202obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o 202obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
203mailbox_mach-objs := mailbox.o 203mailbox_mach-objs := mailbox.o
204 204
205obj-$(CONFIG_OMAP_IOMMU) += iommu2.o
206
207iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o 205iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o
208obj-y += $(iommu-m) $(iommu-y) 206obj-y += $(iommu-m) $(iommu-y)
209 207
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index d2215e9873a5..3cff7dc514df 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -129,7 +129,7 @@ static struct platform_device omap2cam_device = {
129 129
130#if defined(CONFIG_IOMMU_API) 130#if defined(CONFIG_IOMMU_API)
131 131
132#include <plat/iommu.h> 132#include <linux/platform_data/iommu-omap.h>
133 133
134static struct resource omap3isp_resources[] = { 134static struct resource omap3isp_resources[] = {
135 { 135 {
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index df298d46707c..a6a4ff8744b7 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -13,7 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15 15
16#include <plat/iommu.h> 16#include <linux/platform_data/iommu-omap.h>
17 17
18#include "soc.h" 18#include "soc.h"
19#include "common.h" 19#include "common.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index addc1c24ca2e..7f73f2132acc 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -24,8 +24,8 @@
24#include "l4_3xxx.h" 24#include "l4_3xxx.h"
25#include <linux/platform_data/asoc-ti-mcbsp.h> 25#include <linux/platform_data/asoc-ti-mcbsp.h>
26#include <linux/platform_data/spi-omap2-mcspi.h> 26#include <linux/platform_data/spi-omap2-mcspi.h>
27#include <linux/platform_data/iommu-omap.h>
27#include <plat/dmtimer.h> 28#include <plat/dmtimer.h>
28#include <plat/iommu.h>
29 29
30#include "am35xx.h" 30#include "am35xx.h"
31 31
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index f5b55a78a5f0..26f8e9f18190 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -28,8 +28,8 @@
28#include <linux/platform_data/omap_ocp2scp.h> 28#include <linux/platform_data/omap_ocp2scp.h>
29#include <linux/platform_data/spi-omap2-mcspi.h> 29#include <linux/platform_data/spi-omap2-mcspi.h>
30#include <linux/platform_data/asoc-ti-mcbsp.h> 30#include <linux/platform_data/asoc-ti-mcbsp.h>
31#include <linux/platform_data/iommu-omap.h>
31#include <plat/dmtimer.h> 32#include <plat/dmtimer.h>
32#include <plat/iommu.h>
33 33
34#include "omap_hwmod.h" 34#include "omap_hwmod.h"
35#include "omap_hwmod_common_data.h" 35#include "omap_hwmod_common_data.h"
diff --git a/arch/arm/plat-omap/include/plat/iommu2.h b/arch/arm/plat-omap/include/plat/iommu2.h
deleted file mode 100644
index d4116b595e40..000000000000
--- a/arch/arm/plat-omap/include/plat/iommu2.h
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * omap iommu: omap2 architecture specific definitions
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __MACH_IOMMU2_H
14#define __MACH_IOMMU2_H
15
16#include <linux/io.h>
17
18/*
19 * MMU Register offsets
20 */
21#define MMU_REVISION 0x00
22#define MMU_SYSCONFIG 0x10
23#define MMU_SYSSTATUS 0x14
24#define MMU_IRQSTATUS 0x18
25#define MMU_IRQENABLE 0x1c
26#define MMU_WALKING_ST 0x40
27#define MMU_CNTL 0x44
28#define MMU_FAULT_AD 0x48
29#define MMU_TTB 0x4c
30#define MMU_LOCK 0x50
31#define MMU_LD_TLB 0x54
32#define MMU_CAM 0x58
33#define MMU_RAM 0x5c
34#define MMU_GFLUSH 0x60
35#define MMU_FLUSH_ENTRY 0x64
36#define MMU_READ_CAM 0x68
37#define MMU_READ_RAM 0x6c
38#define MMU_EMU_FAULT_AD 0x70
39
40#define MMU_REG_SIZE 256
41
42/*
43 * MMU Register bit definitions
44 */
45#define MMU_LOCK_BASE_SHIFT 10
46#define MMU_LOCK_BASE_MASK (0x1f << MMU_LOCK_BASE_SHIFT)
47#define MMU_LOCK_BASE(x) \
48 ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
49
50#define MMU_LOCK_VICT_SHIFT 4
51#define MMU_LOCK_VICT_MASK (0x1f << MMU_LOCK_VICT_SHIFT)
52#define MMU_LOCK_VICT(x) \
53 ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
54
55#define MMU_CAM_VATAG_SHIFT 12
56#define MMU_CAM_VATAG_MASK \
57 ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
58#define MMU_CAM_P (1 << 3)
59#define MMU_CAM_V (1 << 2)
60#define MMU_CAM_PGSZ_MASK 3
61#define MMU_CAM_PGSZ_1M (0 << 0)
62#define MMU_CAM_PGSZ_64K (1 << 0)
63#define MMU_CAM_PGSZ_4K (2 << 0)
64#define MMU_CAM_PGSZ_16M (3 << 0)
65
66#define MMU_RAM_PADDR_SHIFT 12
67#define MMU_RAM_PADDR_MASK \
68 ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
69#define MMU_RAM_ENDIAN_SHIFT 9
70#define MMU_RAM_ENDIAN_MASK (1 << MMU_RAM_ENDIAN_SHIFT)
71#define MMU_RAM_ENDIAN_BIG (1 << MMU_RAM_ENDIAN_SHIFT)
72#define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT)
73#define MMU_RAM_ELSZ_SHIFT 7
74#define MMU_RAM_ELSZ_MASK (3 << MMU_RAM_ELSZ_SHIFT)
75#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
76#define MMU_RAM_ELSZ_16 (1 << MMU_RAM_ELSZ_SHIFT)
77#define MMU_RAM_ELSZ_32 (2 << MMU_RAM_ELSZ_SHIFT)
78#define MMU_RAM_ELSZ_NONE (3 << MMU_RAM_ELSZ_SHIFT)
79#define MMU_RAM_MIXED_SHIFT 6
80#define MMU_RAM_MIXED_MASK (1 << MMU_RAM_MIXED_SHIFT)
81#define MMU_RAM_MIXED MMU_RAM_MIXED_MASK
82
83/*
84 * register accessors
85 */
86static inline u32 iommu_read_reg(struct omap_iommu *obj, size_t offs)
87{
88 return __raw_readl(obj->regbase + offs);
89}
90
91static inline void iommu_write_reg(struct omap_iommu *obj, u32 val, size_t offs)
92{
93 __raw_writel(val, obj->regbase + offs);
94}
95
96#endif /* __MACH_IOMMU2_H */
diff --git a/arch/arm/plat-omap/include/plat/iovmm.h b/arch/arm/plat-omap/include/plat/iovmm.h
deleted file mode 100644
index 498e57cda6cd..000000000000
--- a/arch/arm/plat-omap/include/plat/iovmm.h
+++ /dev/null
@@ -1,89 +0,0 @@
1/*
2 * omap iommu: simple virtual address space management
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __IOMMU_MMAP_H
14#define __IOMMU_MMAP_H
15
16#include <linux/iommu.h>
17
18struct iovm_struct {
19 struct omap_iommu *iommu; /* iommu object which this belongs to */
20 u32 da_start; /* area definition */
21 u32 da_end;
22 u32 flags; /* IOVMF_: see below */
23 struct list_head list; /* linked in ascending order */
24 const struct sg_table *sgt; /* keep 'page' <-> 'da' mapping */
25 void *va; /* mpu side mapped address */
26};
27
28/*
29 * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
30 *
31 * lower 16 bit is used for h/w and upper 16 bit is for s/w.
32 */
33#define IOVMF_SW_SHIFT 16
34
35/*
36 * iovma: h/w flags derived from cam and ram attribute
37 */
38#define IOVMF_CAM_MASK (~((1 << 10) - 1))
39#define IOVMF_RAM_MASK (~IOVMF_CAM_MASK)
40
41#define IOVMF_PGSZ_MASK (3 << 0)
42#define IOVMF_PGSZ_1M MMU_CAM_PGSZ_1M
43#define IOVMF_PGSZ_64K MMU_CAM_PGSZ_64K
44#define IOVMF_PGSZ_4K MMU_CAM_PGSZ_4K
45#define IOVMF_PGSZ_16M MMU_CAM_PGSZ_16M
46
47#define IOVMF_ENDIAN_MASK (1 << 9)
48#define IOVMF_ENDIAN_BIG MMU_RAM_ENDIAN_BIG
49#define IOVMF_ENDIAN_LITTLE MMU_RAM_ENDIAN_LITTLE
50
51#define IOVMF_ELSZ_MASK (3 << 7)
52#define IOVMF_ELSZ_8 MMU_RAM_ELSZ_8
53#define IOVMF_ELSZ_16 MMU_RAM_ELSZ_16
54#define IOVMF_ELSZ_32 MMU_RAM_ELSZ_32
55#define IOVMF_ELSZ_NONE MMU_RAM_ELSZ_NONE
56
57#define IOVMF_MIXED_MASK (1 << 6)
58#define IOVMF_MIXED MMU_RAM_MIXED
59
60/*
61 * iovma: s/w flags, used for mapping and umapping internally.
62 */
63#define IOVMF_MMIO (1 << IOVMF_SW_SHIFT)
64#define IOVMF_ALLOC (2 << IOVMF_SW_SHIFT)
65#define IOVMF_ALLOC_MASK (3 << IOVMF_SW_SHIFT)
66
67/* "superpages" is supported just with physically linear pages */
68#define IOVMF_DISCONT (1 << (2 + IOVMF_SW_SHIFT))
69#define IOVMF_LINEAR (2 << (2 + IOVMF_SW_SHIFT))
70#define IOVMF_LINEAR_MASK (3 << (2 + IOVMF_SW_SHIFT))
71
72#define IOVMF_DA_FIXED (1 << (4 + IOVMF_SW_SHIFT))
73
74
75extern struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da);
76extern u32
77omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,
78 const struct sg_table *sgt, u32 flags);
79extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain,
80 struct device *dev, u32 da);
81extern u32
82omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev,
83 u32 da, size_t bytes, u32 flags);
84extern void
85omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,
86 const u32 da);
87extern void *omap_da_to_va(struct device *dev, u32 da);
88
89#endif /* __IOMMU_MMAP_H */
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 14a4d5fc94fa..f66b816d455c 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_DMAR_TABLE) += dmar.o
7obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o 7obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
8obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o 8obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
9obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o 9obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
10obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
10obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o 11obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o
11obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o 12obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
12obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o 13obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index f55fc5dfbadc..d97fbe4fb9b1 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -18,11 +18,11 @@
18#include <linux/uaccess.h> 18#include <linux/uaccess.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/debugfs.h> 20#include <linux/debugfs.h>
21#include <linux/omap-iommu.h>
22#include <linux/platform_data/iommu-omap.h>
21 23
22#include <plat/iommu.h> 24#include "omap-iopgtable.h"
23#include <plat/iovmm.h> 25#include "omap-iommu.h"
24
25#include <plat/iopgtable.h>
26 26
27#define MAXCOLUMN 100 /* for short messages */ 27#define MAXCOLUMN 100 /* for short messages */
28 28
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index d0b1234581be..badc17c2bcb4 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -19,14 +19,17 @@
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/iommu.h> 21#include <linux/iommu.h>
22#include <linux/omap-iommu.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
23#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/io.h>
24 26
25#include <asm/cacheflush.h> 27#include <asm/cacheflush.h>
26 28
27#include <plat/iommu.h> 29#include <linux/platform_data/iommu-omap.h>
28 30
29#include <plat/iopgtable.h> 31#include "omap-iopgtable.h"
32#include "omap-iommu.h"
30 33
31#define for_each_iotlb_cr(obj, n, __i, cr) \ 34#define for_each_iotlb_cr(obj, n, __i, cr) \
32 for (__i = 0; \ 35 for (__i = 0; \
@@ -51,6 +54,21 @@ struct omap_iommu_domain {
51 spinlock_t lock; 54 spinlock_t lock;
52}; 55};
53 56
57#define MMU_LOCK_BASE_SHIFT 10
58#define MMU_LOCK_BASE_MASK (0x1f << MMU_LOCK_BASE_SHIFT)
59#define MMU_LOCK_BASE(x) \
60 ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
61
62#define MMU_LOCK_VICT_SHIFT 4
63#define MMU_LOCK_VICT_MASK (0x1f << MMU_LOCK_VICT_SHIFT)
64#define MMU_LOCK_VICT(x) \
65 ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
66
67struct iotlb_lock {
68 short base;
69 short vict;
70};
71
54/* accommodate the difference between omap1 and omap2/3 */ 72/* accommodate the difference between omap1 and omap2/3 */
55static const struct iommu_functions *arch_iommu; 73static const struct iommu_functions *arch_iommu;
56 74
@@ -1015,6 +1033,23 @@ static void iopte_cachep_ctor(void *iopte)
1015 clean_dcache_area(iopte, IOPTE_TABLE_SIZE); 1033 clean_dcache_area(iopte, IOPTE_TABLE_SIZE);
1016} 1034}
1017 1035
1036static u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
1037 u32 flags)
1038{
1039 memset(e, 0, sizeof(*e));
1040
1041 e->da = da;
1042 e->pa = pa;
1043 e->valid = 1;
1044 /* FIXME: add OMAP1 support */
1045 e->pgsz = flags & MMU_CAM_PGSZ_MASK;
1046 e->endian = flags & MMU_RAM_ENDIAN_MASK;
1047 e->elsz = flags & MMU_RAM_ELSZ_MASK;
1048 e->mixed = flags & MMU_RAM_MIXED_MASK;
1049
1050 return iopgsz_to_bytes(e->pgsz);
1051}
1052
1018static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, 1053static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
1019 phys_addr_t pa, size_t bytes, int prot) 1054 phys_addr_t pa, size_t bytes, int prot)
1020{ 1055{
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/drivers/iommu/omap-iommu.h
index 68b5f0362f35..2b5f3c04d167 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/drivers/iommu/omap-iommu.h
@@ -10,8 +10,9 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#ifndef __MACH_IOMMU_H 13#if defined(CONFIG_ARCH_OMAP1)
14#define __MACH_IOMMU_H 14#error "iommu for this processor not implemented yet"
15#endif
15 16
16struct iotlb_entry { 17struct iotlb_entry {
17 u32 da; 18 u32 da;
@@ -71,11 +72,6 @@ struct cr_regs {
71 }; 72 };
72}; 73};
73 74
74struct iotlb_lock {
75 short base;
76 short vict;
77};
78
79/* architecture specific functions */ 75/* architecture specific functions */
80struct iommu_functions { 76struct iommu_functions {
81 unsigned long version; 77 unsigned long version;
@@ -103,42 +99,6 @@ struct iommu_functions {
103 ssize_t (*dump_ctx)(struct omap_iommu *obj, char *buf, ssize_t len); 99 ssize_t (*dump_ctx)(struct omap_iommu *obj, char *buf, ssize_t len);
104}; 100};
105 101
106/**
107 * struct omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod
108 * @da_start: device address where the va space starts.
109 * @da_end: device address where the va space ends.
110 * @nr_tlb_entries: number of entries supported by the translation
111 * look-aside buffer (TLB).
112 */
113struct omap_mmu_dev_attr {
114 u32 da_start;
115 u32 da_end;
116 int nr_tlb_entries;
117};
118
119struct iommu_platform_data {
120 const char *name;
121 const char *clk_name;
122 const int nr_tlb_entries;
123 u32 da_start;
124 u32 da_end;
125};
126
127/**
128 * struct iommu_arch_data - omap iommu private data
129 * @name: name of the iommu device
130 * @iommu_dev: handle of the iommu device
131 *
132 * This is an omap iommu private data object, which binds an iommu user
133 * to its iommu device. This object should be placed at the iommu user's
134 * dev_archdata so generic IOMMU API can be used without having to
135 * utilize omap-specific plumbing anymore.
136 */
137struct omap_iommu_arch_data {
138 const char *name;
139 struct omap_iommu *iommu_dev;
140};
141
142#ifdef CONFIG_IOMMU_API 102#ifdef CONFIG_IOMMU_API
143/** 103/**
144 * dev_to_omap_iommu() - retrieves an omap iommu object from a user device 104 * dev_to_omap_iommu() - retrieves an omap iommu object from a user device
@@ -152,18 +112,59 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
152} 112}
153#endif 113#endif
154 114
155/* IOMMU errors */ 115/*
156#define OMAP_IOMMU_ERR_TLB_MISS (1 << 0) 116 * MMU Register offsets
157#define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1) 117 */
158#define OMAP_IOMMU_ERR_EMU_MISS (1 << 2) 118#define MMU_REVISION 0x00
159#define OMAP_IOMMU_ERR_TBLWALK_FAULT (1 << 3) 119#define MMU_SYSCONFIG 0x10
160#define OMAP_IOMMU_ERR_MULTIHIT_FAULT (1 << 4) 120#define MMU_SYSSTATUS 0x14
121#define MMU_IRQSTATUS 0x18
122#define MMU_IRQENABLE 0x1c
123#define MMU_WALKING_ST 0x40
124#define MMU_CNTL 0x44
125#define MMU_FAULT_AD 0x48
126#define MMU_TTB 0x4c
127#define MMU_LOCK 0x50
128#define MMU_LD_TLB 0x54
129#define MMU_CAM 0x58
130#define MMU_RAM 0x5c
131#define MMU_GFLUSH 0x60
132#define MMU_FLUSH_ENTRY 0x64
133#define MMU_READ_CAM 0x68
134#define MMU_READ_RAM 0x6c
135#define MMU_EMU_FAULT_AD 0x70
136
137#define MMU_REG_SIZE 256
161 138
162#if defined(CONFIG_ARCH_OMAP1) 139/*
163#error "iommu for this processor not implemented yet" 140 * MMU Register bit definitions
164#else 141 */
165#include <plat/iommu2.h> 142#define MMU_CAM_VATAG_SHIFT 12
166#endif 143#define MMU_CAM_VATAG_MASK \
144 ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
145#define MMU_CAM_P (1 << 3)
146#define MMU_CAM_V (1 << 2)
147#define MMU_CAM_PGSZ_MASK 3
148#define MMU_CAM_PGSZ_1M (0 << 0)
149#define MMU_CAM_PGSZ_64K (1 << 0)
150#define MMU_CAM_PGSZ_4K (2 << 0)
151#define MMU_CAM_PGSZ_16M (3 << 0)
152
153#define MMU_RAM_PADDR_SHIFT 12
154#define MMU_RAM_PADDR_MASK \
155 ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
156
157#define MMU_RAM_ENDIAN_MASK (1 << MMU_RAM_ENDIAN_SHIFT)
158#define MMU_RAM_ENDIAN_BIG (1 << MMU_RAM_ENDIAN_SHIFT)
159
160#define MMU_RAM_ELSZ_MASK (3 << MMU_RAM_ELSZ_SHIFT)
161#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
162#define MMU_RAM_ELSZ_16 (1 << MMU_RAM_ELSZ_SHIFT)
163#define MMU_RAM_ELSZ_32 (2 << MMU_RAM_ELSZ_SHIFT)
164#define MMU_RAM_ELSZ_NONE (3 << MMU_RAM_ELSZ_SHIFT)
165#define MMU_RAM_MIXED_SHIFT 6
166#define MMU_RAM_MIXED_MASK (1 << MMU_RAM_MIXED_SHIFT)
167#define MMU_RAM_MIXED MMU_RAM_MIXED_MASK
167 168
168/* 169/*
169 * utilities for super page(16MB, 1MB, 64KB and 4KB) 170 * utilities for super page(16MB, 1MB, 64KB and 4KB)
@@ -199,23 +200,29 @@ extern void omap_iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
199extern int 200extern int
200omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e); 201omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e);
201 202
202extern int omap_iommu_set_isr(const char *name,
203 int (*isr)(struct omap_iommu *obj, u32 da, u32 iommu_errs,
204 void *priv),
205 void *isr_priv);
206
207extern void omap_iommu_save_ctx(struct device *dev); 203extern void omap_iommu_save_ctx(struct device *dev);
208extern void omap_iommu_restore_ctx(struct device *dev); 204extern void omap_iommu_restore_ctx(struct device *dev);
209 205
210extern int omap_install_iommu_arch(const struct iommu_functions *ops);
211extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops);
212
213extern int omap_foreach_iommu_device(void *data, 206extern int omap_foreach_iommu_device(void *data,
214 int (*fn)(struct device *, void *)); 207 int (*fn)(struct device *, void *));
215 208
209extern int omap_install_iommu_arch(const struct iommu_functions *ops);
210extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops);
211
216extern ssize_t 212extern ssize_t
217omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); 213omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len);
218extern size_t 214extern size_t
219omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len); 215omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len);
220 216
221#endif /* __MACH_IOMMU_H */ 217/*
218 * register accessors
219 */
220static inline u32 iommu_read_reg(struct omap_iommu *obj, size_t offs)
221{
222 return __raw_readl(obj->regbase + offs);
223}
224
225static inline void iommu_write_reg(struct omap_iommu *obj, u32 val, size_t offs)
226{
227 __raw_writel(val, obj->regbase + offs);
228}
diff --git a/arch/arm/mach-omap2/iommu2.c b/drivers/iommu/omap-iommu2.c
index eefc37912ef3..c02020292377 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/drivers/iommu/omap-iommu2.c
@@ -13,12 +13,15 @@
13 13
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/io.h>
16#include <linux/jiffies.h> 17#include <linux/jiffies.h>
17#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/omap-iommu.h>
18#include <linux/slab.h> 20#include <linux/slab.h>
19#include <linux/stringify.h> 21#include <linux/stringify.h>
22#include <linux/platform_data/iommu-omap.h>
20 23
21#include <plat/iommu.h> 24#include "omap-iommu.h"
22 25
23/* 26/*
24 * omap2 architecture specific register bit definitions 27 * omap2 architecture specific register bit definitions
@@ -65,6 +68,12 @@
65 ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \ 68 ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \
66 ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0) 69 ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)
67 70
71/* IOMMU errors */
72#define OMAP_IOMMU_ERR_TLB_MISS (1 << 0)
73#define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1)
74#define OMAP_IOMMU_ERR_EMU_MISS (1 << 2)
75#define OMAP_IOMMU_ERR_TBLWALK_FAULT (1 << 3)
76#define OMAP_IOMMU_ERR_MULTIHIT_FAULT (1 << 4)
68 77
69static void __iommu_set_twl(struct omap_iommu *obj, bool on) 78static void __iommu_set_twl(struct omap_iommu *obj, bool on)
70{ 79{
diff --git a/arch/arm/plat-omap/include/plat/iopgtable.h b/drivers/iommu/omap-iopgtable.h
index 66a813977d52..cd4ae9e5b0c6 100644
--- a/arch/arm/plat-omap/include/plat/iopgtable.h
+++ b/drivers/iommu/omap-iopgtable.h
@@ -10,9 +10,6 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#ifndef __PLAT_OMAP_IOMMU_H
14#define __PLAT_OMAP_IOMMU_H
15
16/* 13/*
17 * "L2 table" address mask and size definitions. 14 * "L2 table" address mask and size definitions.
18 */ 15 */
@@ -97,24 +94,5 @@ static inline phys_addr_t omap_iommu_translate(u32 d, u32 va, u32 mask)
97#define iopte_index(da) (((da) >> IOPTE_SHIFT) & (PTRS_PER_IOPTE - 1)) 94#define iopte_index(da) (((da) >> IOPTE_SHIFT) & (PTRS_PER_IOPTE - 1))
98#define iopte_offset(iopgd, da) (iopgd_page_vaddr(iopgd) + iopte_index(da)) 95#define iopte_offset(iopgd, da) (iopgd_page_vaddr(iopgd) + iopte_index(da))
99 96
100static inline u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
101 u32 flags)
102{
103 memset(e, 0, sizeof(*e));
104
105 e->da = da;
106 e->pa = pa;
107 e->valid = 1;
108 /* FIXME: add OMAP1 support */
109 e->pgsz = flags & MMU_CAM_PGSZ_MASK;
110 e->endian = flags & MMU_RAM_ENDIAN_MASK;
111 e->elsz = flags & MMU_RAM_ELSZ_MASK;
112 e->mixed = flags & MMU_RAM_MIXED_MASK;
113
114 return iopgsz_to_bytes(e->pgsz);
115}
116
117#define to_iommu(dev) \ 97#define to_iommu(dev) \
118 (struct omap_iommu *)platform_get_drvdata(to_platform_device(dev)) 98 (struct omap_iommu *)platform_get_drvdata(to_platform_device(dev))
119
120#endif /* __PLAT_OMAP_IOMMU_H */
diff --git a/drivers/iommu/omap-iovmm.c b/drivers/iommu/omap-iovmm.c
index 2e10c3e0a7ae..46d875690739 100644
--- a/drivers/iommu/omap-iovmm.c
+++ b/drivers/iommu/omap-iovmm.c
@@ -17,14 +17,58 @@
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/scatterlist.h> 18#include <linux/scatterlist.h>
19#include <linux/iommu.h> 19#include <linux/iommu.h>
20#include <linux/omap-iommu.h>
21#include <linux/platform_data/iommu-omap.h>
20 22
21#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
22#include <asm/mach/map.h> 24#include <asm/mach/map.h>
23 25
24#include <plat/iommu.h> 26#include "omap-iopgtable.h"
25#include <plat/iovmm.h> 27#include "omap-iommu.h"
26 28
27#include <plat/iopgtable.h> 29/*
30 * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
31 *
32 * lower 16 bit is used for h/w and upper 16 bit is for s/w.
33 */
34#define IOVMF_SW_SHIFT 16
35
36/*
37 * iovma: h/w flags derived from cam and ram attribute
38 */
39#define IOVMF_CAM_MASK (~((1 << 10) - 1))
40#define IOVMF_RAM_MASK (~IOVMF_CAM_MASK)
41
42#define IOVMF_PGSZ_MASK (3 << 0)
43#define IOVMF_PGSZ_1M MMU_CAM_PGSZ_1M
44#define IOVMF_PGSZ_64K MMU_CAM_PGSZ_64K
45#define IOVMF_PGSZ_4K MMU_CAM_PGSZ_4K
46#define IOVMF_PGSZ_16M MMU_CAM_PGSZ_16M
47
48#define IOVMF_ENDIAN_MASK (1 << 9)
49#define IOVMF_ENDIAN_BIG MMU_RAM_ENDIAN_BIG
50
51#define IOVMF_ELSZ_MASK (3 << 7)
52#define IOVMF_ELSZ_16 MMU_RAM_ELSZ_16
53#define IOVMF_ELSZ_32 MMU_RAM_ELSZ_32
54#define IOVMF_ELSZ_NONE MMU_RAM_ELSZ_NONE
55
56#define IOVMF_MIXED_MASK (1 << 6)
57#define IOVMF_MIXED MMU_RAM_MIXED
58
59/*
60 * iovma: s/w flags, used for mapping and umapping internally.
61 */
62#define IOVMF_MMIO (1 << IOVMF_SW_SHIFT)
63#define IOVMF_ALLOC (2 << IOVMF_SW_SHIFT)
64#define IOVMF_ALLOC_MASK (3 << IOVMF_SW_SHIFT)
65
66/* "superpages" is supported just with physically linear pages */
67#define IOVMF_DISCONT (1 << (2 + IOVMF_SW_SHIFT))
68#define IOVMF_LINEAR (2 << (2 + IOVMF_SW_SHIFT))
69#define IOVMF_LINEAR_MASK (3 << (2 + IOVMF_SW_SHIFT))
70
71#define IOVMF_DA_FIXED (1 << (4 + IOVMF_SW_SHIFT))
28 72
29static struct kmem_cache *iovm_area_cachep; 73static struct kmem_cache *iovm_area_cachep;
30 74
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 99640d8c1db0..7f182f0ff3da 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -61,6 +61,7 @@
61#include <linux/i2c.h> 61#include <linux/i2c.h>
62#include <linux/interrupt.h> 62#include <linux/interrupt.h>
63#include <linux/module.h> 63#include <linux/module.h>
64#include <linux/omap-iommu.h>
64#include <linux/platform_device.h> 65#include <linux/platform_device.h>
65#include <linux/regulator/consumer.h> 66#include <linux/regulator/consumer.h>
66#include <linux/slab.h> 67#include <linux/slab.h>
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index 8be7487c326f..8d6866942b85 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -31,11 +31,9 @@
31#include <media/v4l2-device.h> 31#include <media/v4l2-device.h>
32#include <linux/device.h> 32#include <linux/device.h>
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/iommu.h>
34#include <linux/platform_device.h> 35#include <linux/platform_device.h>
35#include <linux/wait.h> 36#include <linux/wait.h>
36#include <linux/iommu.h>
37#include <plat/iommu.h>
38#include <plat/iovmm.h>
39 37
40#include "ispstat.h" 38#include "ispstat.h"
41#include "ispccdc.h" 39#include "ispccdc.h"
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 60181ab96063..6ae1ffb277e7 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -30,6 +30,7 @@
30#include <linux/device.h> 30#include <linux/device.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/mm.h> 32#include <linux/mm.h>
33#include <linux/omap-iommu.h>
33#include <linux/sched.h> 34#include <linux/sched.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <media/v4l2-event.h> 36#include <media/v4l2-event.h>
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index d7ac76b5c2ae..35c38237449d 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28#include <linux/dma-mapping.h> 28#include <linux/dma-mapping.h>
29#include <linux/omap-iommu.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/uaccess.h> 31#include <linux/uaccess.h>
31 32
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 5bd40e6870cc..c4be4fa8a7d7 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -27,6 +27,7 @@
27#include <linux/clk.h> 27#include <linux/clk.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/omap-iommu.h>
30#include <linux/pagemap.h> 31#include <linux/pagemap.h>
31#include <linux/scatterlist.h> 32#include <linux/scatterlist.h>
32#include <linux/sched.h> 33#include <linux/sched.h>
@@ -36,6 +37,7 @@
36#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
37#include <plat/iommu.h> 38#include <plat/iommu.h>
38#include <plat/iovmm.h> 39#include <plat/iovmm.h>
40#include <plat/omap-pm.h>
39 41
40#include "ispvideo.h" 42#include "ispvideo.h"
41#include "isp.h" 43#include "isp.h"
diff --git a/include/linux/omap-iommu.h b/include/linux/omap-iommu.h
new file mode 100644
index 000000000000..cac78de09c07
--- /dev/null
+++ b/include/linux/omap-iommu.h
@@ -0,0 +1,52 @@
1/*
2 * omap iommu: simple virtual address space management
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _INTEL_IOMMU_H_
14#define _INTEL_IOMMU_H_
15
16struct iovm_struct {
17 struct omap_iommu *iommu; /* iommu object which this belongs to */
18 u32 da_start; /* area definition */
19 u32 da_end;
20 u32 flags; /* IOVMF_: see below */
21 struct list_head list; /* linked in ascending order */
22 const struct sg_table *sgt; /* keep 'page' <-> 'da' mapping */
23 void *va; /* mpu side mapped address */
24};
25
26#define MMU_RAM_ENDIAN_SHIFT 9
27#define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT)
28#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
29#define IOVMF_ENDIAN_LITTLE MMU_RAM_ENDIAN_LITTLE
30#define MMU_RAM_ELSZ_SHIFT 7
31#define IOVMF_ELSZ_8 MMU_RAM_ELSZ_8
32
33struct iommu_domain;
34
35extern struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da);
36extern u32
37omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,
38 const struct sg_table *sgt, u32 flags);
39extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain,
40 struct device *dev, u32 da);
41extern u32
42omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev,
43 u32 da, size_t bytes, u32 flags);
44extern void
45omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,
46 const u32 da);
47extern void *omap_da_to_va(struct device *dev, u32 da);
48
49extern void omap_iommu_save_ctx(struct device *dev);
50extern void omap_iommu_restore_ctx(struct device *dev);
51
52#endif
diff --git a/include/linux/platform_data/iommu-omap.h b/include/linux/platform_data/iommu-omap.h
new file mode 100644
index 000000000000..c677b9f2fefa
--- /dev/null
+++ b/include/linux/platform_data/iommu-omap.h
@@ -0,0 +1,49 @@
1/*
2 * omap iommu: main structures
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#define MMU_REG_SIZE 256
14
15/**
16 * struct iommu_arch_data - omap iommu private data
17 * @name: name of the iommu device
18 * @iommu_dev: handle of the iommu device
19 *
20 * This is an omap iommu private data object, which binds an iommu user
21 * to its iommu device. This object should be placed at the iommu user's
22 * dev_archdata so generic IOMMU API can be used without having to
23 * utilize omap-specific plumbing anymore.
24 */
25struct omap_iommu_arch_data {
26 const char *name;
27 struct omap_iommu *iommu_dev;
28};
29
30/**
31 * struct omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod
32 * @da_start: device address where the va space starts.
33 * @da_end: device address where the va space ends.
34 * @nr_tlb_entries: number of entries supported by the translation
35 * look-aside buffer (TLB).
36 */
37struct omap_mmu_dev_attr {
38 u32 da_start;
39 u32 da_end;
40 int nr_tlb_entries;
41};
42
43struct iommu_platform_data {
44 const char *name;
45 const char *clk_name;
46 const int nr_tlb_entries;
47 u32 da_start;
48 u32 da_end;
49};