aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKanigeri, Hari <h-kanigeri2@ti.com>2010-05-23 22:01:51 -0400
committerHiroshi DOYU <Hiroshi.DOYU@nokia.com>2010-06-29 00:55:07 -0400
commitddfa975a8cf66753a7d829bada753c3617628486 (patch)
tree6416bc443c662b18232ded390d61abf081799cba
parent993dd17e32cfb6cc058e1a4394dd113edf764186 (diff)
omap iommu: add functionality to get TLB miss interrupt
In order to enable TLB miss interrupt, the TWL should be disabled. This patch provides the functionality to get the MMU fault interrupt for a TLB miss in the cases where the users are working with the locked TLB entries and with TWL disabled. New interface is added to select twl and to enable TLB miss interrupt. Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com> Signed-off-by: Ramesh Gupta <grgupta@ti.com> Signed-off-by: Hiroshi Doyu <Hiroshi.DOYU@nokia.com>
-rw-r--r--arch/arm/mach-omap2/iommu2.c32
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h2
-rw-r--r--arch/arm/plat-omap/iommu.c17
3 files changed, 46 insertions, 5 deletions
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index ebbdae262f78..edf7cd4b6553 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -65,6 +65,26 @@
65 ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \ 65 ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \
66 ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0) 66 ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)
67 67
68
69static void __iommu_set_twl(struct iommu *obj, bool on)
70{
71 u32 l = iommu_read_reg(obj, MMU_CNTL);
72
73 if (on)
74 iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE);
75 else
76 iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE);
77
78 l &= ~MMU_CNTL_MASK;
79 if (on)
80 l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN);
81 else
82 l |= (MMU_CNTL_MMU_EN);
83
84 iommu_write_reg(obj, l, MMU_CNTL);
85}
86
87
68static int omap2_iommu_enable(struct iommu *obj) 88static int omap2_iommu_enable(struct iommu *obj)
69{ 89{
70 u32 l, pa; 90 u32 l, pa;
@@ -100,13 +120,9 @@ static int omap2_iommu_enable(struct iommu *obj)
100 l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE); 120 l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
101 iommu_write_reg(obj, l, MMU_SYSCONFIG); 121 iommu_write_reg(obj, l, MMU_SYSCONFIG);
102 122
103 iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE);
104 iommu_write_reg(obj, pa, MMU_TTB); 123 iommu_write_reg(obj, pa, MMU_TTB);
105 124
106 l = iommu_read_reg(obj, MMU_CNTL); 125 __iommu_set_twl(obj, true);
107 l &= ~MMU_CNTL_MASK;
108 l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN);
109 iommu_write_reg(obj, l, MMU_CNTL);
110 126
111 return 0; 127 return 0;
112} 128}
@@ -122,6 +138,11 @@ static void omap2_iommu_disable(struct iommu *obj)
122 dev_dbg(obj->dev, "%s is shutting down\n", obj->name); 138 dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
123} 139}
124 140
141static void omap2_iommu_set_twl(struct iommu *obj, bool on)
142{
143 __iommu_set_twl(obj, false);
144}
145
125static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) 146static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
126{ 147{
127 int i; 148 int i;
@@ -304,6 +325,7 @@ static const struct iommu_functions omap2_iommu_ops = {
304 325
305 .enable = omap2_iommu_enable, 326 .enable = omap2_iommu_enable,
306 .disable = omap2_iommu_disable, 327 .disable = omap2_iommu_disable,
328 .set_twl = omap2_iommu_set_twl,
307 .fault_isr = omap2_iommu_fault_isr, 329 .fault_isr = omap2_iommu_fault_isr,
308 330
309 .tlb_read_cr = omap2_tlb_read_cr, 331 .tlb_read_cr = omap2_tlb_read_cr,
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index 0752af9d099e..33c7d41cb6a5 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -80,6 +80,7 @@ struct iommu_functions {
80 80
81 int (*enable)(struct iommu *obj); 81 int (*enable)(struct iommu *obj);
82 void (*disable)(struct iommu *obj); 82 void (*disable)(struct iommu *obj);
83 void (*set_twl)(struct iommu *obj, bool on);
83 u32 (*fault_isr)(struct iommu *obj, u32 *ra); 84 u32 (*fault_isr)(struct iommu *obj, u32 *ra);
84 85
85 void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr); 86 void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr);
@@ -143,6 +144,7 @@ extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
143extern u32 iotlb_cr_to_virt(struct cr_regs *cr); 144extern u32 iotlb_cr_to_virt(struct cr_regs *cr);
144 145
145extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e); 146extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e);
147extern void iommu_set_twl(struct iommu *obj, bool on);
146extern void flush_iotlb_page(struct iommu *obj, u32 da); 148extern void flush_iotlb_page(struct iommu *obj, u32 da);
147extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); 149extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end);
148extern void flush_iotlb_all(struct iommu *obj); 150extern void flush_iotlb_all(struct iommu *obj);
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index 341c48179ee0..688ae66bb8fc 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -370,6 +370,23 @@ void flush_iotlb_all(struct iommu *obj)
370} 370}
371EXPORT_SYMBOL_GPL(flush_iotlb_all); 371EXPORT_SYMBOL_GPL(flush_iotlb_all);
372 372
373/**
374 * iommu_set_twl - enable/disable table walking logic
375 * @obj: target iommu
376 * @on: enable/disable
377 *
378 * Function used to enable/disable TWL. If one wants to work
379 * exclusively with locked TLB entries and receive notifications
380 * for TLB miss then call this function to disable TWL.
381 */
382void iommu_set_twl(struct iommu *obj, bool on)
383{
384 clk_enable(obj->clk);
385 arch_iommu->set_twl(obj, on);
386 clk_disable(obj->clk);
387}
388EXPORT_SYMBOL_GPL(iommu_set_twl);
389
373#if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) 390#if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE)
374 391
375ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) 392ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes)