[PATCH v5 2/5] iommu/omap: keep mmu enabled when requested

2012-11-19 Thread Omar Ramirez Luna
The purpose of the mmu is to handle the memory accesses requested by
its users. Typically, the mmu is bundled with the processing unit in
a single IP block, which makes them to share the same clock to be
functional.

Currently, iommu code assumes that its user will be indirectly
clocking it, but being a separate mmu driver, it should handle
its own clocks, so as long as the mmu is requested it will be
powered ON and once detached it will be powered OFF.

The remaining clock handling out of iommu_enable and iommu_disable
corresponds to paths that can be accessed through debugfs, some of
them doesn't work if the module is not enabled first, but in future
if the mmu is idled withouth freeing, these are needed to debug.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 drivers/iommu/omap-iommu.c |3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 6b1288c..f8082da 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -154,7 +154,6 @@ static int iommu_enable(struct omap_iommu *obj)
 
err = arch_iommu-enable(obj);
 
-   clk_disable(obj-clk);
return err;
 }
 
@@ -163,8 +162,6 @@ static void iommu_disable(struct omap_iommu *obj)
if (!obj)
return;
 
-   clk_enable(obj-clk);
-
arch_iommu-disable(obj);
 
clk_disable(obj-clk);
-- 
1.7.4.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 4/5] iommu/omap: adapt to runtime pm

2012-11-19 Thread Omar Ramirez Luna
Use runtime PM functionality interfaced with hwmod enable/idle
functions, to replace direct clock operations and sysconfig
handling.

Due to reset sequence, pm_runtime_[get|put]_sync must be used, to
avoid possible operations with the module under reset. Because of
this and given that the driver uses spin_locks to protect their
critical sections, we must use pm_runtime_irq_safe in order for the
runtime ops to be happy, otherwise might_sleep_if checks in runtime
framework will complain.

The remaining pm_runtime out of iommu_enable and iommu_disable
corresponds to paths that can be accessed through debugfs, some of
them doesn't work if the module is not enabled first, but in future
if the mmu is idled withouth freeing, these are needed to debug.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 arch/arm/mach-omap2/omap-iommu.c |1 -
 drivers/iommu/omap-iommu.c   |   40 ++---
 drivers/iommu/omap-iommu.h   |3 --
 drivers/iommu/omap-iommu2.c  |   17 
 include/linux/platform_data/iommu-omap.h |1 -
 5 files changed, 19 insertions(+), 43 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index 02726a6..7642fc4 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -31,7 +31,6 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, 
void *unused)
return -ENOMEM;
 
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;
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index af9b4f3..18108c14 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -16,13 +16,13 @@
 #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/omap-iommu.h
 #include linux/mutex.h
 #include linux/spinlock.h
 #include linux/io.h
+#include linux/pm_runtime.h
 
 #include asm/cacheflush.h
 
@@ -160,7 +160,7 @@ static int iommu_enable(struct omap_iommu *obj)
}
}
 
-   clk_enable(obj-clk);
+   pm_runtime_get_sync(obj-dev);
 
err = arch_iommu-enable(obj);
 
@@ -177,7 +177,7 @@ static void iommu_disable(struct omap_iommu *obj)
 
arch_iommu-disable(obj);
 
-   clk_disable(obj-clk);
+   pm_runtime_put_sync(obj-dev);
 
if (pdata-assert_reset)
pdata-assert_reset(pdev, pdata-reset_name);
@@ -303,7 +303,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) {
@@ -333,7 +333,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_sync(obj-dev);
return PTR_ERR(cr);
}
 
@@ -347,7 +347,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_sync(obj-dev);
return err;
 }
 
@@ -377,7 +377,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;
@@ -396,7 +396,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_sync(obj-dev);
 
if (i == obj-nr_tlb_entries)
dev_dbg(obj-dev, %s: no page for %08x\n, __func__, da);
@@ -410,7 +410,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;
@@ -418,7 +418,7 @@ static void flush_iotlb_all(struct omap_iommu *obj)
 
iommu_write_reg(obj, 1, MMU_GFLUSH);
 
-   clk_disable(obj-clk);
+   pm_runtime_put_sync(obj-dev);
 }
 
 #if defined(CONFIG_OMAP_IOMMU_DEBUG) || defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE)
@@ -428,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_sync(obj-dev

[PATCH v4 0/2] OMAP: iommu: hwmod, reset handling and runtime PM

2012-11-13 Thread Omar Ramirez Luna
These patches are needed for remoteproc to work on OMAP4.

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

For this series I dropped the patches already included in
mainline, along with cleanup and refactoring patches for save and
restore of mmu context, and DT bindings.

Due to single Image support, I rebased these on top of k3.7-rc5 and
DEPEND on:

[PATCH v5 0/6] Move rest of omap-iommu to live in drivers/iommu
http://thread.gmane.org/gmane.linux.kernel/1387788

Minor rebasing might be needed if these are included on top of
linux-omap, since they are affected by changes on headers being
moved to include/linux/platform_data and arch/arm/mach-omap2.

Omar Ramirez Luna (2):
  ARM: OMAP3/4: iommu: migrate to hwmod framework
  ARM: OMAP3/4: iommu: adapt to runtime pm

 arch/arm/mach-omap2/devices.c|2 +-
 arch/arm/mach-omap2/omap-iommu.c |  167 +++---
 drivers/iommu/omap-iommu.c   |   68 +++--
 drivers/iommu/omap-iommu.h   |3 -
 drivers/iommu/omap-iommu2.c  |   36 ---
 include/linux/platform_data/iommu-omap.h |9 ++-
 6 files changed, 82 insertions(+), 203 deletions(-)

-- 
1.7.4.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v3 0/6] OMAP: iommu: hwmod, reset handling and runtime PM

2012-10-19 Thread Omar Ramirez Luna
Tony,

On 18 October 2012 18:52, Tony Lindgren t...@atomide.com wrote:
 Thanks, the related patches are now posted in thread
 [PATCH v3 0/6] omap iommu changes to remove plat includes.

Ok.

 Also, can you please take a look at the Updated status of the removal
 of plat headers thread?

 I've tagged you to remove the omap plat/mailbox.h :)

Yes, got the request from Benoit too, but just now had the time to look at it.

Cheers,

Omar
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/6] ARM: OMAP3/4: iommu: adapt to runtime pm

2012-10-15 Thread Omar Ramirez Luna
Hi Felipe,

On 12 October 2012 16:25, Felipe Contreras felipe.contre...@gmail.com wrote:
 @@ -142,11 +142,10 @@ static int iommu_enable(struct omap_iommu *obj)
 }
 }

 -   clk_enable(obj-clk);
 +   pm_runtime_get_sync(obj-dev);

 err = arch_iommu-enable(obj);

 -   clk_disable(obj-clk);

 The device will never go to sleep, until iommu_disable is called.
 clk_enable - pm_runtime_get_sync, clk_disable pm_runtime_put.

 Which is what you want... why would you want your iommu to be disabled
 if the client of that iommu could request a translation?

 That's the whole point of *dynamic* pm; _when_ the client wants to
 request a translation, _then_ the device is waken up, which is what I
 believe the code currently does.

