Loading arch/arm/mach-omap2/Makefile +4 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,10 @@ obj-$(CONFIG_OMAP3_EMU) += emu.o obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o mailbox_mach-objs := mailbox.o obj-$(CONFIG_OMAP_IOMMU) := iommu2.o omap-iommu.o obj-$(CONFIG_OMAP_IOMMU) += iommu2.o iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o obj-y += $(iommu-m) $(iommu-y) i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o obj-y += $(i2c-omap-m) $(i2c-omap-y) Loading arch/arm/mach-omap2/iommu2.c +35 −9 Original line number Diff line number Diff line Loading @@ -44,9 +44,13 @@ #define MMU_IRQ_EMUMISS (1 << 2) #define MMU_IRQ_TRANSLATIONFAULT (1 << 1) #define MMU_IRQ_TLBMISS (1 << 0) #define __MMU_IRQ_FAULT \ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_EMUMISS | MMU_IRQ_TRANSLATIONFAULT) #define MMU_IRQ_MASK \ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \ MMU_IRQ_TRANSLATIONFAULT) (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_TLBMISS) #define MMU_IRQ_TWL_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT) #define MMU_IRQ_TLB_MISS_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TLBMISS) /* MMU_CNTL */ #define MMU_CNTL_SHIFT 1 Loading @@ -61,6 +65,26 @@ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0) static void __iommu_set_twl(struct iommu *obj, bool on) { u32 l = iommu_read_reg(obj, MMU_CNTL); if (on) iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); else iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE); l &= ~MMU_CNTL_MASK; if (on) l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); else l |= (MMU_CNTL_MMU_EN); iommu_write_reg(obj, l, MMU_CNTL); } static int omap2_iommu_enable(struct iommu *obj) { u32 l, pa; Loading Loading @@ -96,13 +120,9 @@ static int omap2_iommu_enable(struct iommu *obj) l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE); iommu_write_reg(obj, l, MMU_SYSCONFIG); iommu_write_reg(obj, MMU_IRQ_MASK, MMU_IRQENABLE); iommu_write_reg(obj, pa, MMU_TTB); l = iommu_read_reg(obj, MMU_CNTL); l &= ~MMU_CNTL_MASK; l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); iommu_write_reg(obj, l, MMU_CNTL); __iommu_set_twl(obj, true); return 0; } Loading @@ -118,6 +138,11 @@ static void omap2_iommu_disable(struct iommu *obj) dev_dbg(obj->dev, "%s is shutting down\n", obj->name); } static void omap2_iommu_set_twl(struct iommu *obj, bool on) { __iommu_set_twl(obj, false); } static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) { int i; Loading Loading @@ -147,7 +172,7 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) printk("\n"); iommu_write_reg(obj, stat, MMU_IRQSTATUS); omap2_iommu_disable(obj); return stat; } Loading Loading @@ -300,6 +325,7 @@ static const struct iommu_functions omap2_iommu_ops = { .enable = omap2_iommu_enable, .disable = omap2_iommu_disable, .set_twl = omap2_iommu_set_twl, .fault_isr = omap2_iommu_fault_isr, .tlb_read_cr = omap2_tlb_read_cr, Loading arch/arm/mach-omap2/omap-iommu.c +1 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES]; static struct iommu_device omap4_devices[] = { { .base = OMAP4_MMU1_BASE, .irq = INT_44XX_DUCATI_MMU_IRQ, .irq = OMAP44XX_IRQ_DUCATI_MMU, .pdata = { .name = "ducati", .nr_tlb_entries = 32, Loading arch/arm/plat-omap/include/plat/iommu.h +2 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ struct iommu_functions { int (*enable)(struct iommu *obj); void (*disable)(struct iommu *obj); void (*set_twl)(struct iommu *obj, bool on); u32 (*fault_isr)(struct iommu *obj, u32 *ra); void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr); Loading Loading @@ -143,6 +144,7 @@ extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); extern u32 iotlb_cr_to_virt(struct cr_regs *cr); extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e); extern void iommu_set_twl(struct iommu *obj, bool on); extern void flush_iotlb_page(struct iommu *obj, u32 da); extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); extern void flush_iotlb_all(struct iommu *obj); Loading arch/arm/plat-omap/iommu.c +23 −4 Original line number Diff line number Diff line Loading @@ -370,6 +370,23 @@ void flush_iotlb_all(struct iommu *obj) } EXPORT_SYMBOL_GPL(flush_iotlb_all); /** * iommu_set_twl - enable/disable table walking logic * @obj: target iommu * @on: enable/disable * * Function used to enable/disable TWL. If one wants to work * exclusively with locked TLB entries and receive notifications * for TLB miss then call this function to disable TWL. */ void iommu_set_twl(struct iommu *obj, bool on) { clk_enable(obj->clk); arch_iommu->set_twl(obj, on); clk_disable(obj->clk); } EXPORT_SYMBOL_GPL(iommu_set_twl); #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) Loading Loading @@ -653,7 +670,7 @@ void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, u32 **ppte) if (!*iopgd) goto out; if (*iopgd & IOPGD_TABLE) if (iopgd_is_table(*iopgd)) iopte = iopte_offset(iopgd, da); out: *ppgd = iopgd; Loading @@ -670,7 +687,7 @@ static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da) if (!*iopgd) return 0; if (*iopgd & IOPGD_TABLE) { if (iopgd_is_table(*iopgd)) { int i; u32 *iopte = iopte_offset(iopgd, da); Loading Loading @@ -745,7 +762,7 @@ static void iopgtable_clear_entry_all(struct iommu *obj) if (!*iopgd) continue; if (*iopgd & IOPGD_TABLE) if (iopgd_is_table(*iopgd)) iopte_free(iopte_offset(iopgd, 0)); *iopgd = 0; Loading Loading @@ -783,9 +800,11 @@ static irqreturn_t iommu_fault_handler(int irq, void *data) if (!stat) return IRQ_HANDLED; iommu_disable(obj); iopgd = iopgd_offset(obj, da); if (!(*iopgd & IOPGD_TABLE)) { if (!iopgd_is_table(*iopgd)) { dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__, da, iopgd, *iopgd); return IRQ_NONE; Loading Loading
arch/arm/mach-omap2/Makefile +4 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,10 @@ obj-$(CONFIG_OMAP3_EMU) += emu.o obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o mailbox_mach-objs := mailbox.o obj-$(CONFIG_OMAP_IOMMU) := iommu2.o omap-iommu.o obj-$(CONFIG_OMAP_IOMMU) += iommu2.o iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o obj-y += $(iommu-m) $(iommu-y) i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o obj-y += $(i2c-omap-m) $(i2c-omap-y) Loading
arch/arm/mach-omap2/iommu2.c +35 −9 Original line number Diff line number Diff line Loading @@ -44,9 +44,13 @@ #define MMU_IRQ_EMUMISS (1 << 2) #define MMU_IRQ_TRANSLATIONFAULT (1 << 1) #define MMU_IRQ_TLBMISS (1 << 0) #define __MMU_IRQ_FAULT \ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_EMUMISS | MMU_IRQ_TRANSLATIONFAULT) #define MMU_IRQ_MASK \ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \ MMU_IRQ_TRANSLATIONFAULT) (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_TLBMISS) #define MMU_IRQ_TWL_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT) #define MMU_IRQ_TLB_MISS_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TLBMISS) /* MMU_CNTL */ #define MMU_CNTL_SHIFT 1 Loading @@ -61,6 +65,26 @@ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0) static void __iommu_set_twl(struct iommu *obj, bool on) { u32 l = iommu_read_reg(obj, MMU_CNTL); if (on) iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); else iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE); l &= ~MMU_CNTL_MASK; if (on) l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); else l |= (MMU_CNTL_MMU_EN); iommu_write_reg(obj, l, MMU_CNTL); } static int omap2_iommu_enable(struct iommu *obj) { u32 l, pa; Loading Loading @@ -96,13 +120,9 @@ static int omap2_iommu_enable(struct iommu *obj) l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE); iommu_write_reg(obj, l, MMU_SYSCONFIG); iommu_write_reg(obj, MMU_IRQ_MASK, MMU_IRQENABLE); iommu_write_reg(obj, pa, MMU_TTB); l = iommu_read_reg(obj, MMU_CNTL); l &= ~MMU_CNTL_MASK; l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); iommu_write_reg(obj, l, MMU_CNTL); __iommu_set_twl(obj, true); return 0; } Loading @@ -118,6 +138,11 @@ static void omap2_iommu_disable(struct iommu *obj) dev_dbg(obj->dev, "%s is shutting down\n", obj->name); } static void omap2_iommu_set_twl(struct iommu *obj, bool on) { __iommu_set_twl(obj, false); } static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) { int i; Loading Loading @@ -147,7 +172,7 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) printk("\n"); iommu_write_reg(obj, stat, MMU_IRQSTATUS); omap2_iommu_disable(obj); return stat; } Loading Loading @@ -300,6 +325,7 @@ static const struct iommu_functions omap2_iommu_ops = { .enable = omap2_iommu_enable, .disable = omap2_iommu_disable, .set_twl = omap2_iommu_set_twl, .fault_isr = omap2_iommu_fault_isr, .tlb_read_cr = omap2_tlb_read_cr, Loading
arch/arm/mach-omap2/omap-iommu.c +1 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES]; static struct iommu_device omap4_devices[] = { { .base = OMAP4_MMU1_BASE, .irq = INT_44XX_DUCATI_MMU_IRQ, .irq = OMAP44XX_IRQ_DUCATI_MMU, .pdata = { .name = "ducati", .nr_tlb_entries = 32, Loading
arch/arm/plat-omap/include/plat/iommu.h +2 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ struct iommu_functions { int (*enable)(struct iommu *obj); void (*disable)(struct iommu *obj); void (*set_twl)(struct iommu *obj, bool on); u32 (*fault_isr)(struct iommu *obj, u32 *ra); void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr); Loading Loading @@ -143,6 +144,7 @@ extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); extern u32 iotlb_cr_to_virt(struct cr_regs *cr); extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e); extern void iommu_set_twl(struct iommu *obj, bool on); extern void flush_iotlb_page(struct iommu *obj, u32 da); extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); extern void flush_iotlb_all(struct iommu *obj); Loading
arch/arm/plat-omap/iommu.c +23 −4 Original line number Diff line number Diff line Loading @@ -370,6 +370,23 @@ void flush_iotlb_all(struct iommu *obj) } EXPORT_SYMBOL_GPL(flush_iotlb_all); /** * iommu_set_twl - enable/disable table walking logic * @obj: target iommu * @on: enable/disable * * Function used to enable/disable TWL. If one wants to work * exclusively with locked TLB entries and receive notifications * for TLB miss then call this function to disable TWL. */ void iommu_set_twl(struct iommu *obj, bool on) { clk_enable(obj->clk); arch_iommu->set_twl(obj, on); clk_disable(obj->clk); } EXPORT_SYMBOL_GPL(iommu_set_twl); #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) Loading Loading @@ -653,7 +670,7 @@ void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, u32 **ppte) if (!*iopgd) goto out; if (*iopgd & IOPGD_TABLE) if (iopgd_is_table(*iopgd)) iopte = iopte_offset(iopgd, da); out: *ppgd = iopgd; Loading @@ -670,7 +687,7 @@ static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da) if (!*iopgd) return 0; if (*iopgd & IOPGD_TABLE) { if (iopgd_is_table(*iopgd)) { int i; u32 *iopte = iopte_offset(iopgd, da); Loading Loading @@ -745,7 +762,7 @@ static void iopgtable_clear_entry_all(struct iommu *obj) if (!*iopgd) continue; if (*iopgd & IOPGD_TABLE) if (iopgd_is_table(*iopgd)) iopte_free(iopte_offset(iopgd, 0)); *iopgd = 0; Loading Loading @@ -783,9 +800,11 @@ static irqreturn_t iommu_fault_handler(int irq, void *data) if (!stat) return IRQ_HANDLED; iommu_disable(obj); iopgd = iopgd_offset(obj, da); if (!(*iopgd & IOPGD_TABLE)) { if (!iopgd_is_table(*iopgd)) { dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__, da, iopgd, *iopgd); return IRQ_NONE; Loading