Skip to contentSkip to conversation

OMAP: iommu: hwmod support and runtime PM

PATCH Superseded Omar Ramirez Luna 4 participants 15 messages Nov 1, 2011 – Nov 8, 2011

Subsystems (7)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover OMAP: iommu: hwmod support and runtime PM

Introduced hwmod support for OMAP3 (iva, isp) and OMAP4 (ipu, dsp), along with the corresponding runtime PM routines to deassert reset lines, enable/disable clocks and configure sysc registers.

v3:
- Rebased to 3.1-rc10 lo rebuilt, added structure terminators, and removed .omap_chip field.

v2:
- Added oh reset info to assert/deassert mmu reset lines.
- Addressed previous comments on v1
http://www.spinics.net/lists/arm-kernel/msg103271.html

Due to compatibility an ifdef needs to be propagated (previously on iommu resource info) to hwmod data in OMAP3, so users of iommu and tidspbridge can avoid issues of two modules managing mmu data/irqs/resets; this until tidspbridge can be safely migrated to iommu framework.

Omar Ramirez Luna (4):
OMAP3: hwmod data: add mmu data for iva and isp
OMAP4: hwmod data: add mmu hwmod for ipu and dsp OMAP3/4: iommu: migrate to hwmod framework OMAP3/4: iommu: adapt to runtime pm

 arch/arm/mach-omap2/iommu2.c                      |   36 -----
 arch/arm/mach-omap2/omap-iommu.c                  |  162 ++++-----------------
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c        |  131 +++++++++++++++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c        |  154 ++++++++++++++++++--
 arch/arm/plat-omap/include/plat/iommu.h           |   17 ++-
 arch/arm/plat-omap/include/plat/iommu2.h          |    2 -
 drivers/iommu/omap-iommu.c                        |   49 +++----
 drivers/media/video/omap3isp/isp.c                |    2 +-
 drivers/staging/tidspbridge/core/tiomap3430_pwr.c |    2 +-
 9 files changed, 339 insertions(+), 216 deletions(-)
#1 lore raw

PATCH v3 1/4 OMAP3: hwmod data: add mmu data for iva and isp

Add mmu hwmod data for iva and isp.

---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  131 ++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/plat/iommu.h    |   13 +++
 2 files changed, 144 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +131 -0
index 3008e16..d7ee173 100644
@@ -26,6 +26,7 @@
 #include <plat/mcbsp.h>
 #include <plat/mcspi.h>
 #include <plat/dmtimer.h>