No it doesn't, current code is working because the processor and the
iommu share the same clock, so enabling the processor is implicitly
guaranteeing that the iommu will be enabled. IMHO, there shouldn't be
such assumption that you can control both with the same clock.

So, once the remote processor is enabled, any dynamic pm from iommu
with current code has no effect because the clock was already enabled
for the processor.

 After your patch, even if I don't use the camera, or the DSP, the
 iommu devices will be enabled, and will be consuming energy *all the
 time*. Which I don't think is what we want.

Wrong, the iommu device will be enabled by pm_runtime_get_sync once
you decide to attach with iommu_attach_device, if you do not use
camera or the dsp, you won't turn ON the iommus.

On probe this patch does pm_runtime_enable, however this doesn't mean
the device is turned ON or resumed or kept ON all the time.

 I'm not saying I have a solution, I'm simply saying that's what's
 going to happen if I'm correct.

Ok, but that is not what happens here.

 Remember that these iommus, sit along of other processors not on the
 main processor side. So, this code should enable it for the other
 processor to use, and there is no point where the processor can say
 I'm not using it, shut it down or I'm using it, turn it on in the
 middle of execution, other than suspend/resume and if supported,
 autosuspend.

 I understand, but perhaps there should be?

Autosuspend is a feature missing and should handle the scenario where
the remote processor can sleep dynamically, this scenario should turn
off the iommu and the remote processor itself when there is no
workload but it depends on the remote processor activity not the iommu
activity.

 @@ -1009,7 +1001,8 @@ 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);
 +   pm_runtime_disable(obj-dev);

 This will turn on the device unnecessarily, wasting power, and there's
 no need for that, kfree will take care of that without resuming.

 Left aside the aesthetics of having balanced calls, the device will be
 enabled if there was a pending resume to be executed, otherwise it
 won't, kfree won't increment the disable_depth counter and I don't
 think that freeing the pointer is enough reason to ignore
 pm_runtime_disable.

 You are doing __pm_runtime_disable(dev, true), kfree will do
 __pm_runtime_disable(dev, false), which is what we want. Both will
 decrement the disable_depth.

I'm quite confused here, could you please point me to the kfree snip
that does __pm_runtime_disable(dev, false)?

 But at least you agree that there's a chance that the device will be waken up.

Of course, if there is a pending resume to be executed, it must honor
that resume request and then turn off the device before removing the
iommu, IMHO.

 Also, I still think that something like this is needed:
 ...
 +static struct clk cam_fck = {
 +   .name   = cam_fck,
 +   .ops= clkops_omap2_iclk_dflt,
 +   .parent = l3_ick,
 +   .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),

 a cam_fck name to enable the ick?

 Yeap, according to the TRM. Take a look at 12.3 Camera ISP Integration
 Fig 12-50.

What I meant is that, you are using the CM_ICLKEN to enable a clock
named cam_fck which has l3_ick as a parent. And that is not
consistent with what that register is meant to do, which is:

4.14.1.10 CAM_CM Registers

CM_ICKLEN_CAM
0x0: CAM_L3_ICK and CAM_L4_ICLK are disabled
0x1: CAM_L3_ICK and CAM_L4_ICLK are enabled

So, I'm complaining about the name cam_fck, for an interface clock
with parent l3_ick. However I don't know why on section 12.3 they
refer to CAM_FCK to a l3_ick child clock.

Cheers,

Omar
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/6] ARM: OMAP3/4: iommu: adapt to runtime pm

2012-10-12 Thread Omar Ramirez Luna
On 12 October 2012 02:48, Felipe Contreras felipe.contre...@gmail.com wrote:
 I already made most of these comments, but here they go again.

I replied to all, but here it goes again:

 @@ -142,11 +142,10 @@ static int iommu_enable(struct omap_iommu *obj)
 }
 }

 -   clk_enable(obj-clk);
 +   pm_runtime_get_sync(obj-dev);

 err = arch_iommu-enable(obj);

 -   clk_disable(obj-clk);

 The device will never go to sleep, until iommu_disable is called.
 clk_enable - pm_runtime_get_sync, clk_disable pm_runtime_put.

Which is what you want... why would you want your iommu to be disabled
if the client of that iommu could request a translation?

Remember that these iommus, sit along of other processors not on the
main processor side. So, this code should enable it for the other
processor to use, and there is no point where the processor can say
I'm not using it, shut it down or I'm using it, turn it on in the
middle of execution, other than suspend/resume and if supported,
autosuspend.

 @@ -288,7 +285,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) {
 @@ -318,7 +315,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_sync(obj-dev);
 return PTR_ERR(cr);
 }

 If I'm correct, the above pm_runtime_get/put are redundant, because
 the count can't possibly reach 0 because of the reason I explained
 before.

 The same for all the cases below.

You can access this paths through debugfs, some of them doesn't work
if the module is not enabled first, but in future if you just want to
idle the iommu withouth freeing, these are needed to debug.

BTW, the next patch in the series: ARM: OMAP: iommu: pm runtime save
and restore context, let's you do a pm_runtime_[enable|put] through
save/restore ctx functions, which is just for compatibility on how isp
code uses the save and restore code.

 @@ -1009,7 +1001,8 @@ 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);
 +   pm_runtime_disable(obj-dev);

 This will turn on the device unnecessarily, wasting power, and there's
 no need for that, kfree will take care of that without resuming.

Left aside the aesthetics of having balanced calls, the device will be
enabled if there was a pending resume to be executed, otherwise it
won't, kfree won't increment the disable_depth counter and I don't
think that freeing the pointer is enough reason to ignore
pm_runtime_disable.

 Also, I still think that something like this is needed:
...
 +static struct clk cam_fck = {
 +   .name   = cam_fck,
 +   .ops= clkops_omap2_iclk_dflt,
 +   .parent = l3_ick,
 +   .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),

a cam_fck name to enable the ick?

Cheers,

Omar
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 0/6] OMAP: iommu: hwmod, reset handling and runtime PM

2012-10-11 Thread Omar Ramirez Luna
These patches are needed for remoteproc to work on OMAP4.

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

Although IOMMU hwmod patches were already submitted in the past,
this series adds few more changes, like:
- New reset handling.
- Save and restore context code rework.
- Device tree bindings for OMAP3 and OMAP4.

For this series I just dropped the patches already included in
mainline.

Previous work can be found at:
[v2]
  http://www.mail-archive.com/linux-omap@vger.kernel.org/msg75701.html
