Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f40fd0e2 authored by Tony Lindgren's avatar Tony Lindgren
Browse files

Merge branch 'v2.6.35-rc3-iommu-for-next' of...

Merge branch 'v2.6.35-rc3-iommu-for-next' of git://gitorious.org/~doyu/lk/mainline into omap-for-linus
parents 9f2952db 1fd7f467
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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)
+35 −9
Original line number Diff line number Diff line
@@ -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
@@ -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;
@@ -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;
}
@@ -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;
@@ -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;
}

@@ -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,
+1 −1
Original line number Diff line number Diff line
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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);
+23 −4
Original line number Diff line number Diff line
@@ -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)
@@ -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;
@@ -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);

@@ -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;
@@ -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