+#include <plat/iommu.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -2920,6 +2921,132 @@ static struct omap_hwmod omap34xx_mcspi4 = {
 };
 
 /*
+ * 'mmu' class
+ * The memory management unit performs virtual to physical address translation
+ * for its requestors.
+ */
+
+static struct omap_hwmod_class_sysconfig mmu_sysc = {
+	.rev_offs	= 0x000,
+	.sysc_offs	= 0x010,
+	.syss_offs	= 0x014,
+	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_mmu_hwmod_class = {
+	.name = "mmu",
+	.sysc = &mmu_sysc,
+};
+
+/* isp mmu */
+
+static struct omap_mmu_dev_attr isp_mmu_dev_attr = {
+	.da_start = 0x0,
+	.da_end = 0xfffff000,
+	.nr_tlb_entries = 8,
+};
+
+static struct omap_hwmod omap3xxx_isp_mmu_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_isp_mmu_irqs[] = {
+	{ .irq = 24 },
+	{ .irq = -1 }
+};
+
+static struct omap_hwmod_addr_space omap3xxx_isp_mmu_addrs[] = {
+	{
+		.pa_start	= 0x480bd400,
+		.pa_end		= 0x480bd47f,
+		.flags		= ADDR_TYPE_RT,
+	},
+	{ }
+};
+
+/* l4_core -> isp mmu */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__isp_mmu = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap3xxx_isp_mmu_hwmod,
+	.addr		= omap3xxx_isp_mmu_addrs,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* isp mmu slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_isp_mmu_slaves[] = {
+	&omap3xxx_l4_core__isp_mmu,
+};
+
+static struct omap_hwmod omap3xxx_isp_mmu_hwmod = {
+	.name		= "isp_mmu",
+	.class		= &omap3xxx_mmu_hwmod_class,
+	.mpu_irqs	= omap3xxx_isp_mmu_irqs,
+	.main_clk	= "cam_ick",
+	.dev_attr	= &isp_mmu_dev_attr,
+	.slaves		= omap3xxx_isp_mmu_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_isp_mmu_slaves),
+	.flags		= HWMOD_NO_IDLEST,
+};
+
+/* iva mmu */
+
+static struct omap_mmu_dev_attr iva_mmu_dev_attr = {
+	.da_start = 0x11000000,
+	.da_end = 0xfffff000,
+	.nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap3xxx_iva_mmu_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_iva_mmu_irqs[] = {
+	{ .irq = 28 },
+	{ .irq = -1 }
+};
+
+static struct omap_hwmod_rst_info omap3xxx_iva_mmu_resets[] = {
+	{ .name = "mmu", .rst_shift = 1, .st_shift = 9 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_iva_mmu_addrs[] = {
+	{
+		.pa_start	= 0x5d000000,
+		.pa_end		= 0x5d00007f,
+		.flags		= ADDR_TYPE_RT,
+	},
+	{ }
+};
+
+/* l3_main -> iva mmu */
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__iva_mmu = {
+	.master		= &omap3xxx_l3_main_hwmod,
+	.slave		= &omap3xxx_iva_mmu_hwmod,
+	.addr		= omap3xxx_iva_mmu_addrs,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* iva mmu slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_iva_mmu_slaves[] = {
+	&omap3xxx_l3_main__iva_mmu,
+};
+
+static struct omap_hwmod omap3xxx_iva_mmu_hwmod = {
+	.name		= "iva_mmu",
+	.class		= &omap3xxx_mmu_hwmod_class,
+	.mpu_irqs	= omap3xxx_iva_mmu_irqs,
+	.rst_lines	= omap3xxx_iva_mmu_resets,
+	.rst_lines_cnt	= ARRAY_SIZE(omap3xxx_iva_mmu_resets),
+	.main_clk	= "iva2_ck",
+	.prcm = {
+		.omap2 = {
+			.module_offs = OMAP3430_IVA2_MOD,
+		},
+	},
+	.dev_attr	= &iva_mmu_dev_attr,
+	.slaves		= omap3xxx_iva_mmu_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap3xxx_iva_mmu_slaves),
+	.flags		= HWMOD_NO_IDLEST | HWMOD_INIT_NO_RESET,
+};
+
+/*
  * usbhsotg
  */
 static struct omap_hwmod_class_sysconfig omap3xxx_usbhsotg_sysc = {
@@ -3220,6 +3347,10 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap34xx_mcspi3,
 	&omap34xx_mcspi4,
 
+	/* mmu class */
+	&omap3xxx_isp_mmu_hwmod,
+	&omap3xxx_iva_mmu_hwmod,
+
 	NULL,
 };
 
arch/arm/plat-omap/include/plat/iommu.h +13 -0
index c8b955f..e713691 100644
@@ -104,6 +104,19 @@ struct iommu_functions {
 	ssize_t (*dump_ctx)(struct omap_iommu *obj, char *buf, ssize_t len);
 };
 
+/**
+ * omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod
+ * @da_start:		device address where the va space starts.
+ * @da_end:		device address where the va space ends.
+ * @nr_tlb_entries:	number of entries supported by the translation
+ *			look-aside buffer (TLB).
+ */
+struct omap_mmu_dev_attr {
+	u32 da_start;
+	u32 da_end;
+	int nr_tlb_entries;
+};
+
 struct iommu_platform_data {
 	const char *name;
 	const char *clk_name;
Signature · 1 line
1.7.0.4
#2 lore raw

PATCH v3 2/4 OMAP4: hwmod data: add mmu hwmod for ipu and dsp

In reply to Omar Ramirez Luna

Add mmu hwmod data for ipu and dsp.

---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  154 +++++++++++++++++++++++++--
 1 files changed, 142 insertions(+), 12 deletions(-)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +142 -12
index 393afac..096b9a7 100644
@@ -30,6 +30,7 @@
 #include <plat/mmc.h>
 #include <plat/i2c.h>
 #include <plat/dmtimer.h>
+#include <plat/iommu.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -1101,10 +1102,6 @@ static struct omap_hwmod_irq_info omap44xx_dsp_irqs[] = {
 	{ .irq = -1 }
 };
 
-static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = {
-	{ .name = "mmu_cache", .rst_shift = 1 },
-};
-
 static struct omap_hwmod_rst_info omap44xx_dsp_c0_resets[] = {
 	{ .name = "dsp", .rst_shift = 0 },
 };
@@ -1156,8 +1153,6 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
 	.class		= &omap44xx_dsp_hwmod_class,
 	.clkdm_name	= "tesla_clkdm",
 	.mpu_irqs	= omap44xx_dsp_irqs,
-	.rst_lines	= omap44xx_dsp_resets,
-	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_dsp_resets),
 	.main_clk	= "dsp_fck",
 	.prcm = {
 		.omap4 = {
@@ -2507,10 +2502,6 @@ static struct omap_hwmod_rst_info omap44xx_ipu_c1_resets[] = {
 	{ .name = "cpu1", .rst_shift = 1 },
 };
 
-static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = {
-	{ .name = "mmu_cache", .rst_shift = 2 },
-};
-
 /* ipu master ports */
 static struct omap_hwmod_ocp_if *omap44xx_ipu_masters[] = {
 	&omap44xx_ipu__l3_main_2,
@@ -2564,8 +2555,6 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
 	.class		= &omap44xx_ipu_hwmod_class,
 	.clkdm_name	= "ducati_clkdm",
 	.mpu_irqs	= omap44xx_ipu_irqs,
-	.rst_lines	= omap44xx_ipu_resets,
-	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_ipu_resets),
 	.main_clk	= "ipu_fck",
 	.prcm = {
 		.omap4 = {
@@ -3932,6 +3921,143 @@ static struct omap_hwmod omap44xx_mpu_hwmod = {
 };
 
 /*
+ * 'mmu' class
+ * The memory management unit performs virtual to physical address translation
+ * for its requestors.
+ */
+
+static struct omap_hwmod_class_sysconfig mmu_sysc = {
+	.rev_offs	= 0x000,
+	.sysc_offs	= 0x010,
+	.syss_offs	= 0x014,
+	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_mmu_hwmod_class = {
+	.name = "mmu",
+	.sysc = &mmu_sysc,
+};
+
+/* ipu mmu */
+
+static struct omap_mmu_dev_attr ipu_mmu_dev_attr = {
+	.da_start = 0x0,
+	.da_end = 0xfffff000,
+	.nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap44xx_ipu_mmu_hwmod;
+static struct omap_hwmod_irq_info omap44xx_ipu_mmu_irqs[] = {
+	{ .irq = 100 + OMAP44XX_IRQ_GIC_START, },
+	{ .irq = -1 }
+};
+
+static struct omap_hwmod_rst_info omap44xx_ipu_mmu_resets[] = {
+	{ .name = "mmu_cache", .rst_shift = 2 },
+};
+
+static struct omap_hwmod_addr_space omap44xx_ipu_mmu_addrs[] = {
+	{
+		.pa_start	= 0x55082000,
+		.pa_end		= 0x550820ff,
+		.flags		= ADDR_TYPE_RT,
+	},
+	{ }
+};
+
+/* l3_main_1 -> ipu mmu */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__ipu_mmu = {
+	.master		= &omap44xx_l3_main_1_hwmod,
+	.slave		= &omap44xx_ipu_mmu_hwmod,
+	.addr		= omap44xx_ipu_mmu_addrs,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* ipu mmu slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_ipu_mmu_slaves[] = {
+	&omap44xx_l3_main_1__ipu_mmu,
+};
+
+static struct omap_hwmod omap44xx_ipu_mmu_hwmod = {
+	.name		= "ipu_mmu",
+	.class		= &omap44xx_mmu_hwmod_class,
+	.mpu_irqs	= omap44xx_ipu_mmu_irqs,
+	.rst_lines	= omap44xx_ipu_mmu_resets,
+	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_ipu_mmu_resets),
+	.main_clk	= "ipu_fck",
+	.prcm = {
+		.omap4 = {
+			.rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
+		},
+	},
+	.dev_attr	= &ipu_mmu_dev_attr,
+	.slaves		= omap44xx_ipu_mmu_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_ipu_mmu_slaves),
+	.flags		= HWMOD_INIT_NO_RESET,
+};
+
+/* dsp mmu */
+
+static struct omap_mmu_dev_attr dsp_mmu_dev_attr = {
+	.da_start = 0x0,
+	.da_end = 0xfffff000,
+	.nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap44xx_dsp_mmu_hwmod;
+static struct omap_hwmod_irq_info omap44xx_dsp_mmu_irqs[] = {
+	{ .irq = 28 + OMAP44XX_IRQ_GIC_START },
+	{ .irq = -1 }
+};
+
+static struct omap_hwmod_rst_info omap44xx_dsp_mmu_resets[] = {
+	{ .name = "mmu_cache", .rst_shift = 1 },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dsp_mmu_addrs[] = {
+	{
+		.pa_start	= 0x4a066000,
+		.pa_end		= 0x4a0660ff,
+		.flags		= ADDR_TYPE_RT,
+	},
+	{ }
+};
+
+/* l3_main_1 -> dsp mmu */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dsp_mmu = {
+	.master		= &omap44xx_l3_main_1_hwmod,
+	.slave		= &omap44xx_dsp_mmu_hwmod,
+	.addr		= omap44xx_dsp_mmu_addrs,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dsp mmu slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dsp_mmu_slaves[] = {
+	&omap44xx_l3_main_1__dsp_mmu,
+};
+
+static struct omap_hwmod omap44xx_dsp_mmu_hwmod = {
+	.name		= "dsp_mmu",
+	.class		= &omap44xx_mmu_hwmod_class,
+	.mpu_irqs	= omap44xx_dsp_mmu_irqs,
+	.rst_lines	= omap44xx_dsp_mmu_resets,
+	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_dsp_mmu_resets),
+	.main_clk	= "dsp_fck",
+	.prcm = {
+		.omap4 = {
+			.rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
+		},
+	},
+	.dev_attr	= &dsp_mmu_dev_attr,
+	.slaves		= omap44xx_dsp_mmu_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_dsp_mmu_slaves),
+	.flags		= HWMOD_INIT_NO_RESET,
+};
+
+/*
  * 'smartreflex' class
  * smartreflex module (monitor silicon performance and outputs a measure of
  * performance error)
@@ -5388,6 +5514,10 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	/* mpu class */
 	&omap44xx_mpu_hwmod,
 
+	/* mmu class */
+	&omap44xx_ipu_mmu_hwmod,
+	&omap44xx_dsp_mmu_hwmod,
+
 	/* smartreflex class */
 	&omap44xx_smartreflex_core_hwmod,
 	&omap44xx_smartreflex_iva_hwmod,
Signature · 1 line
1.7.0.4
#3 lore raw

Re: [PATCH v3 2/4] OMAP4: hwmod data: add mmu hwmod for ipu and dsp

Quoted 3 lines · Omar Ramirez Luna

Add mmu hwmod data for ipu and dsp.

[...]

Quoted 6 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +6 -0
+static struct omap_hwmod omap44xx_ipu_mmu_hwmod = {
+	.name		= "ipu_mmu",
+	.class		= &omap44xx_mmu_hwmod_class,
+	.mpu_irqs	= omap44xx_ipu_mmu_irqs,
+	.rst_lines	= omap44xx_ipu_mmu_resets,
+	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_ipu_mmu_resets),

arch/arm/mach-omap2/omap_hwmod_44xx_data.c static struct omap_hwmod omap44xx_mpu_hwmod = { · line 3999

Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +10 -0
+	.main_clk	= "ipu_fck",
+	.prcm = {
+		.omap4 = {
+			.rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
+		},
+	},
+	.dev_attr	= &ipu_mmu_dev_attr,
+	.slaves		= omap44xx_ipu_mmu_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_ipu_mmu_slaves),
+	.flags		= HWMOD_INIT_NO_RESET,

Why is this needed?

[...]

Quoted 6 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +6 -0
+static struct omap_hwmod omap44xx_dsp_mmu_hwmod = {
+	.name		= "dsp_mmu",
+	.class		= &omap44xx_mmu_hwmod_class,
+	.mpu_irqs	= omap44xx_dsp_mmu_irqs,
+	.rst_lines	= omap44xx_dsp_mmu_resets,
+	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_dsp_mmu_resets),

arch/arm/mach-omap2/omap_hwmod_44xx_data.c static struct omap_hwmod omap44xx_mpu_hwmod = { · line 4057

Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +10 -0
+	.main_clk	= "dsp_fck",
+	.prcm = {
+		.omap4 = {
+			.rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
+		},
+	},
+	.dev_attr	= &dsp_mmu_dev_attr,
+	.slaves		= omap44xx_dsp_mmu_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_dsp_mmu_slaves),
+	.flags		= HWMOD_INIT_NO_RESET,

And this?

Kevin

#4 lore raw

Re: [PATCH v3 2/4] OMAP4: hwmod data: add mmu hwmod for ipu and dsp

Hi,

Quoted 3 lines · Kevin Hilman
Quoted 1 line

+ ? ? .flags ? ? ? ? ?= HWMOD_INIT_NO_RESET,

Why is this needed?

...

Quoted 3 lines
Quoted 1 line

+ ? ? .flags ? ? ? ? ?= HWMOD_INIT_NO_RESET,

And this?

I have this because the hwmod complains about a failure in hard reset, even though the reset deassert does complete after the clock is enabled. Later on, hwmod will warn again because of a wrong state when enabling, I believe because of the failure on _setup but didn't dig into it yet.

Regards,

Omar

#5 lore raw

Re: [PATCH v3 2/4] OMAP4: hwmod data: add mmu hwmod for ipu and dsp

Quoted 9 lines · Omar

Hi,

Quoted 3 lines · Kevin Hilman
Quoted 1 line

+ ? ? .flags ? ? ? ? ?= HWMOD_INIT_NO_RESET,

Why is this needed?

...

Quoted 2 lines
Quoted 1 line

+ ? ? .flags ? ? ? ? ?= HWMOD_INIT_NO_RESET,

Quoted 7 lines
Quoted 1 line

And this?

I have this because the hwmod complains about a failure in hard reset, even though the reset deassert does complete after the clock is enabled. Later on, hwmod will warn again because of a wrong state when enabling, I believe because of the failure on _setup but didn't dig into it yet.

Please dig deeper into the reset failure.

We don't merge HWMOD_INIT_NO_RESET changes without a very good reason (that is also well described in the changelog.)

Thanks,

Kevin

#6 lore raw

PATCH v3 3/4 OMAP3/4: iommu: migrate to hwmod framework

In reply to Omar Ramirez Luna

Use hwmod data and device attributes to build and register an omap device for iommu driver.

- Update the naming convention in isp module.
- Remove unneeded check for number of resources, as this is now handled by omap_device and prevents driver from loading.
- Now unused, remove platform device and resource data, handling of sysconfig register for softreset purposes; and add device latency in preparation for runtime PM.

---
 arch/arm/mach-omap2/iommu2.c            |   19 ----
 arch/arm/mach-omap2/omap-iommu.c        |  163 ++++++------------------------
 arch/arm/plat-omap/include/plat/iommu.h |    2 +-
 drivers/iommu/omap-iommu.c              |    3 -
 drivers/media/video/omap3isp/isp.c      |    2 +-
 5 files changed, 35 insertions(+), 154 deletions(-)
arch/arm/mach-omap2/iommu2.c +0 -19
index 6ca3438..60e3363 100644
@@ -32,12 +32,8 @@
 #define MMU_SYS_IDLE_SMART	(2 << MMU_SYS_IDLE_SHIFT)
 #define MMU_SYS_IDLE_MASK	(3 << MMU_SYS_IDLE_SHIFT)
 
-#define MMU_SYS_SOFTRESET	(1 << 1)
 #define MMU_SYS_AUTOIDLE	1
 
-/* SYSSTATUS */
-#define MMU_SYS_RESETDONE	1
-
 /* IRQSTATUS & IRQENABLE */
 #define MMU_IRQ_MULTIHITFAULT	(1 << 4)
 #define MMU_IRQ_TABLEWALKFAULT	(1 << 3)
@@ -88,7 +84,6 @@ static void __iommu_set_twl(struct omap_iommu *obj, bool on)
 static int omap2_iommu_enable(struct omap_iommu *obj)
 {
 	u32 l, pa;
-	unsigned long timeout;
 
 	if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd,  SZ_16K))
 		return -EINVAL;
@@ -97,20 +92,6 @@ static int omap2_iommu_enable(struct omap_iommu *obj)
 	if (!IS_ALIGNED(pa, SZ_16K))
 		return -EINVAL;
 
-	iommu_write_reg(obj, MMU_SYS_SOFTRESET, MMU_SYSCONFIG);
-
-	timeout = jiffies + msecs_to_jiffies(20);
-	do {
-		l = iommu_read_reg(obj, MMU_SYSSTATUS);
-		if (l & MMU_SYS_RESETDONE)
-			break;
-	} while (!time_after(jiffies, timeout));
-
-	if (!(l & MMU_SYS_RESETDONE)) {
-		dev_err(obj->dev, "can't take mmu out of reset\n");
-		return -ENODEV;
-	}
-
 	l = iommu_read_reg(obj, MMU_REVISION);
 	dev_info(obj->dev, "%s: version %d.%d\n", obj->name,
 		 (l >> 4) & 0xf, l & 0xf);
arch/arm/mach-omap2/omap-iommu.c +33 -130

185 lines not on this page · raw message

arch/arm/plat-omap/include/plat/iommu.h +1 -1
index e713691..01927a5 100644
@@ -120,7 +120,7 @@ struct omap_mmu_dev_attr {
 struct iommu_platform_data {
 	const char *name;
 	const char *clk_name;
-	const int nr_tlb_entries;
+	int nr_tlb_entries;
 	u32 da_start;
 	u32 da_end;
 };
drivers/iommu/omap-iommu.c +0 -3
index cc5dca7..bbbf747 100644
@@ -1006,9 +1006,6 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct iommu_platform_data *pdata = pdev->dev.platform_data;
 
-	if (pdev->num_resources != 2)
-		return -EINVAL;
-
 	obj = kzalloc(sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
 	if (!obj)
 		return -ENOMEM;
drivers/media/video/omap3isp/isp.c +1 -1
index a4baa61..b4eea7b 100644
@@ -2131,7 +2131,7 @@ static int isp_probe(struct platform_device *pdev)
 	}
 
 	/* IOMMU */
-	isp->iommu_dev = omap_find_iommu_device("isp");
+	isp->iommu_dev = omap_find_iommu_device("isp_mmu");
 	if (!isp->iommu_dev) {
 		dev_err(isp->dev, "omap_find_iommu_device failed\n");
 		ret = -ENODEV;
Signature · 1 line
1.7.0.4
#7 lore raw

PATCH v3 4/4 OMAP3/4: iommu: adapt to runtime pm

In reply to Omar Ramirez Luna

Use runtime PM functionality interfaced with hwmod enable/idle functions, to replace direct clock operations, reset and sysconfig handling.

Tidspbridge uses a macro removed with this patch, for now the value is hardcoded to avoid breaking compilation.

---
 arch/arm/mach-omap2/iommu2.c                      |   17 --------
 arch/arm/mach-omap2/omap-iommu.c                  |    1 -
 arch/arm/plat-omap/include/plat/iommu.h           |    2 -
 arch/arm/plat-omap/include/plat/iommu2.h          |    2 -
 drivers/iommu/omap-iommu.c                        |   46 ++++++++-------------
 drivers/staging/tidspbridge/core/tiomap3430_pwr.c |    2 +-
 6 files changed, 19 insertions(+), 51 deletions(-)
arch/arm/mach-omap2/iommu2.c +0 -17
index 60e3363..5adad97 100644
@@ -25,15 +25,6 @@
  */
 #define IOMMU_ARCH_VERSION	0x00000011
 
-/* SYSCONF */
-#define MMU_SYS_IDLE_SHIFT	3
-#define MMU_SYS_IDLE_FORCE	(0 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_NONE	(1 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_SMART	(2 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_MASK	(3 << MMU_SYS_IDLE_SHIFT)
-
-#define MMU_SYS_AUTOIDLE	1
-
 /* IRQSTATUS & IRQENABLE */
 #define MMU_IRQ_MULTIHITFAULT	(1 << 4)
 #define MMU_IRQ_TABLEWALKFAULT	(1 << 3)
@@ -96,11 +87,6 @@ static int omap2_iommu_enable(struct omap_iommu *obj)
 	dev_info(obj->dev, "%s: version %d.%d\n", obj->name,
 		 (l >> 4) & 0xf, l & 0xf);
 
-	l = iommu_read_reg(obj, MMU_SYSCONFIG);
-	l &= ~MMU_SYS_IDLE_MASK;
-	l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
-	iommu_write_reg(obj, l, MMU_SYSCONFIG);
-
 	iommu_write_reg(obj, pa, MMU_TTB);
 
 	__iommu_set_twl(obj, true);
@@ -114,7 +100,6 @@ static void omap2_iommu_disable(struct omap_iommu *obj)
 
 	l &= ~MMU_CNTL_MASK;
 	iommu_write_reg(obj, l, MMU_CNTL);
-	iommu_write_reg(obj, MMU_SYS_IDLE_FORCE, MMU_SYSCONFIG);
 
 	dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
 }
@@ -244,8 +229,6 @@ omap2_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len)
 	char *p = buf;
 
 	pr_reg(REVISION);
-	pr_reg(SYSCONFIG);
-	pr_reg(SYSSTATUS);
 	pr_reg(IRQSTATUS);
 	pr_reg(IRQENABLE);
 	pr_reg(WALKING_ST);
arch/arm/mach-omap2/omap-iommu.c +0 -1
index 669fd07..cad98c7 100644
@@ -34,7 +34,6 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
 	static int i;
 
 	pdata.name = oh->name;
-	pdata.clk_name = oh->main_clk;
 	pdata.nr_tlb_entries = a->nr_tlb_entries;
 	pdata.da_start = a->da_start;
 	pdata.da_end = a->da_end;
arch/arm/plat-omap/include/plat/iommu.h +0 -2
index 01927a5..3842e99 100644
@@ -28,7 +28,6 @@ struct iotlb_entry {
 struct omap_iommu {
 	const char	*name;
 	struct module	*owner;
-	struct clk	*clk;
 	void __iomem	*regbase;
 	struct device	*dev;
 	void		*isr_priv;
@@ -119,7 +118,6 @@ struct omap_mmu_dev_attr {
 
 struct iommu_platform_data {
 	const char *name;
-	const char *clk_name;
 	int nr_tlb_entries;
 	u32 da_start;
 	u32 da_end;
arch/arm/plat-omap/include/plat/iommu2.h +0 -2
index d4116b5..1579694 100644
@@ -19,8 +19,6 @@
  * MMU Register offsets
  */
 #define MMU_REVISION		0x00
-#define MMU_SYSCONFIG		0x10
-#define MMU_SYSSTATUS		0x14
 #define MMU_IRQSTATUS		0x18
 #define MMU_IRQENABLE		0x1c
 #define MMU_WALKING_ST		0x40
drivers/iommu/omap-iommu.c +18 -28

168 lines not on this page · raw message

drivers/staging/tidspbridge/core/tiomap3430_pwr.c +1 -1
index 8889a8c..0b7c29d 100644
@@ -329,7 +329,7 @@ int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
 		omap_mbox_restore_ctx(dev_context->mbox);
 
 		/* Access MMU SYS CONFIG register to generate a short wakeup */
-		iommu_read_reg(dev_context->mmu, MMU_SYSCONFIG);
+		iommu_read_reg(dev_context->mmu, 0x10);
 
 		dev_context->brd_state = BRD_RUNNING;
 
Signature · 1 line
1.7.0.4
#8 lore raw

Re: [PATCH v3 4/4] OMAP3/4: iommu: adapt to runtime pm

Quoted 37 lines · Omar Ramirez Luna

Use runtime PM functionality interfaced with hwmod enable/idle functions, to replace direct clock operations, reset and sysconfig handling.

Tidspbridge uses a macro removed with this patch, for now the value is hardcoded to avoid breaking compilation.

---

?arch/arm/mach-omap2/iommu2.c ? ? ? ? ? ? ? ? ? ? ?| ? 17 --------
?arch/arm/mach-omap2/omap-iommu.c ? ? ? ? ? ? ? ? ?| ? ?1 -
?arch/arm/plat-omap/include/plat/iommu.h ? ? ? ? ? | ? ?2 -
?arch/arm/plat-omap/include/plat/iommu2.h ? ? ? ? ?| ? ?2 -
?drivers/iommu/omap-iommu.c ? ? ? ? ? ? ? ? ? ? ? ?| ? 46 ++++++++-------------
?drivers/staging/tidspbridge/core/tiomap3430_pwr.c | ? ?2 +-

?6 files changed, 19 insertions(+), 51 deletions(-)

drivers/iommu/omap-iommu.c +2 -2
index bbbf747..3c55be0 100644
@@ -123,11 +123,11 @@ static int iommu_enable(struct omap_iommu *obj)
 ? ? ? ?if (!arch_iommu)
 ? ? ? ? ? ? ? ?return -ENODEV;
 
- ? ? ? clk_enable(obj->clk);
+ ? ? ? pm_runtime_enable(obj->dev);
+ ? ? ? pm_runtime_get_sync(obj->dev);
 
 ? ? ? ?err = arch_iommu->enable(obj);
 
- ? ? ? clk_disable(obj->clk);
 ? ? ? ?return err;
 ?}
 
@@ -136,11 +136,10 @@ static void iommu_disable(struct omap_iommu *obj)
 ? ? ? ?if (!obj)

drivers/iommu/omap-iommu.c static void iommu_disable(struct omap_iommu *obj) · line 143

Quoted 10 lines
drivers/iommu/omap-iommu.c +2 -3
 ? ? ? ? ? ? ? ?return;
 
- ? ? ? clk_enable(obj->clk);
-
 ? ? ? ?arch_iommu->disable(obj);
 
- ? ? ? clk_disable(obj->clk);
+ ? ? ? pm_runtime_put_sync(obj->dev);
+ ? ? ? pm_runtime_disable(obj->dev);
 ?}

Hello Omar,

I'm just curious here... Is there any reason to do pm_runtime_enable/disable at iommu_enable/iommu_disable which are called by iommu_attach/detach?
I thought that normally, ideal locations of pm_runtime_enable/disable for such devices are in probe/remove() because it assures that the device is suspended after the probe.
It seems that the device might be kept on after probe and before the first iommu_attach if it is default-on.

Thanks,
MyungJoo

Signature · 2 lines
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics
#9 lore raw

Re: [PATCH v3 4/4] OMAP3/4: iommu: adapt to runtime pm

Hi MyungJoo,

Quoted 44 lines · MyungJoo Ham
Quoted 43 lines · Omar Ramirez Luna

Use runtime PM functionality interfaced with hwmod enable/idle functions, to replace direct clock operations, reset and sysconfig handling.

Tidspbridge uses a macro removed with this patch, for now the value is hardcoded to avoid breaking compilation.

---

?arch/arm/mach-omap2/iommu2.c ? ? ? ? ? ? ? ? ? ? ?| ? 17 --------
?arch/arm/mach-omap2/omap-iommu.c ? ? ? ? ? ? ? ? ?| ? ?1 -
?arch/arm/plat-omap/include/plat/iommu.h ? ? ? ? ? | ? ?2 -
?arch/arm/plat-omap/include/plat/iommu2.h ? ? ? ? ?| ? ?2 -
?drivers/iommu/omap-iommu.c ? ? ? ? ? ? ? ? ? ? ? ?| ? 46 ++++++++-------------
?drivers/staging/tidspbridge/core/tiomap3430_pwr.c | ? ?2 +-

?6 files changed, 19 insertions(+), 51 deletions(-)

drivers/iommu/omap-iommu.c +2 -4
index bbbf747..3c55be0 100644
@@ -123,11 +123,11 @@ static int iommu_enable(struct omap_iommu *obj)
 ? ? ? ?if (!arch_iommu)
 ? ? ? ? ? ? ? ?return -ENODEV;
 
- ? ? ? clk_enable(obj->clk);
+ ? ? ? pm_runtime_enable(obj->dev);
+ ? ? ? pm_runtime_get_sync(obj->dev);
 
 ? ? ? ?err = arch_iommu->enable(obj);
 
- ? ? ? clk_disable(obj->clk);
 ? ? ? ?return err;
 ?}
 
@@ -136,11 +136,10 @@ static void iommu_disable(struct omap_iommu *obj)
 ? ? ? ?if (!obj)
 ? ? ? ? ? ? ? ?return;
 
- ? ? ? clk_enable(obj->clk);
-
 ? ? ? ?arch_iommu->disable(obj);
 
Quoted 12 lines

drivers/iommu/omap-iommu.c static void iommu_disable(struct omap_iommu *obj) · line 143

Quoted 4 lines
drivers/iommu/omap-iommu.c +2 -1
- ? ? ? clk_disable(obj->clk);
+ ? ? ? pm_runtime_put_sync(obj->dev);
+ ? ? ? pm_runtime_disable(obj->dev);
 ?}

I'm just curious here... Is there any reason to do pm_runtime_enable/disable at iommu_enable/iommu_disable which are called by iommu_attach/detach?
I thought that normally, ideal locations of pm_runtime_enable/disable for such devices are in probe/remove() because it assures that the device is suspended after the probe.
It seems that the device might be kept on after probe and before the first iommu_attach if it is default-on.

The default state of these MMUs is on reset and needs to be deasserted to be used, but you're right, it makes more sense to move pm_runtime_enable/disable calls to probe/remove. I'll wait a bit, do this change and resubmit.

Thanks for the comment,

Omar

#10 lore raw

Re: [PATCH v3 4/4] OMAP3/4: iommu: adapt to runtime pm

In reply to Omar Ramirez Luna
Quoted 6 lines · Omar Ramirez Luna

Use runtime PM functionality interfaced with hwmod enable/idle functions, to replace direct clock operations, reset and sysconfig handling.

Tidspbridge uses a macro removed with this patch, for now the value is hardcoded to avoid breaking compilation.

You probably want to include people involved with power management on this, so maybe the linux-pm mailing list, and those involved with runtime-pm stuff (I think Rafael qualifies as the maintainer for this stuff, even if he's not listed in MAINTAINERS.)

Quoted 310 lines
---
 arch/arm/mach-omap2/iommu2.c                      |   17 --------
 arch/arm/mach-omap2/omap-iommu.c                  |    1 -
 arch/arm/plat-omap/include/plat/iommu.h           |    2 -
 arch/arm/plat-omap/include/plat/iommu2.h          |    2 -
 drivers/iommu/omap-iommu.c                        |   46 ++++++++-------------
 drivers/staging/tidspbridge/core/tiomap3430_pwr.c |    2 +-
 6 files changed, 19 insertions(+), 51 deletions(-)
arch/arm/mach-omap2/iommu2.c +0 -17
index 60e3363..5adad97 100644
@@ -25,15 +25,6 @@
  */
 #define IOMMU_ARCH_VERSION	0x00000011
 
-/* SYSCONF */
-#define MMU_SYS_IDLE_SHIFT	3
-#define MMU_SYS_IDLE_FORCE	(0 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_NONE	(1 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_SMART	(2 << MMU_SYS_IDLE_SHIFT)
-#define MMU_SYS_IDLE_MASK	(3 << MMU_SYS_IDLE_SHIFT)
-
-#define MMU_SYS_AUTOIDLE	1
-
 /* IRQSTATUS & IRQENABLE */
 #define MMU_IRQ_MULTIHITFAULT	(1 << 4)
 #define MMU_IRQ_TABLEWALKFAULT	(1 << 3)
@@ -96,11 +87,6 @@ static int omap2_iommu_enable(struct omap_iommu *obj)
 	dev_info(obj->dev, "%s: version %d.%d\n", obj->name,
 		 (l >> 4) & 0xf, l & 0xf);
 
-	l = iommu_read_reg(obj, MMU_SYSCONFIG);
-	l &= ~MMU_SYS_IDLE_MASK;
-	l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
-	iommu_write_reg(obj, l, MMU_SYSCONFIG);
-
 	iommu_write_reg(obj, pa, MMU_TTB);
 
 	__iommu_set_twl(obj, true);
@@ -114,7 +100,6 @@ static void omap2_iommu_disable(struct omap_iommu *obj)
 
 	l &= ~MMU_CNTL_MASK;
 	iommu_write_reg(obj, l, MMU_CNTL);
-	iommu_write_reg(obj, MMU_SYS_IDLE_FORCE, MMU_SYSCONFIG);
 
 	dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
 }
@@ -244,8 +229,6 @@ omap2_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len)
 	char *p = buf;
 
 	pr_reg(REVISION);
-	pr_reg(SYSCONFIG);
-	pr_reg(SYSSTATUS);
 	pr_reg(IRQSTATUS);
 	pr_reg(IRQENABLE);
 	pr_reg(WALKING_ST);
arch/arm/mach-omap2/omap-iommu.c +0 -1
index 669fd07..cad98c7 100644
@@ -34,7 +34,6 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
 	static int i;
 
 	pdata.name = oh->name;
-	pdata.clk_name = oh->main_clk;
 	pdata.nr_tlb_entries = a->nr_tlb_entries;
 	pdata.da_start = a->da_start;
 	pdata.da_end = a->da_end;
arch/arm/plat-omap/include/plat/iommu.h +0 -2
index 01927a5..3842e99 100644
@@ -28,7 +28,6 @@ struct iotlb_entry {
 struct omap_iommu {
 	const char	*name;
 	struct module	*owner;
-	struct clk	*clk;
 	void __iomem	*regbase;
 	struct device	*dev;
 	void		*isr_priv;
@@ -119,7 +118,6 @@ struct omap_mmu_dev_attr {
 
 struct iommu_platform_data {
 	const char *name;
-	const char *clk_name;
 	int nr_tlb_entries;
 	u32 da_start;
 	u32 da_end;
arch/arm/plat-omap/include/plat/iommu2.h +0 -2
index d4116b5..1579694 100644
@@ -19,8 +19,6 @@
  * MMU Register offsets
  */
 #define MMU_REVISION		0x00
-#define MMU_SYSCONFIG		0x10
-#define MMU_SYSSTATUS		0x14
 #define MMU_IRQSTATUS		0x18
 #define MMU_IRQENABLE		0x1c
 #define MMU_WALKING_ST		0x40
drivers/iommu/omap-iommu.c +18 -28
index bbbf747..3c55be0 100644
@@ -16,11 +16,11 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/iommu.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/cacheflush.h>
 
@@ -123,11 +123,11 @@ static int iommu_enable(struct omap_iommu *obj)
 	if (!arch_iommu)
 		return -ENODEV;
 
-	clk_enable(obj->clk);
+	pm_runtime_enable(obj->dev);
+	pm_runtime_get_sync(obj->dev);
 
 	err = arch_iommu->enable(obj);
 
-	clk_disable(obj->clk);
 	return err;
 }
 
@@ -136,11 +136,10 @@ static void iommu_disable(struct omap_iommu *obj)
 	if (!obj)
 		return;
 
-	clk_enable(obj->clk);
-
 	arch_iommu->disable(obj);
 
-	clk_disable(obj->clk);
+	pm_runtime_put_sync(obj->dev);
+	pm_runtime_disable(obj->dev);
 }
 
 /*
@@ -264,7 +263,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
 	if (!obj || !obj->nr_tlb_entries || !e)
 		return -EINVAL;
 
-	clk_enable(obj->clk);
+	pm_runtime_get_sync(obj->dev);
 
 	iotlb_lock_get(obj, &l);
 	if (l.base == obj->nr_tlb_entries) {
@@ -294,7 +293,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
 
 	cr = iotlb_alloc_cr(obj, e);
 	if (IS_ERR(cr)) {
-		clk_disable(obj->clk);
+		pm_runtime_put(obj->dev);
 		return PTR_ERR(cr);
 	}
 
@@ -308,7 +307,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
 		l.vict = l.base;
 	iotlb_lock_set(obj, &l);
 out:
-	clk_disable(obj->clk);
+	pm_runtime_put(obj->dev);
 	return err;
 }
 EXPORT_SYMBOL_GPL(load_iotlb_entry);
@@ -339,7 +338,7 @@ static void flush_iotlb_page(struct omap_iommu *obj, u32 da)
 	int i;
 	struct cr_regs cr;
 
-	clk_enable(obj->clk);
+	pm_runtime_get_sync(obj->dev);
 
 	for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) {
 		u32 start;
@@ -358,7 +357,7 @@ static void flush_iotlb_page(struct omap_iommu *obj, u32 da)
 			iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
 		}
 	}
-	clk_disable(obj->clk);
+	pm_runtime_put(obj->dev);
 
 	if (i == obj->nr_tlb_entries)
 		dev_dbg(obj->dev, "%s: no page for %08x\n", __func__, da);
@@ -393,7 +392,7 @@ static void flush_iotlb_all(struct omap_iommu *obj)
 {
 	struct iotlb_lock l;
 
-	clk_enable(obj->clk);
+	pm_runtime_get_sync(obj->dev);
 
 	l.base = 0;
 	l.vict = 0;
@@ -401,7 +400,7 @@ static void flush_iotlb_all(struct omap_iommu *obj)
 
 	iommu_write_reg(obj, 1, MMU_GFLUSH);
 
-	clk_disable(obj->clk);
+	pm_runtime_put(obj->dev);
 }
 EXPORT_SYMBOL_GPL(flush_iotlb_all);
 
@@ -416,9 +415,9 @@ EXPORT_SYMBOL_GPL(flush_iotlb_all);
  */
 void iommu_set_twl(struct omap_iommu *obj, bool on)
 {
-	clk_enable(obj->clk);
+	pm_runtime_get_sync(obj->dev);
 	arch_iommu->set_twl(obj, on);
-	clk_disable(obj->clk);
+	pm_runtime_put(obj->dev);
 }
 EXPORT_SYMBOL_GPL(iommu_set_twl);
 
@@ -429,11 +428,11 @@ ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t bytes)
 	if (!obj || !buf)
 		return -EINVAL;
 
-	clk_enable(obj->clk);
+	pm_runtime_get_sync(obj->dev);
 
 	bytes = arch_iommu->dump_ctx(obj, buf, bytes);
 
-	clk_disable(obj->clk);
+	pm_runtime_put(obj->dev);
 
 	return bytes;
 }
@@ -447,7 +446,7 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num)
 	struct cr_regs tmp;
 	struct cr_regs *p = crs;
 
-	clk_enable(obj->clk);
+	pm_runtime_get_sync(obj->dev);
 	iotlb_lock_get(obj, &saved);
 
 	for_each_iotlb_cr(obj, num, i, tmp) {
@@ -457,7 +456,7 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num)
 	}
 
 	iotlb_lock_set(obj, &saved);
-	clk_disable(obj->clk);
+	pm_runtime_put(obj->dev);
 
 	return  p - crs;
 }
@@ -821,9 +820,7 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
 	if (!obj->refcount)
 		return IRQ_NONE;
 
-	clk_enable(obj->clk);
 	errs = iommu_report_fault(obj, &da);
-	clk_disable(obj->clk);
 	if (errs == 0)
 		return IRQ_HANDLED;
 
@@ -1010,10 +1007,6 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
 	if (!obj)
 		return -ENOMEM;
 
-	obj->clk = clk_get(&pdev->dev, pdata->clk_name);
-	if (IS_ERR(obj->clk))
-		goto err_clk;
-
 	obj->nr_tlb_entries = pdata->nr_tlb_entries;
 	obj->name = pdata->name;
 	obj->dev = &pdev->dev;
@@ -1064,8 +1057,6 @@ err_irq:
 err_ioremap:
 	release_mem_region(res->start, resource_size(res));
 err_mem:
-	clk_put(obj->clk);
-err_clk:
 	kfree(obj);
 	return err;
 }
@@ -1086,7 +1077,6 @@ static int __devexit omap_iommu_remove(struct platform_device *pdev)
 	release_mem_region(res->start, resource_size(res));
 	iounmap(obj->regbase);
 
-	clk_put(obj->clk);
 	dev_info(&pdev->dev, "%s removed\n", obj->name);
 	kfree(obj);
 	return 0;
drivers/staging/tidspbridge/core/tiomap3430_pwr.c +1 -1
index 8889a8c..0b7c29d 100644
@@ -329,7 +329,7 @@ int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
 		omap_mbox_restore_ctx(dev_context->mbox);
 
 		/* Access MMU SYS CONFIG register to generate a short wakeup */
-		iommu_read_reg(dev_context->mmu, MMU_SYSCONFIG);
+		iommu_read_reg(dev_context->mmu, 0x10);
 
 		dev_context->brd_state = BRD_RUNNING;
 
Signature · 1 line
1.7.0.4
#11 lore raw

Re: [PATCH v3 4/4] OMAP3/4: iommu: adapt to runtime pm

Quoted 5 lines · Russell King - ARM Linux
Quoted 4 lines · Omar Ramirez Luna

Use runtime PM functionality interfaced with hwmod enable/idle functions, to replace direct clock operations, reset and sysconfig handling.

Quoted 7 lines
Quoted 2 lines

Tidspbridge uses a macro removed with this patch, for now the value is hardcoded to avoid breaking compilation.

You probably want to include people involved with power management on this, so maybe the linux-pm mailing list, and those involved with runtime-pm stuff (I think Rafael qualifies as the maintainer for this stuff, even if he's not listed in MAINTAINERS.)

Will do, I'll submit it again if no other comments are received.

Regards,

Omar

#12 lore raw

Re: [PATCH v3 4/4] OMAP3/4: iommu: adapt to runtime pm

In reply to Omar Ramirez Luna
Quoted 8 lines · Omar Ramirez Luna

Use runtime PM functionality interfaced with hwmod enable/idle functions, to replace direct clock operations, reset and sysconfig handling.

Tidspbridge uses a macro removed with this patch, for now the value is hardcoded to avoid breaking compilation.

Looks like a good cleanup.

I agree with the comments from Myungjoo, and have a question below..

[...]

drivers/iommu/omap-iommu.c static irqreturn_t iommu_fault_handler(int irq, void *data) · line 825

Quoted 9 lines
drivers/iommu/omap-iommu.c +0 -2
@@ -821,9 +820,7 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
 	if (!obj->refcount)
 		return IRQ_NONE;
 
-	clk_enable(obj->clk);
 	errs = iommu_report_fault(obj, &da);
-	clk_disable(obj->clk);
 	if (errs == 0)
 		return IRQ_HANDLED;

I'm not terribly familiar with this IOMMU code, but this one looks suspiciou because you're removing the clock calls but not replacing them with runtime PM get/put calls.

I just want to make sure that's intentional. If so, you might want to add a comment about that to the changelog.

Kevin

#13 lore raw

Re: [PATCH v3 4/4] OMAP3/4: iommu: adapt to runtime pm

Hi,

Quoted 14 lines · Kevin Hilman

Review static irqreturn_t iommu_fault_handler(int irq, void *data) · line 825

Quoted 9 lines
(quoted diff) +0 -2
@@ -821,9 +820,7 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
 ? ? ? if (!obj->refcount)
 ? ? ? ? ? ? ? return IRQ_NONE;
 
- ? ? clk_enable(obj->clk);
 ? ? ? errs = iommu_report_fault(obj, &da);
- ? ? clk_disable(obj->clk);
 ? ? ? if (errs == 0)
 ? ? ? ? ? ? ? return IRQ_HANDLED;

I'm not terribly familiar with this IOMMU code, but this one looks suspiciou because you're removing the clock calls but not replacing them with runtime PM get/put calls.

Quoted 2 lines

I just want to make sure that's intentional. ?If so, you might want to add a comment about that to the changelog.

Yes it is intentional, reason is that in order to get an interrupt, the device should be powered on in advance, right now it is working because the modules share a common clock so the users of the omap-iommu indirectly give power to it. However I made another change to do pm_runtime_get/put on attach/detach so it doesn't rely on others to keep the clocks on.

I'll add the comment.

Thanks,

Omar

#14 lore raw
In reply to Omar Ramirez Luna

+ Joerg, iommu-list

Quoted 34 lines · Omar Ramirez Luna

Introduced hwmod support for OMAP3 (iva, isp) and OMAP4 (ipu, dsp), along with the corresponding runtime PM routines to deassert reset lines, enable/disable clocks and configure sysc registers.

v3:
- Rebased to 3.1-rc10 lo rebuilt, added structure terminators, and removed .omap_chip field.

v2:
- Added oh reset info to assert/deassert mmu reset lines.
- Addressed previous comments on v1
http://www.spinics.net/lists/arm-kernel/msg103271.html

Due to compatibility an ifdef needs to be propagated (previously on iommu resource info) to hwmod data in OMAP3, so users of iommu and tidspbridge can avoid issues of two modules managing mmu data/irqs/resets; this until tidspbridge can be safely migrated to iommu framework.

Omar Ramirez Luna (4):
?OMAP3: hwmod data: add mmu data for iva and isp
?OMAP4: hwmod data: add mmu hwmod for ipu and dsp
?OMAP3/4: iommu: migrate to hwmod framework
?OMAP3/4: iommu: adapt to runtime pm

?arch/arm/mach-omap2/iommu2.c ? ? ? ? ? ? ? ? ? ? ?| ? 36 -----
?arch/arm/mach-omap2/omap-iommu.c ? ? ? ? ? ? ? ? ?| ?162 ++++-----------------
?arch/arm/mach-omap2/omap_hwmod_3xxx_data.c ? ? ? ?| ?131 +++++++++++++++++
?arch/arm/mach-omap2/omap_hwmod_44xx_data.c ? ? ? ?| ?154 ++++++++++++++++++--
?arch/arm/plat-omap/include/plat/iommu.h ? ? ? ? ? | ? 17 ++-
?arch/arm/plat-omap/include/plat/iommu2.h ? ? ? ? ?| ? ?2 -
?drivers/iommu/omap-iommu.c ? ? ? ? ? ? ? ? ? ? ? ?| ? 49 +++----
?drivers/media/video/omap3isp/isp.c ? ? ? ? ? ? ? ?| ? ?2 +-
?drivers/staging/tidspbridge/core/tiomap3430_pwr.c | ? ?2 +-

?9 files changed, 339 insertions(+), 216 deletions(-)