[v1]
  http://www.mail-archive.com/linux-omap@vger.kernel.org/msg70447.html

[old iteration without reset, save/restore and device tree]
  http://www.mail-archive.com/linux-omap@vger.kernel.org/msg60133.html

Omar Ramirez Luna (6):
  ARM: OMAP3/4: iommu: migrate to hwmod framework
  ARM: OMAP3/4: iommu: adapt to runtime pm
  ARM: OMAP: iommu: pm runtime save and restore context
  ARM: OMAP: iommu: optimize save and restore routines
  ARM: OMAP: iommu: add device tree support
  arm/dts: OMAP3/4: Add iommu nodes

 .../devicetree/bindings/arm/omap/iommu.txt |   10 ++
 arch/arm/boot/dts/omap3.dtsi   |   12 +-
 arch/arm/boot/dts/omap4.dtsi   |   17 +-
 arch/arm/mach-omap2/devices.c  |2 +-
 arch/arm/mach-omap2/iommu2.c   |   74 ++--
 arch/arm/mach-omap2/omap-iommu.c   |  176 +---
 arch/arm/plat-omap/include/plat/iommu.h|   20 ++-
 arch/arm/plat-omap/include/plat/iommu2.h   |4 -
 drivers/iommu/omap-iommu.c |  163 ++
 9 files changed, 245 insertions(+), 233 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/omap/iommu.txt

-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 1/6] ARM: OMAP3/4: iommu: migrate to hwmod framework

2012-10-11 Thread 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, use default
   latency structure.
 - Use hwmod API for reset handling.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 arch/arm/mach-omap2/devices.c   |2 +-
 arch/arm/mach-omap2/iommu2.c|   19 
 arch/arm/mach-omap2/omap-iommu.c|  165 +++
 arch/arm/plat-omap/include/plat/iommu.h |8 +-
 drivers/iommu/omap-iommu.c  |   23 -
 5 files changed, 64 insertions(+), 153 deletions(-)

diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index c8c2117..e084b94 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -213,7 +213,7 @@ static struct platform_device omap3isp_device = {
 };
 
 static struct omap_iommu_arch_data omap3_isp_iommu = {
-   .name = isp,
+   .name = mmu_isp,
 };
 
 int omap3_init_camera(struct isp_platform_data *pdata)
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index eefc379..35cab47 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -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);
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index df298d4..e400845 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -12,153 +12,64 @@
 
 #include linux/module.h
 #include linux/platform_device.h
+#include linux/err.h
+#include linux/slab.h
 
 #include plat/iommu.h
+#include plat/omap_hwmod.h
+#include plat/omap_device.h
 
 #include soc.h
 #include common.h
 
