summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch453
1 files changed, 453 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch
new file mode 100644
index 0000000000..d5f78dd14e
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch
@@ -0,0 +1,453 @@
1From c79d7959c45f40e47520aa6acd54c19094754787 Mon Sep 17 00:00:00 2001
2From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
3Date: Mon, 26 Jan 2009 15:13:45 +0200
4Subject: [PATCH] omap iommu: omap2 architecture specific functions
5
6The structure 'arch_mmu' accommodates the difference between omap1 and
7omap2/3.
8
9This patch provides omap2/3 specific functions
10
11Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
12---
13 arch/arm/mach-omap2/iommu2.c | 326 ++++++++++++++++++++++++++++++
14 arch/arm/plat-omap/include/mach/iommu2.h | 94 +++++++++
15 2 files changed, 420 insertions(+), 0 deletions(-)
16 create mode 100644 arch/arm/mach-omap2/iommu2.c
17 create mode 100644 arch/arm/plat-omap/include/mach/iommu2.h
18
19diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
20new file mode 100644
21index 0000000..88a44f1
22--- /dev/null
23+++ b/arch/arm/mach-omap2/iommu2.c
24@@ -0,0 +1,326 @@
25+/*
26+ * omap iommu: omap2/3 architecture specific functions
27+ *
28+ * Copyright (C) 2008-2009 Nokia Corporation
29+ *
30+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>,
31+ * Paul Mundt and Toshihiro Kobayashi
32+ *
33+ * This program is free software; you can redistribute it and/or modify
34+ * it under the terms of the GNU General Public License version 2 as
35+ * published by the Free Software Foundation.
36+ */
37+
38+#include <linux/err.h>
39+#include <linux/device.h>
40+#include <linux/jiffies.h>
41+#include <linux/module.h>
42+#include <linux/stringify.h>
43+
44+#include <asm/io.h>
45+
46+#include <mach/iommu.h>
47+#include <mach/iommu2.h>
48+
49+/*
50+ * omap2 architecture specific register bit definitions
51+ */
52+#define IOMMU_ARCH_VERSION 0x00000011
53+
54+/* SYSCONF */
55+#define MMU_SYS_IDLE_SHIFT 3
56+#define MMU_SYS_IDLE_FORCE (0 << MMU_SYS_IDLE_SHIFT)
57+#define MMU_SYS_IDLE_NONE (1 << MMU_SYS_IDLE_SHIFT)
58+#define MMU_SYS_IDLE_SMART (2 << MMU_SYS_IDLE_SHIFT)
59+#define MMU_SYS_IDLE_MASK (3 << MMU_SYS_IDLE_SHIFT)
60+
61+#define MMU_SYS_SOFTRESET (1 << 1)
62+#define MMU_SYS_AUTOIDLE 1
63+
64+/* SYSSTATUS */
65+#define MMU_SYS_RESETDONE 1
66+
67+/* IRQSTATUS & IRQENABLE */
68+#define MMU_IRQ_MULTIHITFAULT (1 << 4)
69+#define MMU_IRQ_TABLEWALKFAULT (1 << 3)
70+#define MMU_IRQ_EMUMISS (1 << 2)
71+#define MMU_IRQ_TRANSLATIONFAULT (1 << 1)
72+#define MMU_IRQ_TLBMISS (1 << 0)
73+#define MMU_IRQ_MASK \
74+ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \
75+ MMU_IRQ_TRANSLATIONFAULT)
76+
77+/* MMU_CNTL */
78+#define MMU_CNTL_SHIFT 1
79+#define MMU_CNTL_MASK (7 << MMU_CNTL_SHIFT)
80+#define MMU_CNTL_EML_TLB (1 << 3)
81+#define MMU_CNTL_TWL_EN (1 << 2)
82+#define MMU_CNTL_MMU_EN (1 << 1)
83+
84+#define get_cam_va_mask(pgsz) \
85+ (((pgsz) == MMU_CAM_PGSZ_16M) ? 0xff000000 : \
86+ ((pgsz) == MMU_CAM_PGSZ_1M) ? 0xfff00000 : \
87+ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \
88+ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)
89+
90+static int omap2_iommu_enable(struct iommu *obj)
91+{
92+ u32 l, pa;
93+ unsigned long timeout;
94+
95+ if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd, SZ_16K))
96+ return -EINVAL;
97+
98+ pa = virt_to_phys(obj->iopgd);
99+ if (!IS_ALIGNED(pa, SZ_16K))
100+ return -EINVAL;
101+
102+ iommu_write_reg(obj, MMU_SYS_SOFTRESET, MMU_SYSCONFIG);
103+
104+ timeout = jiffies + msecs_to_jiffies(20);
105+ do {
106+ l = iommu_read_reg(obj, MMU_SYSSTATUS);
107+ if (l & MMU_SYS_RESETDONE)
108+ break;
109+ } while (time_after(jiffies, timeout));
110+
111+ if (!(l & MMU_SYS_RESETDONE)) {
112+ dev_err(obj->dev, "can't take mmu out of reset\n");
113+ return -ENODEV;
114+ }
115+
116+ l = iommu_read_reg(obj, MMU_REVISION);
117+ dev_info(obj->dev, "%s: version %d.%d\n", obj->name,
118+ (l >> 4) & 0xf, l & 0xf);
119+
120+ l = iommu_read_reg(obj, MMU_SYSCONFIG);
121+ l &= ~MMU_SYS_IDLE_MASK;
122+ l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
123+ iommu_write_reg(obj, l, MMU_SYSCONFIG);
124+
125+ iommu_write_reg(obj, MMU_IRQ_MASK, MMU_IRQENABLE);
126+ iommu_write_reg(obj, pa, MMU_TTB);
127+
128+ l = iommu_read_reg(obj, MMU_CNTL);
129+ l &= ~MMU_CNTL_MASK;
130+ l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN);
131+ iommu_write_reg(obj, l, MMU_CNTL);
132+
133+ return 0;
134+}
135+
136+static void omap2_iommu_disable(struct iommu *obj)
137+{
138+ u32 l = iommu_read_reg(obj, MMU_CNTL);
139+
140+ l &= ~MMU_CNTL_MASK;
141+ iommu_write_reg(obj, l, MMU_CNTL);
142+ iommu_write_reg(obj, MMU_SYS_IDLE_FORCE, MMU_SYSCONFIG);
143+
144+ dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
145+}
146+
147+static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
148+{
149+ int i;
150+ u32 stat, da;
151+ const char *err_msg[] = {
152+ "tlb miss",
153+ "translation fault",
154+ "emulation miss",
155+ "table walk fault",
156+ "multi hit fault",
157+ };
158+
159+ stat = iommu_read_reg(obj, MMU_IRQSTATUS);
160+ stat &= MMU_IRQ_MASK;
161+ if (!stat)
162+ return 0;
163+
164+ da = iommu_read_reg(obj, MMU_FAULT_AD);
165+ *ra = da;
166+
167+ dev_err(obj->dev, "%s:\tda:%08x ", __func__, da);
168+
169+ for (i = 0; i < ARRAY_SIZE(err_msg); i++) {
170+ if (stat & (1 << i))
171+ printk("%s ", err_msg[i]);
172+ }
173+ printk("\n");
174+
175+ iommu_write_reg(obj, stat, MMU_IRQSTATUS);
176+ return stat;
177+}
178+
179+static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
180+{
181+ cr->cam = iommu_read_reg(obj, MMU_READ_CAM);
182+ cr->ram = iommu_read_reg(obj, MMU_READ_RAM);
183+}
184+
185+static void omap2_tlb_load_cr(struct iommu *obj, struct cr_regs *cr)
186+{
187+ iommu_write_reg(obj, cr->cam | MMU_CAM_V, MMU_CAM);
188+ iommu_write_reg(obj, cr->ram, MMU_RAM);
189+}
190+
191+static u32 omap2_cr_to_virt(struct cr_regs *cr)
192+{
193+ u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK;
194+ u32 mask = get_cam_va_mask(cr->cam & page_size);
195+
196+ return cr->cam & mask;
197+}
198+
199+static struct cr_regs *omap2_alloc_cr(struct iommu *obj, struct iotlb_entry *e)
200+{
201+ struct cr_regs *cr;
202+
203+ if (e->da & ~(get_cam_va_mask(e->pgsz))) {
204+ dev_err(obj->dev, "%s:\twrong alignment: %08x\n", __func__,
205+ e->da);
206+ return ERR_PTR(-EINVAL);
207+ }
208+
209+ cr = kmalloc(sizeof(*cr), GFP_KERNEL);
210+ if (!cr)
211+ return ERR_PTR(-ENOMEM);
212+
213+ cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz;
214+ cr->ram = e->pa | e->endian | e->elsz | e->mixed;
215+
216+ return cr;
217+}
218+
219+static inline int omap2_cr_valid(struct cr_regs *cr)
220+{
221+ return cr->cam & MMU_CAM_V;
222+}
223+
224+static u32 omap2_get_pte_attr(struct iotlb_entry *e)
225+{
226+ u32 attr;
227+
228+ attr = e->mixed << 5;
229+ attr |= e->endian;
230+ attr |= e->elsz >> 3;
231+ attr <<= ((e->pgsz & MMU_CAM_PGSZ_4K) ? 0 : 6);
232+
233+ return attr;
234+}
235+
236+static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf)
237+{
238+ char *p = buf;
239+
240+ /* FIXME: Need more detail analysis of cam/ram */
241+ p += sprintf(p, "%08x %08x\n", cr->cam, cr->ram);
242+
243+ return p - buf;
244+}
245+
246+#define pr_reg(name) \
247+ p += sprintf(p, "%20s: %08x\n", \
248+ __stringify(name), iommu_read_reg(obj, MMU_##name));
249+
250+static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf)
251+{
252+ char *p = buf;
253+
254+ pr_reg(REVISION);
255+ pr_reg(SYSCONFIG);
256+ pr_reg(SYSSTATUS);
257+ pr_reg(IRQSTATUS);
258+ pr_reg(IRQENABLE);
259+ pr_reg(WALKING_ST);
260+ pr_reg(CNTL);
261+ pr_reg(FAULT_AD);
262+ pr_reg(TTB);
263+ pr_reg(LOCK);
264+ pr_reg(LD_TLB);
265+ pr_reg(CAM);
266+ pr_reg(RAM);
267+ pr_reg(GFLUSH);
268+ pr_reg(FLUSH_ENTRY);
269+ pr_reg(READ_CAM);
270+ pr_reg(READ_RAM);
271+ pr_reg(EMU_FAULT_AD);
272+
273+ return p - buf;
274+}
275+
276+static void omap2_iommu_save_ctx(struct iommu *obj)
277+{
278+ int i;
279+ u32 *p = obj->ctx;
280+
281+ for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) {
282+ p[i] = iommu_read_reg(obj, i * sizeof(u32));
283+ dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]);
284+ }
285+
286+ BUG_ON(p[0] != IOMMU_ARCH_VERSION);
287+}
288+
289+static void omap2_iommu_restore_ctx(struct iommu *obj)
290+{
291+ int i;
292+ u32 *p = obj->ctx;
293+
294+ for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) {
295+ iommu_write_reg(obj, p[i], i * sizeof(u32));
296+ dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]);
297+ }
298+
299+ BUG_ON(p[0] != IOMMU_ARCH_VERSION);
300+}
301+
302+static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
303+{
304+ e->da = cr->cam & MMU_CAM_VATAG_MASK;
305+ e->pa = cr->ram & MMU_RAM_PADDR_MASK;
306+ e->valid = cr->cam & MMU_CAM_V;
307+ e->pgsz = cr->cam & MMU_CAM_PGSZ_MASK;
308+ e->endian = cr->ram & MMU_RAM_ENDIAN_MASK;
309+ e->elsz = cr->ram & MMU_RAM_ELSZ_MASK;
310+ e->mixed = cr->ram & MMU_RAM_MIXED;
311+}
312+
313+static const struct iommu_functions omap2_iommu_ops = {
314+ .version = IOMMU_ARCH_VERSION,
315+
316+ .enable = omap2_iommu_enable,
317+ .disable = omap2_iommu_disable,
318+ .fault_isr = omap2_iommu_fault_isr,
319+
320+ .tlb_read_cr = omap2_tlb_read_cr,
321+ .tlb_load_cr = omap2_tlb_load_cr,
322+
323+ .cr_to_e = omap2_cr_to_e,
324+ .cr_to_virt = omap2_cr_to_virt,
325+ .alloc_cr = omap2_alloc_cr,
326+ .cr_valid = omap2_cr_valid,
327+ .dump_cr = omap2_dump_cr,
328+
329+ .get_pte_attr = omap2_get_pte_attr,
330+
331+ .save_ctx = omap2_iommu_save_ctx,
332+ .restore_ctx = omap2_iommu_restore_ctx,
333+ .dump_ctx = omap2_iommu_dump_ctx,
334+};
335+
336+static int __init omap2_iommu_init(void)
337+{
338+ return install_iommu_arch(&omap2_iommu_ops);
339+}
340+module_init(omap2_iommu_init);
341+
342+static void __exit omap2_iommu_exit(void)
343+{
344+ uninstall_iommu_arch(&omap2_iommu_ops);
345+}
346+module_exit(omap2_iommu_exit);
347+
348+MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi");
349+MODULE_DESCRIPTION("omap iommu: omap2/3 architecture specific functions");
350+MODULE_LICENSE("GPL v2");
351diff --git a/arch/arm/plat-omap/include/mach/iommu2.h b/arch/arm/plat-omap/include/mach/iommu2.h
352new file mode 100644
353index 0000000..d746047
354--- /dev/null
355+++ b/arch/arm/plat-omap/include/mach/iommu2.h
356@@ -0,0 +1,94 @@
357+/*
358+ * omap iommu: omap2 architecture specific definitions
359+ *
360+ * Copyright (C) 2008-2009 Nokia Corporation
361+ *
362+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
363+ *
364+ * This program is free software; you can redistribute it and/or modify
365+ * it under the terms of the GNU General Public License version 2 as
366+ * published by the Free Software Foundation.
367+ */
368+
369+#ifndef __MACH_IOMMU2_H
370+#define __MACH_IOMMU2_H
371+
372+/*
373+ * MMU Register offsets
374+ */
375+#define MMU_REVISION 0x00
376+#define MMU_SYSCONFIG 0x10
377+#define MMU_SYSSTATUS 0x14
378+#define MMU_IRQSTATUS 0x18
379+#define MMU_IRQENABLE 0x1c
380+#define MMU_WALKING_ST 0x40
381+#define MMU_CNTL 0x44
382+#define MMU_FAULT_AD 0x48
383+#define MMU_TTB 0x4c
384+#define MMU_LOCK 0x50
385+#define MMU_LD_TLB 0x54
386+#define MMU_CAM 0x58
387+#define MMU_RAM 0x5c
388+#define MMU_GFLUSH 0x60
389+#define MMU_FLUSH_ENTRY 0x64
390+#define MMU_READ_CAM 0x68
391+#define MMU_READ_RAM 0x6c
392+#define MMU_EMU_FAULT_AD 0x70
393+
394+#define MMU_REG_SIZE 256
395+
396+/*
397+ * MMU Register bit definitions
398+ */
399+#define MMU_LOCK_BASE_SHIFT 10
400+#define MMU_LOCK_BASE_MASK (0x1f << MMU_LOCK_BASE_SHIFT)
401+#define MMU_LOCK_BASE(x) \
402+ ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
403+
404+#define MMU_LOCK_VICT_SHIFT 4
405+#define MMU_LOCK_VICT_MASK (0x1f << MMU_LOCK_VICT_SHIFT)
406+#define MMU_LOCK_VICT(x) \
407+ ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
408+
409+#define MMU_CAM_VATAG_SHIFT 12
410+#define MMU_CAM_VATAG_MASK \
411+ ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
412+#define MMU_CAM_P (1 << 3)
413+#define MMU_CAM_V (1 << 2)
414+#define MMU_CAM_PGSZ_MASK 3
415+#define MMU_CAM_PGSZ_1M (0 << 0)
416+#define MMU_CAM_PGSZ_64K (1 << 0)
417+#define MMU_CAM_PGSZ_4K (2 << 0)
418+#define MMU_CAM_PGSZ_16M (3 << 0)
419+
420+#define MMU_RAM_PADDR_SHIFT 12
421+#define MMU_RAM_PADDR_MASK \
422+ ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
423+#define MMU_RAM_ENDIAN_SHIFT 9
424+#define MMU_RAM_ENDIAN_MASK (1 << MMU_RAM_ENDIAN_SHIFT)
425+#define MMU_RAM_ENDIAN_BIG (1 << MMU_RAM_ENDIAN_SHIFT)
426+#define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT)
427+#define MMU_RAM_ELSZ_SHIFT 7
428+#define MMU_RAM_ELSZ_MASK (3 << MMU_RAM_ELSZ_SHIFT)
429+#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
430+#define MMU_RAM_ELSZ_16 (1 << MMU_RAM_ELSZ_SHIFT)
431+#define MMU_RAM_ELSZ_32 (2 << MMU_RAM_ELSZ_SHIFT)
432+#define MMU_RAM_ELSZ_NONE (3 << MMU_RAM_ELSZ_SHIFT)
433+#define MMU_RAM_MIXED_SHIFT 6
434+#define MMU_RAM_MIXED_MASK (1 << MMU_RAM_MIXED_SHIFT)
435+#define MMU_RAM_MIXED MMU_RAM_MIXED_MASK
436+
437+/*
438+ * register accessors
439+ */
440+static inline u32 iommu_read_reg(struct iommu *obj, size_t offs)
441+{
442+ return __raw_readl(obj->regbase + offs);
443+}
444+
445+static inline void iommu_write_reg(struct iommu *obj, u32 val, size_t offs)
446+{
447+ __raw_writel(val, obj->regbase + offs);
448+}
449+
450+#endif /* __MACH_IOMMU2_H */
451--
4521.5.6.5
453