aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2014-04-02 06:47:37 -0400
committerJoerg Roedel <jroedel@suse.de>2014-05-26 05:18:21 -0400
commitd25a2a16f0889de4a1cd8639896f35dc9465f6f5 (patch)
tree3b7e1425317bbc6bd965a05c47e87aff4f2be26d
parent4b660a7f5c8099d88d1a43d8ae138965112592c7 (diff)
iommu: Add driver for Renesas VMSA-compatible IPMMU
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/Kconfig12
-rw-r--r--drivers/iommu/Makefile1
-rw-r--r--drivers/iommu/ipmmu-vmsa.c1070
-rw-r--r--include/linux/platform_data/ipmmu-vmsa.h24
4 files changed, 1107 insertions, 0 deletions
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index df56e4c74a7e..a22b537caacd 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -272,6 +272,18 @@ config SHMOBILE_IOMMU_L1SIZE
272 default 256 if SHMOBILE_IOMMU_ADDRSIZE_64MB 272 default 256 if SHMOBILE_IOMMU_ADDRSIZE_64MB
273 default 128 if SHMOBILE_IOMMU_ADDRSIZE_32MB 273 default 128 if SHMOBILE_IOMMU_ADDRSIZE_32MB
274 274
275config IPMMU_VMSA
276 bool "Renesas VMSA-compatible IPMMU"
277 depends on ARM_LPAE
278 depends on ARCH_SHMOBILE || COMPILE_TEST
279 select IOMMU_API
280 select ARM_DMA_USE_IOMMU
281 help
282 Support for the Renesas VMSA-compatible IPMMU Renesas found in the
283 R-Mobile APE6 and R-Car H2/M2 SoCs.
284
285 If unsure, say N.
286
275config SPAPR_TCE_IOMMU 287config SPAPR_TCE_IOMMU
276 bool "sPAPR TCE IOMMU Support" 288 bool "sPAPR TCE IOMMU Support"
277 depends on PPC_POWERNV || PPC_PSERIES 289 depends on PPC_POWERNV || PPC_PSERIES
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 5d58bf16e9e3..8893bad048e0 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
7obj-$(CONFIG_ARM_SMMU) += arm-smmu.o 7obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
8obj-$(CONFIG_DMAR_TABLE) += dmar.o 8obj-$(CONFIG_DMAR_TABLE) += dmar.o
9obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o 9obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
10obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
10obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o 11obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
11obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o 12obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
12obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o 13obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
new file mode 100644
index 000000000000..b084530babf4
--- /dev/null
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -0,0 +1,1070 @@
1/*
2 * IPMMU VMSA
3 *
4 * Copyright (C) 2014 Renesas Electronics Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 */
10
11#include <linux/delay.h>
12#include <linux/dma-mapping.h>
13#include <linux/err.h>
14#include <linux/export.h>
15#include <linux/interrupt.h>
16#include <linux/io.h>
17#include <linux/iommu.h>
18#include <linux/module.h>
19#include <linux/platform_data/ipmmu-vmsa.h>
20#include <linux/platform_device.h>
21#include <linux/sizes.h>
22#include <linux/slab.h>
23
24#include <asm/dma-iommu.h>
25#include <asm/pgalloc.h>
26
27struct ipmmu_vmsa_device {
28 struct device *dev;
29 void __iomem *base;
30 struct list_head list;
31
32 const struct ipmmu_vmsa_platform_data *pdata;
33 unsigned int num_utlbs;
34
35 struct dma_iommu_mapping *mapping;
36};
37
38struct ipmmu_vmsa_domain {
39 struct ipmmu_vmsa_device *mmu;
40 struct iommu_domain *io_domain;
41
42 unsigned int context_id;
43 spinlock_t lock; /* Protects mappings */
44 pgd_t *pgd;
45};
46
47static DEFINE_SPINLOCK(ipmmu_devices_lock);
48static LIST_HEAD(ipmmu_devices);
49
50#define TLB_LOOP_TIMEOUT 100 /* 100us */
51
52/* -----------------------------------------------------------------------------
53 * Registers Definition
54 */
55
56#define IM_CTX_SIZE 0x40
57
58#define IMCTR 0x0000
59#define IMCTR_TRE (1 << 17)
60#define IMCTR_AFE (1 << 16)
61#define IMCTR_RTSEL_MASK (3 << 4)
62#define IMCTR_RTSEL_SHIFT 4
63#define IMCTR_TREN (1 << 3)
64#define IMCTR_INTEN (1 << 2)
65#define IMCTR_FLUSH (1 << 1)
66#define IMCTR_MMUEN (1 << 0)
67
68#define IMCAAR 0x0004
69
70#define IMTTBCR 0x0008
71#define IMTTBCR_EAE (1 << 31)
72#define IMTTBCR_PMB (1 << 30)
73#define IMTTBCR_SH1_NON_SHAREABLE (0 << 28)
74#define IMTTBCR_SH1_OUTER_SHAREABLE (2 << 28)
75#define IMTTBCR_SH1_INNER_SHAREABLE (3 << 28)
76#define IMTTBCR_SH1_MASK (3 << 28)
77#define IMTTBCR_ORGN1_NC (0 << 26)
78#define IMTTBCR_ORGN1_WB_WA (1 << 26)
79#define IMTTBCR_ORGN1_WT (2 << 26)
80#define IMTTBCR_ORGN1_WB (3 << 26)
81#define IMTTBCR_ORGN1_MASK (3 << 26)
82#define IMTTBCR_IRGN1_NC (0 << 24)
83#define IMTTBCR_IRGN1_WB_WA (1 << 24)
84#define IMTTBCR_IRGN1_WT (2 << 24)
85#define IMTTBCR_IRGN1_WB (3 << 24)
86#define IMTTBCR_IRGN1_MASK (3 << 24)
87#define IMTTBCR_TSZ1_MASK (7 << 16)
88#define IMTTBCR_TSZ1_SHIFT 16
89#define IMTTBCR_SH0_NON_SHAREABLE (0 << 12)
90#define IMTTBCR_SH0_OUTER_SHAREABLE (2 << 12)
91#define IMTTBCR_SH0_INNER_SHAREABLE (3 << 12)
92#define IMTTBCR_SH0_MASK (3 << 12)
93#define IMTTBCR_ORGN0_NC (0 << 10)
94#define IMTTBCR_ORGN0_WB_WA (1 << 10)
95#define IMTTBCR_ORGN0_WT (2 << 10)
96#define IMTTBCR_ORGN0_WB (3 << 10)
97#define IMTTBCR_ORGN0_MASK (3 << 10)
98#define IMTTBCR_IRGN0_NC (0 << 8)
99#define IMTTBCR_IRGN0_WB_WA (1 << 8)
100#define IMTTBCR_IRGN0_WT (2 << 8)
101#define IMTTBCR_IRGN0_WB (3 << 8)
102#define IMTTBCR_IRGN0_MASK (3 << 8)
103#define IMTTBCR_SL0_LVL_2 (0 << 4)
104#define IMTTBCR_SL0_LVL_1 (1 << 4)
105#define IMTTBCR_TSZ0_MASK (7 << 0)
106#define IMTTBCR_TSZ0_SHIFT O
107
108#define IMBUSCR 0x000c
109#define IMBUSCR_DVM (1 << 2)
110#define IMBUSCR_BUSSEL_SYS (0 << 0)
111#define IMBUSCR_BUSSEL_CCI (1 << 0)
112#define IMBUSCR_BUSSEL_IMCAAR (2 << 0)
113#define IMBUSCR_BUSSEL_CCI_IMCAAR (3 << 0)
114#define IMBUSCR_BUSSEL_MASK (3 << 0)
115
116#define IMTTLBR0 0x0010
117#define IMTTUBR0 0x0014
118#define IMTTLBR1 0x0018
119#define IMTTUBR1 0x001c
120
121#define IMSTR 0x0020
122#define IMSTR_ERRLVL_MASK (3 << 12)
123#define IMSTR_ERRLVL_SHIFT 12
124#define IMSTR_ERRCODE_TLB_FORMAT (1 << 8)
125#define IMSTR_ERRCODE_ACCESS_PERM (4 << 8)
126#define IMSTR_ERRCODE_SECURE_ACCESS (5 << 8)
127#define IMSTR_ERRCODE_MASK (7 << 8)
128#define IMSTR_MHIT (1 << 4)
129#define IMSTR_ABORT (1 << 2)
130#define IMSTR_PF (1 << 1)
131#define IMSTR_TF (1 << 0)
132
133#define IMMAIR0 0x0028
134#define IMMAIR1 0x002c
135#define IMMAIR_ATTR_MASK 0xff
136#define IMMAIR_ATTR_DEVICE 0x04
137#define IMMAIR_ATTR_NC 0x44
138#define IMMAIR_ATTR_WBRWA 0xff
139#define IMMAIR_ATTR_SHIFT(n) ((n) << 3)
140#define IMMAIR_ATTR_IDX_NC 0
141#define IMMAIR_ATTR_IDX_WBRWA 1
142#define IMMAIR_ATTR_IDX_DEV 2
143
144#define IMEAR 0x0030
145
146#define IMPCTR 0x0200
147#define IMPSTR 0x0208
148#define IMPEAR 0x020c
149#define IMPMBA(n) (0x0280 + ((n) * 4))
150#define IMPMBD(n) (0x02c0 + ((n) * 4))
151
152#define IMUCTR(n) (0x0300 + ((n) * 16))
153#define IMUCTR_FIXADDEN (1 << 31)
154#define IMUCTR_FIXADD_MASK (0xff << 16)
155#define IMUCTR_FIXADD_SHIFT 16
156#define IMUCTR_TTSEL_MMU(n) ((n) << 4)
157#define IMUCTR_TTSEL_PMB (8 << 4)
158#define IMUCTR_TTSEL_MASK (15 << 4)
159#define IMUCTR_FLUSH (1 << 1)
160#define IMUCTR_MMUEN (1 << 0)
161
162#define IMUASID(n) (0x0308 + ((n) * 16))
163#define IMUASID_ASID8_MASK (0xff << 8)
164#define IMUASID_ASID8_SHIFT 8
165#define IMUASID_ASID0_MASK (0xff << 0)
166#define IMUASID_ASID0_SHIFT 0
167