-struct iommu_device {
-   resource_size_t base;
-   int irq;
-   struct iommu_platform_data pdata;
-   struct resource res[2];
-};
-static struct iommu_device *devices;
-static int num_iommu_devices;
-
-#ifdef CONFIG_ARCH_OMAP3
-static struct iommu_device omap3_devices[] = {
-   {
-   .base = 0x480bd400,
-   .irq = 24 + OMAP_INTC_START,
-   .pdata = {
-   .name = isp,
-   .nr_tlb_entries = 8,
-   .clk_name = cam_ick,
-   .da_start = 0x0,
-   .da_end = 0xF000,
-   },
-   },
-#if defined(CONFIG_OMAP_IOMMU_IVA2)
-   {
-   .base = 0x5d00,
-   .irq = 28 + OMAP_INTC_START,
-   .pdata = {
-   .name = iva2,
-   .nr_tlb_entries = 32,
-   .clk_name = iva2_ck,
-   .da_start = 0x1100,
-   .da_end = 0xF000,
-   },
-   },
-#endif
-};
-#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices)
-static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES];
-#else
-#define omap3_devices  NULL
-#define NR_OMAP3_IOMMU_DEVICES 0
-#define omap3_iommu_pdev   NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-static struct iommu_device omap4_devices[] = {
-   {
-   .base = OMAP4_MMU1_BASE,
-   .irq = 100 + OMAP44XX_IRQ_GIC_START,
-   .pdata = {
-   .name = ducati,
-   .nr_tlb_entries = 32,
-   .clk_name = ipu_fck,
-   .da_start = 0x0

[PATCH 1/6] ARM: OMAP3/4: iommu: migrate to hwmod framework

2012-10-11 Thread 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, use default
   latency structure.
 - Use hwmod API for reset handling.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 arch/arm/mach-omap2/devices.c   |2 +-
 arch/arm/mach-omap2/iommu2.c|   19 
 arch/arm/mach-omap2/omap-iommu.c|  165 +++
 arch/arm/plat-omap/include/plat/iommu.h |8 +-
 drivers/iommu/omap-iommu.c  |   23 -
 5 files changed, 64 insertions(+), 153 deletions(-)

diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index c8c2117..e084b94 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -213,7 +213,7 @@ static struct platform_device omap3isp_device = {
 };
 
 static struct omap_iommu_arch_data omap3_isp_iommu = {
-   .name = isp,
+   .name = mmu_isp,
 };
 
 int omap3_init_camera(struct isp_platform_data *pdata)
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index eefc379..35cab47 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -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);
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index df298d4..e400845 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -12,153 +12,64 @@
 
 #include linux/module.h
 #include linux/platform_device.h
+#include linux/err.h
+#include linux/slab.h
 
 #include plat/iommu.h
+#include plat/omap_hwmod.h
+#include plat/omap_device.h
 
 #include soc.h
 #include common.h
 
-struct iommu_device {
-   resource_size_t base;
-   int irq;
-   struct iommu_platform_data pdata;
-   struct resource res[2];
-};
-static struct iommu_device *devices;
-static int num_iommu_devices;
-
-#ifdef CONFIG_ARCH_OMAP3
-static struct iommu_device omap3_devices[] = {
-   {
-   .base = 0x480bd400,
-   .irq = 24 + OMAP_INTC_START,
-   .pdata = {
-   .name = isp,
-   .nr_tlb_entries = 8,
-   .clk_name = cam_ick,
-   .da_start = 0x0,
-   .da_end = 0xF000,
-   },
-   },
-#if defined(CONFIG_OMAP_IOMMU_IVA2)
-   {
-   .base = 0x5d00,
-   .irq = 28 + OMAP_INTC_START,
-   .pdata = {
-   .name = iva2,
-   .nr_tlb_entries = 32,
-   .clk_name = iva2_ck,
-   .da_start = 0x1100,
-   .da_end = 0xF000,
-   },
-   },
-#endif
-};
-#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices)
-static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES];
-#else
-#define omap3_devices  NULL
-#define NR_OMAP3_IOMMU_DEVICES 0
-#define omap3_iommu_pdev   NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-static struct iommu_device omap4_devices[] = {
-   {
-   .base = OMAP4_MMU1_BASE,
-   .irq = 100 + OMAP44XX_IRQ_GIC_START,
-   .pdata = {
-   .name = ducati,
-   .nr_tlb_entries = 32,
-   .clk_name = ipu_fck,
-   .da_start = 0x0

[PATCH 2/6] ARM: OMAP3/4: iommu: adapt to runtime pm

2012-10-11 Thread Omar Ramirez Luna
Use runtime PM functionality interfaced with hwmod enable/idle
functions, to replace direct clock operations and sysconfig
handling.

Dues to reset sequence, pm_runtime_put_sync must be used, to avoid
possible operations with the module under reset.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 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   |   45 +-
 5 files changed, 19 insertions(+), 48 deletions(-)

diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index 35cab47..3e47786 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -25,15 +25,6 @@
  */
 #define IOMMU_ARCH_VERSION 0x0011
 
-/* 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);
 }
@@ -243,8 +228,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);
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index e400845..82a422a 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -34,7 +34,6 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, 
void *unused)
return -ENOMEM;
 
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;
diff --git a/arch/arm/plat-omap/include/plat/iommu.h 
b/arch/arm/plat-omap/include/plat/iommu.h
index 0fa913d..902d193 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -30,7 +30,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;
@@ -120,7 +119,6 @@ struct omap_mmu_dev_attr {
 
 struct iommu_platform_data {
const char *name;
-   const char *clk_name;
const char *reset_name;
int nr_tlb_entries;
u32 da_start;
diff --git a/arch/arm/plat-omap/include/plat/iommu2.h 
b/arch/arm/plat-omap/include/plat/iommu2.h
index d4116b5..1579694 100644
--- a/arch/arm/plat-omap/include/plat/iommu2.h
+++ b/arch/arm/plat-omap/include/plat/iommu2.h
@@ -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
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index c1caee4..37644c4 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -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
 
@@ -142,11 +142,10 @@ static int iommu_enable(struct omap_iommu *obj)
}
}
 
-   clk_enable(obj-clk);
+   pm_runtime_get_sync(obj-dev);
 
err = arch_iommu-enable(obj);
 
-   clk_disable(obj-clk);
return err;
 }
 
@@ -158,11 +157,9 @@ static void iommu_disable(struct omap_iommu *obj)
if (!obj || !pdata)
return;
 
-   clk_enable(obj-clk);
-
arch_iommu-disable(obj);
 
-   clk_disable(obj-clk);
+   pm_runtime_put_sync(obj-dev);
 
if (pdata-assert_reset

[PATCH v3 3/6] ARM: OMAP: iommu: pm runtime save and restore context

2012-10-11 Thread Omar Ramirez Luna
Save and restore context during pm runtime transitions.

For now, the previous API for this purpose will trigger
pm runtime functions, and will be left as exported symbol
for compatibility with it's only user.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 drivers/iommu/omap-iommu.c |   29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 37644c4..875e894 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -97,7 +97,7 @@ void omap_iommu_save_ctx(struct device *dev)
 {
struct omap_iommu *obj = dev_to_omap_iommu(dev);
 
-   arch_iommu-save_ctx(obj);
+   pm_runtime_put_sync(obj-dev);
 }
 EXPORT_SYMBOL_GPL(omap_iommu_save_ctx);
 
@@ -109,7 +109,7 @@ void omap_iommu_restore_ctx(struct device *dev)
 {
struct omap_iommu *obj = dev_to_omap_iommu(dev);
 
-   arch_iommu-restore_ctx(obj);
+   pm_runtime_get_sync(obj-dev);
 }
 EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx);
 
@@ -1008,11 +1008,36 @@ static int __devexit omap_iommu_remove(struct 
platform_device *pdev)
return 0;
 }
 
+static int omap_iommu_runtime_suspend(struct device *dev)
+{
+   struct omap_iommu *obj = to_iommu(dev);
+
+   arch_iommu-save_ctx(obj);
+
+   return 0;
+}
+
+static int omap_iommu_runtime_resume(struct device *dev)
+{
+   struct omap_iommu *obj = to_iommu(dev);
+
+   arch_iommu-restore_ctx(obj);
+
+   return 0;
+}
+
+static const struct dev_pm_ops iommu_pm_ops = {
+   SET_RUNTIME_PM_OPS(omap_iommu_runtime_suspend,
+  omap_iommu_runtime_resume,
+  NULL)
+};
+
 static struct platform_driver omap_iommu_driver = {
.probe  = omap_iommu_probe,
.remove = __devexit_p(omap_iommu_remove),
.driver = {
.name   = omap-iommu,
+   .pm = iommu_pm_ops,
},
 };
 
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 3/6] ARM: OMAP: iommu: pm runtime save and restore context

2012-10-11 Thread Omar Ramirez Luna
Save and restore context during pm runtime transitions.

For now, the previous API for this purpose will trigger
pm runtime functions, and will be left as exported symbol
for compatibility with it's only user.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 drivers/iommu/omap-iommu.c |   29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 37644c4..875e894 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -97,7 +97,7 @@ void omap_iommu_save_ctx(struct device *dev)
 {
struct omap_iommu *obj = dev_to_omap_iommu(dev);
 
-   arch_iommu-save_ctx(obj);
+   pm_runtime_put_sync(obj-dev);
 }
 EXPORT_SYMBOL_GPL(omap_iommu_save_ctx);
 
@@ -109,7 +109,7 @@ void omap_iommu_restore_ctx(struct device *dev)
 {
struct omap_iommu *obj = dev_to_omap_iommu(dev);
 
-   arch_iommu-restore_ctx(obj);
+   pm_runtime_get_sync(obj-dev);
 }
 EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx);
 
@@ -1008,11 +1008,36 @@ static int __devexit omap_iommu_remove(struct 
platform_device *pdev)
return 0;
 }
 
+static int omap_iommu_runtime_suspend(struct device *dev)
+{
+   struct omap_iommu *obj = to_iommu(dev);
+
+   arch_iommu-save_ctx(obj);
+
+   return 0;
+}
+
+static int omap_iommu_runtime_resume(struct device *dev)
+{
+   struct omap_iommu *obj = to_iommu(dev);
+
+   arch_iommu-restore_ctx(obj);
+
+   return 0;
+}
+
+static const struct dev_pm_ops iommu_pm_ops = {
+   SET_RUNTIME_PM_OPS(omap_iommu_runtime_suspend,
+  omap_iommu_runtime_resume,
+  NULL)
+};
+
 static struct platform_driver omap_iommu_driver = {
.probe  = omap_iommu_probe,
.remove = __devexit_p(omap_iommu_remove),
.driver = {
.name   = omap-iommu,
+   .pm = iommu_pm_ops,
},
 };
 
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 4/6] ARM: OMAP: iommu: optimize save and restore routines

2012-10-11 Thread Omar Ramirez Luna
These functions save and restore registers irrespectively of their
read or write permissions, this ends up in registers being saved
that can't be restored because of read only attributes. OTOH, so
far only 3 of them need to be saved.

In future GP_REG (which is present only on OMAP4 ipu) needs to be
saved but right now there is no API that can alter its value. Also,
protected TLB entries must be saved but this can be in a separate
patch as the original code didn't implement the loop to traverse
protected TLB entries.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 arch/arm/mach-omap2/iommu2.c |   38 ++
 arch/arm/plat-omap/include/plat/iommu.h  |   10 +++-
 arch/arm/plat-omap/include/plat/iommu2.h |2 --
 drivers/iommu/omap-iommu.c   |3 +--
 4 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index 3e47786..cd77abb 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -19,6 +19,7 @@
 #include linux/stringify.h
 
 #include plat/iommu.h
+#include plat/omap-pm.h
 
 /*
  * omap2 architecture specific register bit definitions
@@ -55,20 +56,26 @@
 
 static void __iommu_set_twl(struct omap_iommu *obj, bool on)
 {
-   u32 l = iommu_read_reg(obj, MMU_CNTL);
+   u32 l;
 
if (on)
-   iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE);
+   l = MMU_IRQ_TWL_MASK;
else
-   iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE);
+   l = MMU_IRQ_TLB_MISS_MASK;
+
+   iommu_write_reg(obj, l, MMU_IRQENABLE);
+   obj-context.irqen = l;
 
+   l = iommu_read_reg(obj, MMU_CNTL);
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);
+   obj-context.cntl = l;
 }
 
 
@@ -88,6 +95,7 @@ static int omap2_iommu_enable(struct omap_iommu *obj)
 (l  4)  0xf, l  0xf);
 
iommu_write_reg(obj, pa, MMU_TTB);
+   obj-context.ttb = pa;
 
__iommu_set_twl(obj, true);
 
@@ -100,6 +108,7 @@ static void omap2_iommu_disable(struct omap_iommu *obj)
 
l = ~MMU_CNTL_MASK;
iommu_write_reg(obj, l, MMU_CNTL);
+   obj-context.cntl = l;
 
dev_dbg(obj-dev, %s is shutting down\n, obj-name);
 }
@@ -249,28 +258,17 @@ out:
 
 static void omap2_iommu_save_ctx(struct omap_iommu *obj)
 {
-   int i;
-   u32 *p = obj-ctx;
-
-   for (i = 0; i  (MMU_REG_SIZE / sizeof(u32)); i++) {
-   p[i] = iommu_read_reg(obj, i * sizeof(u32));
-   dev_dbg(obj-dev, %s\t[%02d] %08x\n, __func__, i, p[i]);
-   }
-
-   BUG_ON(p[0] != IOMMU_ARCH_VERSION);
+   obj-ctx_loss_cnt = omap_pm_get_dev_context_loss_count(obj-dev);
 }
 
 static void omap2_iommu_restore_ctx(struct omap_iommu *obj)
 {
-   int i;
-   u32 *p = obj-ctx;
-
-   for (i = 0; i  (MMU_REG_SIZE / sizeof(u32)); i++) {
-   iommu_write_reg(obj, p[i], i * sizeof(u32));
-   dev_dbg(obj-dev, %s\t[%02d] %08x\n, __func__, i, p[i]);
-   }
+   if (omap_pm_get_dev_context_loss_count(obj-dev) == obj-ctx_loss_cnt)
+   return;
 
-   BUG_ON(p[0] != IOMMU_ARCH_VERSION);
+   iommu_write_reg(obj, obj-context.ttb, MMU_TTB);
+   iommu_write_reg(obj, obj-context.irqen, MMU_IRQENABLE);
+   iommu_write_reg(obj, obj-context.cntl, MMU_CNTL);
 }
 
 static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
diff --git a/arch/arm/plat-omap/include/plat/iommu.h 
b/arch/arm/plat-omap/include/plat/iommu.h
index 902d193..af14486 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -27,6 +27,13 @@ struct iotlb_entry {
};
 };
 
+/* context registers */
+struct iommu_regs {
+   u32 irqen;
+   u32 cntl;
+   u32 ttb;
+};
+
 struct omap_iommu {
const char  *name;
struct module   *owner;
@@ -50,7 +57,8 @@ struct omap_iommu {
struct list_headmmap;
struct mutexmmap_lock; /* protect mmap */
 
-   void *ctx; /* iommu context: registres saved area */
+   struct iommu_regs context;
+   int ctx_loss_cnt;
u32 da_start;
u32 da_end;
 };
diff --git a/arch/arm/plat-omap/include/plat/iommu2.h 
b/arch/arm/plat-omap/include/plat/iommu2.h
index 1579694..bc43d41 100644
--- a/arch/arm/plat-omap/include/plat/iommu2.h
+++ b/arch/arm/plat-omap/include/plat/iommu2.h
@@ -35,8 +35,6 @@
 #define MMU_READ_RAM   0x6c
 #define MMU_EMU_FAULT_AD   0x70
 
-#define MMU_REG_SIZE   256
-
 /*
  * MMU Register bit definitions
  */
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 875e894..e266ad7 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -924,14 +924,13 @@ static int __devinit

Re: [PATCH 0/6] OMAP: iommu: hwmod, reset handling and runtime PM

2012-07-18 Thread Omar Ramirez Luna
On 17 July 2012 05:51, Ohad Ben-Cohen o...@wizery.com wrote:
 + Paul

 On Tue, Jul 17, 2012 at 1:11 PM, Joerg Roedel joerg.roe...@amd.com wrote:
 On Fri, Jun 15, 2012 at 08:55:58PM -0500, Omar Ramirez Luna wrote:
 Omar Ramirez Luna (6):
   ARM: OMAP: iommu: fix including iommu.h without IOMMU_API selected
   ARM: OMAP3: hwmod data: add mmu data for iva and isp
   ARM: OMAP4: hwmod data: add mmu hwmod for ipu and dsp
   ARM: OMAP3/4: iommu: migrate to hwmod framework
   ARM: OMAP2+: iommu: add reset handling
   ARM: OMAP3/4: iommu: adapt to runtime pm

 What happens with this patch-set. Comments anyone? Ohad?

 Looks like it depends on a few OMAP hwmod changes (reset handling)
 which require Paul's ACK.

That's correct, sorry if I failed to mention that in the cover-letter,
but it does depend on:

http://lkml.indiana.edu/hypermail/linux/kernel/1207.2/00361.html

For the hwmod reset handling. Mainly, I wanted to gather comments for
this patch set.

- omar
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 3/6] ARM: OMAP4: hwmod data: add mmu hwmod for ipu and dsp

2012-06-27 Thread Omar Ramirez Luna
+ Paul

On 19 June 2012 12:48, Cousson, Benoit b-cous...@ti.com wrote:
 On 6/19/2012 6:39 PM, Omar Ramirez Luna wrote:

 Hi Benoit,

 On 19 June 2012 07:36, Cousson, Benoit b-cous...@ti.com wrote:

 On 6/16/2012 3:56 AM, Omar Ramirez Luna wrote:

 ...

 +static struct omap_hwmod omap44xx_ipu_mmu_hwmod = {
 +     .name           = ipu_mmu,
 +     .class          = omap44xx_mmu_hwmod_class,
 +     .clkdm_name     = ducati_clkdm,
 +     .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 = {
 +                     .clkctrl_offs =
 OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
 +                     .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
 +                     .context_offs =
 OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
 +                     .modulemode   = MODULEMODE_HWCTRL,
 +             },
 +     },
 +     .dev_attr       = ipu_mmu_dev_attr,
 +};


 In fact, the MMU_IPU hwmod is now almost the same one than the previous
 IPU one...
 If we do that we should maybe just rename the IPU - MMU_IPU and DSP -
 MMU_DSP.

 But by doing that we will assume that the MMU does represent the
 subsystem, which is not necessarily super nice.

 I guess that a much better representation will be to keep the subsystem
 (IPU) to handle the PRCM part:

 +       .main_clk       = ipu_fck,
 +       .prcm = {
 +               .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
 +               .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
 +               .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
 +               .modulemode   = MODULEMODE_HWCTRL,

 And then the MMU_IPU will handle the configuration registers part and the
 reset + irq.

 But then, you will have to create a parent child dependency between your
 devices to ensure that the IPU subsystem device will be enabled before
 trying to access the MMU_IPU.

 This is what the DSS is about to do to handle the same kind of power
 dependency. The DSS device is the parent of all the DSS IPs (DISPC, HDMI...)
 and thus pm_runtime will ensure that the parent is enabled before trying to
 enable the children.

 In term of DT, just to illustrate the situation, it will be something
 like that:

 ipu {
        compatible = simple-bus;
        ti,hwmods = ipu;

        ipu_mmu: mmu@4a066000 {
                compatible = omap-mmu;
                ti,hwmods = mmu_ipu;
                reg...;
                irqs...;
        }
 }

 Is it something you can handle with your current framework?


 I agree it would be nice only IPU managed the prcm, however we can't
 do that right now because hwmod expects the IP block to be out of
 reset to continue the _enable sequence. On IPU both reset lines are
 asserted at that point and hence _are_any_hardreset_lines_asserted
 check will bail out, and ipu resets can't be lifted without a
 configured iommu otherwise it might execute random garbage.


 That's a good point, but like Paul said, the hard reset was removed outside
 of the fmwk due to the lack of understanding about the real usage / need for
 it.

 If we do have a better understanding, we might add some more support in the
 fmwk or at least improve it.

 I'm now realizing that aborting the init if some reset lines are asserted is
 not what we want to do for the IPU SS hwmod that will contain the IPU
 (processor) reset control.
 In fact the previous approach with a fake hwmod for the ipu_c0 processor
 would have been avoided that issue.

 If we do not want to go back with that, we should clearly revise the
 _are_any_hardreset_lines_asserted approach and not prevent the init in such
 case since it will prevent all the subsystem to start properly.


 So, for IPU and DSP the mmu must be deasserted and configured before
 the processor reset line (which is more like a parking brake) is
 deasserted, and the latter should be made before _enable is called so
 it can fully execute the enable sequence.


 Yep, so we have to change the way it is handled today.


 Paul,

 If we consider that the reset lines are stored in the subsystem hwmod (IPU,
 DSP or IVA), we cannot prevent the init phase because some line are
 asserted. Otherwise we will never allow the MMU or processor to be enabled
 later.
 We might have to remove that check, maybe based on flag if we want to keep
 that functionality or do an explicit reset control like we use to do.

 What do you think?

I was waiting for some comments then I realized Paul wasn't actually
in the list of recipients for this email.

Regards,

Omar
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 0/6] OMAP: iommu: hwmod, reset handling and runtime PM

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

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.

Although IOMMU hwmod patches were already submitted in the past,
this series adds few more changes, like:
- New reset handling, based on a series that needs to be accepted first.
- Fix for compile break if IOMMU_API is not selected.

Previous work can be found at:

http://www.mail-archive.com/linux-omap@vger.kernel.org/msg60133.html

Omar Ramirez Luna (6):
  ARM: OMAP: iommu: fix including iommu.h without IOMMU_API selected
  ARM: OMAP3: hwmod data: add mmu data for iva and isp
  ARM: OMAP4: hwmod data: add mmu hwmod for ipu and dsp
  ARM: OMAP3/4: iommu: migrate to hwmod framework
  ARM: OMAP2+: iommu: add reset handling
  ARM: OMAP3/4: iommu: adapt to runtime pm

 arch/arm/mach-omap2/devices.c  |2 +-
 arch/arm/mach-omap2/iommu2.c   |   36 --
 arch/arm/mach-omap2/omap-iommu.c   |  166 ++-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  115 +++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  136 ++-
 arch/arm/plat-omap/include/plat/iommu.h|   25 -
 arch/arm/plat-omap/include/plat/iommu2.h   |2 -
 drivers/iommu/omap-iommu.c |   68 ++-
 8 files changed, 346 insertions(+), 204 deletions(-)

-- 
1.7.4.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/6] ARM: OMAP: iommu: fix including iommu.h without IOMMU_API selected

2012-06-15 Thread Omar Ramirez Luna
If included without IOMMU_API being selected it will break
compilation:

arch/arm/plat-omap/include/plat/iommu.h:
In function 'dev_to_omap_iommu':
arch/arm/plat-omap/include/plat/iommu.h:148:
error: 'struct dev_archdata' has no member named 'iommu'

This will be seen, when hwmod includes iommu.h to get the
structure for attributes.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 arch/arm/plat-omap/include/plat/iommu.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/iommu.h 
b/arch/arm/plat-omap/include/plat/iommu.h
index 88be3e6..e58d571 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -126,6 +126,7 @@ struct omap_iommu_arch_data {
struct omap_iommu *iommu_dev;
 };
 
+#ifdef CONFIG_IOMMU_API
 /**
  * dev_to_omap_iommu() - retrieves an omap iommu object from a user device
  * @dev: iommu client device
@@ -136,6 +137,7 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct 
device *dev)
 
return arch_data-iommu_dev;
 }
+#endif
 
 /* IOMMU errors */
 #define OMAP_IOMMU_ERR_TLB_MISS(1  0)
-- 
1.7.4.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/6] ARM: OMAP3: hwmod data: add mmu data for iva and isp

2012-06-15 Thread Omar Ramirez Luna
Add mmu hwmod data for iva and isp.

Due to compatibility an ifdef CONFIG_OMAP_IOMMU_IVA2 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 migrated
to iommu framework.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  117 
 arch/arm/plat-omap/include/plat/iommu.h|   13 +++
 2 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 0ea53bc..89df566 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -27,6 +27,7 @@
 #include plat/mcbsp.h
 #include plat/mcspi.h
 #include plat/dmtimer.h
+#include plat/iommu.h
 
 #include omap_hwmod_common_data.h
 
@@ -2777,6 +2778,118 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio3 
= {
.user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/*
+ * '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 = 0xf000,
+   .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,
+};
+
+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,
+   .flags  = HWMOD_NO_IDLEST,
+};
+
+/* iva mmu */
+
+static struct omap_mmu_dev_attr iva_mmu_dev_attr = {
+   .da_start = 0x1100,
+   .da_end = 0xf000,
+   .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   = 0x5d00,
+   .pa_end = 0x5d7f,
+   .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,
+};
+
+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,
+   .flags  = HWMOD_NO_IDLEST,
+};
+
 /* l4_per - gpio4 */
 static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = {
{
@@ -3174,6 +3287,10 @@ static struct omap_hwmod_ocp_if 
*omap3xxx_hwmod_ocp_ifs[] __initdata = {
omap34xx_l4_core__mcspi2,
omap34xx_l4_core__mcspi3,
omap34xx_l4_core__mcspi4,
+   omap3xxx_l4_core__isp_mmu,
+#ifdef CONFIG_OMAP_IOMMU_IVA2
+   omap3xxx_l3_main__iva_mmu,
+#endif
omap3xxx_l4_wkup__counter_32k,
NULL,
 };
diff --git a/arch

[PATCH 3/6] ARM: OMAP4: hwmod data: add mmu hwmod for ipu and dsp

2012-06-15 Thread Omar Ramirez Luna
Add mmu hwmod data for ipu and dsp.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  136 +++-
 1 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index ebf9657..3879e9c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -30,6 +30,7 @@
 #include plat/mmc.h
 #include plat/dmtimer.h
 #include plat/common.h
+#include plat/iommu.h
 
 #include omap_hwmod_common_data.h
 
@@ -614,7 +615,6 @@ static struct omap_hwmod_irq_info omap44xx_dsp_irqs[] = {
 
 static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = {
{ .name = dsp, .rst_shift = 0 },
-   { .name = mmu_cache, .rst_shift = 1 },
 };
 
 static struct omap_hwmod omap44xx_dsp_hwmod = {
@@ -1629,7 +1629,6 @@ static struct omap_hwmod_irq_info omap44xx_ipu_irqs[] = {
 static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = {
{ .name = cpu0, .rst_shift = 0 },
{ .name = cpu1, .rst_shift = 1 },
-   { .name = mmu_cache, .rst_shift = 2 },
 };
 
 static struct omap_hwmod omap44xx_ipu_hwmod = {
@@ -2436,6 +2435,137 @@ static struct omap_hwmod omap44xx_mmc5_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 = 0xf000,
+   .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_2 - ipu_mmu */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ipu_mmu = {
+   .master = omap44xx_l3_main_2_hwmod,
+   .slave  = omap44xx_ipu_mmu_hwmod,
+   .clk= l3_div_ck,
+   .addr   = omap44xx_ipu_mmu_addrs,
+   .user   = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap44xx_ipu_mmu_hwmod = {
+   .name   = ipu_mmu,
+   .class  = omap44xx_mmu_hwmod_class,
+   .clkdm_name = ducati_clkdm,
+   .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 = {
+   .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
+   .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
+   .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
+   .modulemode   = MODULEMODE_HWCTRL,
+   },
+   },
+   .dev_attr   = ipu_mmu_dev_attr,
+};
+
+/* dsp mmu */
+
+static struct omap_mmu_dev_attr dsp_mmu_dev_attr = {
+   .da_start = 0x0,
+   .da_end = 0xf000,
+   .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,
+   },
+   { }
+};
+
+/* l4_cfg - dsp */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dsp_mmu = {
+   .master = omap44xx_l4_cfg_hwmod,
+   .slave  = omap44xx_dsp_mmu_hwmod,
+   .clk= l4_div_ck,
+   .addr   = omap44xx_dsp_mmu_addrs,
+   .user   = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap44xx_dsp_mmu_hwmod = {
+   .name   = dsp_mmu,
+   .class  = omap44xx_mmu_hwmod_class

[PATCH 5/6] ARM: OMAP2+: iommu: add reset handling

2012-06-15 Thread Omar Ramirez Luna
Recent changes in hwmod now require for drivers to handle reset
lines. Otherwise iommu initialization will fail.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 arch/arm/mach-omap2/omap-iommu.c|6 ++
 arch/arm/plat-omap/include/plat/iommu.h |6 ++
 drivers/iommu/omap-iommu.c  |   20 ++--
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index 02d98ce..96eecd8 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -37,6 +37,12 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, 
void *unused)
pdata-da_start = a-da_start;
pdata-da_end = a-da_end;
 
+   if (oh-rst_lines_cnt == 1) {
+   pdata-reset_name = oh-rst_lines-name;
+   pdata-assert_reset = omap_device_assert_hardreset;
+   pdata-deassert_reset = omap_device_deassert_hardreset;
+   }
+
pdev = omap_device_build(omap-iommu, i, oh, pdata, sizeof(*pdata),
NULL, 0, 0);
 
diff --git a/arch/arm/plat-omap/include/plat/iommu.h 
b/arch/arm/plat-omap/include/plat/iommu.h
index ed56424..bb15b85 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -13,6 +13,8 @@
 #ifndef __MACH_IOMMU_H
 #define __MACH_IOMMU_H
 
+#include linux/platform_device.h
+
 struct iotlb_entry {
u32 da;
u32 pa;
@@ -119,9 +121,13 @@ struct omap_mmu_dev_attr {
 struct iommu_platform_data {
const char *name;
const char *clk_name;
+   const char *reset_name;
int nr_tlb_entries;
u32 da_start;
u32 da_end;
+
+   int (*assert_reset)(struct platform_device *pdev, const char *name);
+   int (*deassert_reset)(struct platform_device *pdev, const char *name);
 };
 
 /**
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 93d7d84..f0d6865 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -125,13 +125,23 @@ EXPORT_SYMBOL_GPL(omap_iommu_arch_version);
 static int iommu_enable(struct omap_iommu *obj)
 {
int err;
+   struct platform_device *pdev = to_platform_device(obj-dev);
+   struct iommu_platform_data *pdata = pdev-dev.platform_data;
 
-   if (!obj)
+   if (!obj || !pdata)
return -EINVAL;
 
if (!arch_iommu)
return -ENODEV;
 
+   if (pdata-deassert_reset) {
+   err = pdata-deassert_reset(pdev, pdata-reset_name);
+   if (err) {
+   dev_err(obj-dev, deassert_reset failed: %d\n, err);
+   return err;
+   }
+   }
+
clk_enable(obj-clk);
 
err = arch_iommu-enable(obj);
@@ -142,7 +152,10 @@ static int iommu_enable(struct omap_iommu *obj)
 
 static void iommu_disable(struct omap_iommu *obj)
 {
-   if (!obj)
+   struct platform_device *pdev = to_platform_device(obj-dev);
+   struct iommu_platform_data *pdata = pdev-dev.platform_data;
+
+   if (!obj || !pdata)
return;
 
clk_enable(obj-clk);
@@ -150,6 +163,9 @@ static void iommu_disable(struct omap_iommu *obj)
arch_iommu-disable(obj);
 
clk_disable(obj-clk);
+
+   if (pdata-assert_reset)
+   pdata-assert_reset(pdev, pdata-reset_name);
 }
 
 /*
-- 
1.7.4.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 6/6] ARM: OMAP3/4: iommu: adapt to runtime pm

2012-06-15 Thread Omar Ramirez Luna
Use runtime PM functionality interfaced with hwmod enable/idle
functions, to replace direct clock operations and sysconfig
handling.

Due to reset sequence, pm_runtime_put_sync must be used, to avoid
possible operations with the module under reset.

Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 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   |   45 -
 5 files changed, 19 insertions(+), 48 deletions(-)

diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index 35cab47..3e47786 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -25,15 +25,6 @@
  */
 #define IOMMU_ARCH_VERSION 0x0011
 
-/* 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);
 }
@@ -243,8 +228,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);
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index 96eecd8..e8f88dc 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -32,7 +32,6 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, 
void *unused)
return -ENOMEM;
 
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;
diff --git a/arch/arm/plat-omap/include/plat/iommu.h 
b/arch/arm/plat-omap/include/plat/iommu.h
index bb15b85..004cb9e 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -30,7 +30,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;
@@ -120,7 +119,6 @@ struct omap_mmu_dev_attr {
 
 struct iommu_platform_data {
const char *name;
-   const char *clk_name;
const char *reset_name;
int nr_tlb_entries;
u32 da_start;
diff --git a/arch/arm/plat-omap/include/plat/iommu2.h 
b/arch/arm/plat-omap/include/plat/iommu2.h
index d4116b5..1579694 100644
--- a/arch/arm/plat-omap/include/plat/iommu2.h
+++ b/arch/arm/plat-omap/include/plat/iommu2.h
@@ -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
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index f0d6865..5daf4fd 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -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
 
@@ -142,11 +142,10 @@ static int iommu_enable(struct omap_iommu *obj)
}
}
 
-   clk_enable(obj-clk);
+   pm_runtime_get_sync(obj-dev);
 
err = arch_iommu-enable(obj);
 
-   clk_disable(obj-clk);
return err;
 }
 
@@ -158,11 +157,9 @@ static void iommu_disable(struct omap_iommu *obj)
if (!obj || !pdata)
return;
 
-   clk_enable(obj-clk);
-
arch_iommu-disable(obj);
 
-   clk_disable(obj-clk);
+   pm_runtime_put_sync(obj-dev);
 
if (pdata-assert_reset

[PATCH] iommu: OMAP: device detach on domain destroy

2012-03-30 Thread Omar Ramirez Luna
'domain_destroy with devices attached' case isn't yet handled, instead
code assumes that the device was already detached.

If the domain is destroyed the hardware still has access to invalid
pointers to its page table and internal iommu object. In order to
detach the users we need to track devices using the iommu, current
use cases only have one user of iommu per instance. When required
this can evolve to a list with the devices using the iommu_dev.

Reported-by: Joerg Roedel j...@8bytes.org
Reviewed-by: Ohad Ben-Cohen o...@wizery.com
Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 drivers/iommu/omap-iommu.c |   32 +++-
 1 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 821062a..e32bd15 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -41,11 +41,13 @@
  * @pgtable:   the page table
  * @iommu_dev: an omap iommu device attached to this domain. only a single
  * iommu device can be attached for now.
+ * @dev:   Device using this domain.
  * @lock:  domain lock, should be taken when attaching/detaching
  */
 struct omap_iommu_domain {
u32 *pgtable;
struct omap_iommu *iommu_dev;
+   struct device *dev;
spinlock_t lock;
 };
 
@@ -1074,6 +1076,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct 
device *dev)
}
 
omap_domain-iommu_dev = arch_data-iommu_dev = oiommu;
+   omap_domain-dev = dev;
oiommu-domain = domain;
 
/* temporary workaround */
@@ -1084,19 +1087,16 @@ out:
return ret;
 }
 
-static void omap_iommu_detach_dev(struct iommu_domain *domain,
-struct device *dev)
+static void _omap_iommu_detach_dev(struct omap_iommu_domain *omap_domain,
+   struct device *dev)
 {
-   struct omap_iommu_domain *omap_domain = domain-priv;
-   struct omap_iommu_arch_data *arch_data = dev-archdata.iommu;
struct omap_iommu *oiommu = dev_to_omap_iommu(dev);
-
-   spin_lock(omap_domain-lock);
+   struct omap_iommu_arch_data *arch_data = dev-archdata.iommu;
 
/* only a single device is supported per domain for now */
if (omap_domain-iommu_dev != oiommu) {
dev_err(dev, invalid iommu device\n);
-   goto out;
+   return;
}
 
iopgtable_clear_entry_all(oiommu);
@@ -1104,11 +1104,19 @@ static void omap_iommu_detach_dev(struct iommu_domain 
*domain,
omap_iommu_detach(oiommu);
 
omap_domain-iommu_dev = arch_data-iommu_dev = NULL;
+   omap_domain-dev = NULL;
 
/* temporary workaround */
clk_disable(oiommu-clk);
+}
 
-out:
+static void omap_iommu_detach_dev(struct iommu_domain *domain,
+struct device *dev)
+{
+   struct omap_iommu_domain *omap_domain = domain-priv;
+
+   spin_lock(omap_domain-lock);
+   _omap_iommu_detach_dev(omap_domain, dev);
spin_unlock(omap_domain-lock);
 }
 
@@ -1147,13 +1155,19 @@ out:
return -ENOMEM;
 }
 
-/* assume device was already detached */
 static void omap_iommu_domain_destroy(struct iommu_domain *domain)
 {
struct omap_iommu_domain *omap_domain = domain-priv;
 
domain-priv = NULL;
 
+   /*
+* An iommu device is still attached
+* (currently, only one device can be attached) ?
+*/
+   if (omap_domain-iommu_dev)
+   _omap_iommu_detach_dev(omap_domain, omap_domain-dev);
+
kfree(omap_domain-pgtable);
kfree(omap_domain);
 }
-- 
1.7.4.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu