[PATCH v5 00/12] iommu/exynos: Fixes and Enhancements of System MMU driver with DT

2012-12-11 Thread Cho KyongHo
The current exynos-iommu(System MMU) driver does not work autonomously
since it is lack of support for power management of peripheral blocks.
For example, MFC device driver must ensure that its System MMU is disabled
before MFC block is power-down not to invalidate IOTLB in the System MMU
when I/O memory mapping is changed. Because A System MMU is resides in the
same H/W block, access to control registers of System MMU while the H/W
block is turned off must be prohibited.

This set of changes solves the above problem with setting each System MMUs
as the parent of the device which owns the System MMU to receive the
information when the device is turned off or turned on.

Another big change to the driver is the support for devicetree.
The bindings for System MMU is described in
Documentation/devicetree/bindings/arm/samsung/system-mmu.txt

In addition, this patchset also includes several bug fixes and enhancements
of the current driver.

Change log:
v5:
- new bugfix: patch 01
- Reordered patches
  * patch 01 ~ 05: Bugfix and enhancements of the existing driver
  * patch 06 ~ 10: Device Tree support and callbacks for power management
  * patch 11 : System MMU 3.2 and 3.3 support
  * patch 12 ~ 14: Debugging features
- Additional code compaction

v4:
- Remove Change-Id from v3 patches
- Change the order of the third and the first patch
  Thanks to Kukjin Kim.
- Fix memory leak when allocating and assigning exynos_iommu_owner to client
  device if the client device has multiple System MMUs.
  Thanks to Rahul Sharma.

v3:
- Fix prefetch buffer flag definition for System MMU 3.3 (patch 10/12)
- Fix incorrect setting for SET_RUNTIME_PM_OPS (patch 09/12)
  Thanks to Prathyush.

v2:
- Split the patch to iommu/exynos into 9 patches
- Support for System MMU 3.3
- Some code compaction

Patch summary:
[PATCH v5 01/14] iommu/exynos: add missing cache flush for removed pagetable 
entries
[PATCH v5 02/14] iommu/exynos: always use iommu fault handler
[PATCH v5 03/14] iommu/exynos: allocate lv2 page table from own slab
[PATCH v5 04/14] iommu/exynos: change rwlock to spinlock
[PATCH v5 05/14] ARM: EXYNOS: Add clk_ops for gating clocks of System MMU
[PATCH v5 06/14] ARM: EXYNOS: add System MMU definition to DT
[PATCH v5 07/14] iommu/exynos: support for device tree
[PATCH v5 08/14] iommu/exynos: set System MMU as the parent of client device
[PATCH v5 09/14] ARM: EXYNOS: remove system mmu initialization from exynos tree
[PATCH v5 10/14] iommu/exynos: add support for runtime pm and suspend/resume
[PATCH v5 11/14] iommu/exynos: add support for System MMU 3.2 and 3.3
[PATCH v5 12/14] iommu/exynos: pass version information from DT
[PATCH v5 13/14] iommu/exynos: add literal name of System MMU for debugging
[PATCH v5 14/14] iommu/exynos: add debugfs entries for System MMU

Diffstats:
 .../devicetree/bindings/arm/exynos/system-mmu.txt  |   86 ++
 arch/arm/boot/dts/exynos4210.dtsi  |   96 ++
 arch/arm/boot/dts/exynos4x12.dtsi  |  124 ++
 arch/arm/boot/dts/exynos5250.dtsi  |  154 +-
 arch/arm/mach-exynos/Kconfig   |5 -
 arch/arm/mach-exynos/Makefile  |1 -
 arch/arm/mach-exynos/clock-exynos4.c   |   41 +-
 arch/arm/mach-exynos/clock-exynos4210.c|9 +-
 arch/arm/mach-exynos/clock-exynos4212.c|   23 +-
 arch/arm/mach-exynos/clock-exynos5.c   |   86 +-
 arch/arm/mach-exynos/dev-sysmmu.c  |  274 
 arch/arm/mach-exynos/include/mach/sysmmu.h |   66 -
 arch/arm/mach-exynos/mach-exynos4-dt.c |   34 +
 arch/arm/mach-exynos/mach-exynos5-dt.c |   30 +
 drivers/iommu/Kconfig  |2 +-
 drivers/iommu/Makefile |2 +-
 drivers/iommu/exynos-iommu.c   | 1477 +++-
 17 files changed, 1745 insertions(+), 765 deletions(-)

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 01/14] iommu/exynos: add missing cache flush for removed pagetable entries

2012-12-11 Thread Cho KyongHo
This commit adds cache flush for removed small page and large page
entries in exynos_iommu_unmap(). Missing cache flush of removed
page table entries can cause missing page fault interrupt when a
master IP accesses an unmapped area.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 7fe44f8..b96f3b9 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1002,6 +1002,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain 
*domain,
 
if (lv2ent_small(ent)) {
*ent = 0;
+   pgtable_flush(ent, ent + 1);
size = SPAGE_SIZE;
priv-lv2entcnt[lv1ent_offset(iova)] += 1;
goto done;
@@ -1011,6 +1012,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain 
*domain,
BUG_ON(size  LPAGE_SIZE);
 
memset(ent, 0, sizeof(*ent) * SPAGES_PER_LPAGE);
+   pgtable_flush(ent, ent + SPAGES_PER_LPAGE);
 
size = LPAGE_SIZE;
priv-lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE;
-- 
1.8.0


--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 02/14] iommu/exynos: always use iommu fault handler

2012-12-11 Thread Cho KyongHo
This commit removes fault handler definition only for exynos-iommu
driver. Instead, always call iommu fault handler when a fault is
generated by a System MMU. Every new iommu_domain will have a default
fault handler and it can be overridden with iommu_set_fault_handler().
The default fault handler also generates debugging messages and kernel
woops.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 99 
 1 file changed, 36 insertions(+), 63 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index b96f3b9..ef7dbd1 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -124,16 +124,6 @@ enum exynos_sysmmu_inttype {
SYSMMU_FAULTS_NUM
 };
 
-/*
- * @itype: type of fault.
- * @pgtable_base: the physical address of page table base. This is 0 if @itype
- *is SYSMMU_BUSERROR.
- * @fault_addr: the device (virtual) address that the System MMU tried to
- * translated. This is 0 if @itype is SYSMMU_BUSERROR.
- */
-typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype,
-   unsigned long pgtable_base, unsigned long fault_addr);
-
 static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
REG_PAGE_FAULT_ADDR,
REG_AR_FAULT_ADDR,
@@ -176,7 +166,6 @@ struct sysmmu_drvdata {
int activations;
rwlock_t lock;
struct iommu_domain *domain;
-   sysmmu_fault_handler_t fault_handler;
unsigned long pgtable;
 };
 
@@ -291,48 +280,23 @@ finish:
read_unlock_irqrestore(data-lock, flags);
 }
 
-static void __set_fault_handler(struct sysmmu_drvdata *data,
-   sysmmu_fault_handler_t handler)
-{
-   unsigned long flags;
-
-   write_lock_irqsave(data-lock, flags);
-   data-fault_handler = handler;
-   write_unlock_irqrestore(data-lock, flags);
-}
-
-void exynos_sysmmu_set_fault_handler(struct device *dev,
-   sysmmu_fault_handler_t handler)
-{
-   struct sysmmu_drvdata *data = dev_get_drvdata(dev-archdata.iommu);
-
-   __set_fault_handler(data, handler);
-}
-
-static int default_fault_handler(enum exynos_sysmmu_inttype itype,
-unsigned long pgtable_base, unsigned long fault_addr)
+static void __show_fault_information(unsigned long *pgtable, unsigned long 
iova,
+int flags)
 {
unsigned long *ent;
 
-   if ((itype = SYSMMU_FAULTS_NUM) || (itype  SYSMMU_PAGEFAULT))
-   itype = SYSMMU_FAULT_UNKNOWN;
-
pr_err(%s occurred at 0x%lx(Page table base: 0x%lx)\n,
-   sysmmu_fault_name[itype], fault_addr, pgtable_base);
+   sysmmu_fault_name[flags], iova, __pa(pgtable));
 
-   ent = section_entry(__va(pgtable_base), fault_addr);
+   ent = section_entry(pgtable, iova);
pr_err(\tLv1 entry: 0x%lx\n, *ent);
 
if (lv1ent_page(ent)) {
-   ent = page_entry(ent, fault_addr);
+   ent = page_entry(ent, iova);
pr_err(\t Lv2 entry: 0x%lx\n, *ent);
}
 
pr_err(Generating Kernel OOPS... because it is unrecoverable.\n);
-
-   BUG();
-
-   return 0;
 }
 
 static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
@@ -341,7 +305,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
struct sysmmu_drvdata *data = dev_id;
struct resource *irqres;
struct platform_device *pdev;
-   enum exynos_sysmmu_inttype itype;
+   enum exynos_sysmmu_inttype itype = SYSMMU_FAULT_UNKNOWN;
unsigned long addr = -1;
 
int i, ret = -ENOSYS;
@@ -357,9 +321,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
break;
}
 
-   if (i == pdev-num_resources) {
-   itype = SYSMMU_FAULT_UNKNOWN;
-   } else {
+   if (i  pdev-num_resources) {
itype = (enum exynos_sysmmu_inttype)
__ffs(__raw_readl(data-sfrbases[i] + REG_INT_STATUS));
if (WARN_ON(!((itype = 0)  (itype  SYSMMU_FAULT_UNKNOWN
@@ -370,25 +332,25 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void 
*dev_id)
}
 
if (data-domain)
-   ret = report_iommu_fault(data-domain, data-dev,
-   addr, itype);
-
-   if ((ret == -ENOSYS)  data-fault_handler) {
-   unsigned long base = data-pgtable;
-   if (itype != SYSMMU_FAULT_UNKNOWN)
-   base = __raw_readl(
-   data-sfrbases[i] + REG_PT_BASE_ADDR);
-   ret = data-fault_handler(itype, base, addr);
-   }
-
-   if (!ret  (itype != SYSMMU_FAULT_UNKNOWN))
+   ret = report_iommu_fault(data-domain, data-dev, addr, itype);
+   else
+   

[PATCH v5 03/14] iommu/exynos: allocate lv2 page table from own slab

2012-12-11 Thread Cho KyongHo
Since kmalloc() does not guarantee the alignment of 1KB when it
allocates 1KB, it is required to allocate lv2 page table from
own slab that guarantees alignment of 1KB.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index ef7dbd1..58d2a24 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -101,6 +101,8 @@
 #define REG_PB1_SADDR  0x054
 #define REG_PB1_EADDR  0x058
 
+static struct kmem_cache *lv2table_kmem_cache;
+
 static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova)
 {
return pgtable + lv1ent_offset(iova);
@@ -739,7 +741,8 @@ static void exynos_iommu_domain_destroy(struct iommu_domain 
*domain)
 
for (i = 0; i  NUM_LV1ENTRIES; i++)
if (lv1ent_page(priv-pgtable + i))
-   kfree(__va(lv2table_base(priv-pgtable + i)));
+   kmem_cache_free(lv2table_kmem_cache,
+   __va(lv2table_base(priv-pgtable + i)));
 
free_pages((unsigned long)priv-pgtable, 2);
free_pages((unsigned long)priv-lv2entcnt, 1);
@@ -833,7 +836,7 @@ static unsigned long *alloc_lv2entry(unsigned long *sent, 
unsigned long iova,
if (lv1ent_fault(sent)) {
unsigned long *pent;
 
-   pent = kzalloc(LV2TABLE_SIZE, GFP_ATOMIC);
+   pent = kmem_cache_zalloc(lv2table_kmem_cache, GFP_ATOMIC);
BUG_ON((unsigned long)pent  (LV2TABLE_SIZE - 1));
if (!pent)
return NULL;
@@ -856,7 +859,7 @@ static int lv1set_section(unsigned long *sent, phys_addr_t 
paddr, short *pgcnt)
if (*pgcnt != NUM_LV2ENTRIES)
return -EADDRINUSE;
 
-   kfree(page_entry(sent, 0));
+   kmem_cache_free(lv2table_kmem_cache, page_entry(sent, 0));
 
*pgcnt = 0;
}
@@ -1044,10 +1047,23 @@ static int __init exynos_iommu_init(void)
 {
int ret;
 
+   lv2table_kmem_cache = kmem_cache_create(exynos-iommu-lv2table,
+   LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
+   if (!lv2table_kmem_cache) {
+   pr_err(%s: failed to create kmem cache\n, __func__);
+   return -ENOMEM;
+   }
+
ret = platform_driver_register(exynos_sysmmu_driver);
 
if (ret == 0)
-   bus_set_iommu(platform_bus_type, exynos_iommu_ops);
+   ret = bus_set_iommu(platform_bus_type, exynos_iommu_ops);
+
+   if (ret) {
+   pr_err(%s: Failed to register exynos-iommu driver.\n,
+   __func__);
+   kmem_cache_destroy(lv2table_kmem_cache);
+   }
 
return ret;
 }
-- 
1.8.0


--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 04/14] iommu/exynos: change rwlock to spinlock

2012-12-11 Thread Cho KyongHo
Since acquiring read_lock is not more frequent than write_lock, it is
not beneficial to use rwlock, this commit changes rwlock to spinlock.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 58d2a24..5847508 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -166,7 +166,7 @@ struct sysmmu_drvdata {
void __iomem **sfrbases;
struct clk *clk[2];
int activations;
-   rwlock_t lock;
+   spinlock_t lock;
struct iommu_domain *domain;
unsigned long pgtable;
 };
@@ -249,7 +249,7 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
BUG_ON((base0 + size0) = base0);
BUG_ON((size1  0)  ((base1 + size1) = base1));
 
-   read_lock_irqsave(data-lock, flags);
+   spin_lock_irqsave(data-lock, flags);
if (!is_sysmmu_active(data))
goto finish;
 
@@ -279,7 +279,7 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
}
}
 finish:
-   read_unlock_irqrestore(data-lock, flags);
+   spin_unlock_irqrestore(data-lock, flags);
 }
 
 static void __show_fault_information(unsigned long *pgtable, unsigned long 
iova,
@@ -312,7 +312,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
 
int i, ret = -ENOSYS;
 
-   read_lock(data-lock);
+   spin_lock(data-lock);
 
WARN_ON(!is_sysmmu_active(data));
 
@@ -354,7 +354,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
 
sysmmu_unblock(data-sfrbases[i]);
 
-   read_unlock(data-lock);
+   spin_unlock(data-lock);
 
return IRQ_HANDLED;
 }
@@ -365,7 +365,7 @@ static bool __exynos_sysmmu_disable(struct sysmmu_drvdata 
*data)
bool disabled = false;
int i;
 
-   write_lock_irqsave(data-lock, flags);
+   spin_lock_irqsave(data-lock, flags);
 
if (!set_sysmmu_inactive(data))
goto finish;
@@ -382,7 +382,7 @@ static bool __exynos_sysmmu_disable(struct sysmmu_drvdata 
*data)
data-pgtable = 0;
data-domain = NULL;
 finish:
-   write_unlock_irqrestore(data-lock, flags);
+   spin_unlock_irqrestore(data-lock, flags);
 
if (disabled)
dev_dbg(data-sysmmu, (%s) Disabled\n, data-dbgname);
@@ -405,7 +405,7 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata 
*data,
int i, ret = 0;
unsigned long flags;
 
-   write_lock_irqsave(data-lock, flags);
+   spin_lock_irqsave(data-lock, flags);
 
if (!set_sysmmu_active(data)) {
if (WARN_ON(pgtable != data-pgtable)) {
@@ -444,7 +444,7 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata 
*data,
 
dev_dbg(data-sysmmu, (%s) Enabled\n, data-dbgname);
 finish:
-   write_unlock_irqrestore(data-lock, flags);
+   spin_unlock_irqrestore(data-lock, flags);
 
return ret;
 }
@@ -491,7 +491,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, 
unsigned long iova)
unsigned long flags;
struct sysmmu_drvdata *data = dev_get_drvdata(dev-archdata.iommu);
 
-   read_lock_irqsave(data-lock, flags);
+   spin_lock_irqsave(data-lock, flags);
 
if (is_sysmmu_active(data)) {
int i;
@@ -508,7 +508,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, 
unsigned long iova)
data-dbgname);
}
 
-   read_unlock_irqrestore(data-lock, flags);
+   spin_unlock_irqrestore(data-lock, flags);
 }
 
 void exynos_sysmmu_tlb_invalidate(struct device *dev)
@@ -516,7 +516,7 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev)
unsigned long flags;
struct sysmmu_drvdata *data = dev_get_drvdata(dev-archdata.iommu);
 
-   read_lock_irqsave(data-lock, flags);
+   spin_lock_irqsave(data-lock, flags);
 
if (is_sysmmu_active(data)) {
int i;
@@ -532,7 +532,7 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev)
data-dbgname);
}
 
-   read_unlock_irqrestore(data-lock, flags);
+   spin_unlock_irqrestore(data-lock, flags);
 }
 
 static int exynos_sysmmu_probe(struct platform_device *pdev)
@@ -629,7 +629,7 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
}
 
data-sysmmu = dev;
-   rwlock_init(data-lock);
+   spin_lock_init(data-lock);
INIT_LIST_HEAD(data-node);
 
if (dev-parent)
-- 
1.8.0


--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 05/14] ARM: EXYNOS: Add clk_ops for gating clocks of System MMU

2012-12-11 Thread Cho KyongHo
Touching some System MMU needs its master devices' clock to be enabled
before. This commit adds clk_ops.set_parent of gating clocks of System
MMU to ensure gating clocks of System MMU's mater devices are enabled
when enabling gating clocks of System MMU.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 arch/arm/mach-exynos/clock-exynos5.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/mach-exynos/clock-exynos5.c 
b/arch/arm/mach-exynos/clock-exynos5.c
index e48d7c2..a86e88e 100644
--- a/arch/arm/mach-exynos/clock-exynos5.c
+++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -614,6 +614,16 @@ static struct clksrc_clk exynos5_clk_aclk_300_gscl = {
.reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 10, .size = 1 },
 };
 
+static int exynos5_gate_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+   clk-parent = parent;
+   return 0;
+}
+
+static struct clk_ops exynos5_gate_clk_ops = {
+   .set_parent = exynos5_gate_clk_set_parent
+};
+
 static struct clk exynos5_init_clocks_off[] = {
{
.name   = timers,
@@ -855,71 +865,85 @@ static struct clk exynos5_init_clocks_off[] = {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
.enable = exynos5_clk_ip_mfc_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  1),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
.enable = exynos5_clk_ip_mfc_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  2),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(tv, 2),
.enable = exynos5_clk_ip_disp1_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  9)
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(jpeg, 3),
.enable = exynos5_clk_ip_gen_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  7),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(rot, 4),
.enable = exynos5_clk_ip_gen_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  6)
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(gsc0, 5),
.enable = exynos5_clk_ip_gscl_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  7),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(gsc1, 6),
.enable = exynos5_clk_ip_gscl_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  8),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(gsc2, 7),
.enable = exynos5_clk_ip_gscl_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  9),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(gsc3, 8),
.enable = exynos5_clk_ip_gscl_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  10),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(isp, 9),
.enable = exynos5_clk_ip_isp0_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (0x3F  8),
}, {
.name   = SYSMMU_CLOCK_NAME2,
.devname= SYSMMU_CLOCK_DEVNAME(isp, 9),
.enable = exynos5_clk_ip_isp1_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (0xF  4),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(camif0, 12),
.enable = exynos5_clk_ip_gscl_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  11),
}, {
.name   = SYSMMU_CLOCK_NAME,
.devname= SYSMMU_CLOCK_DEVNAME(camif1, 13),
.enable = exynos5_clk_ip_gscl_ctrl,
+   .ops= exynos5_gate_clk_ops,
.ctrlbit= (1  12),
}, {
.name   = 

[PATCH v5 06/14] ARM: EXYNOS: add System MMU definition to DT

2012-12-11 Thread Cho KyongHo
This commit adds System MMU nodes to DT of Exynos SoCs.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 .../devicetree/bindings/arm/exynos/system-mmu.txt  |  86 
 arch/arm/boot/dts/exynos4210.dtsi  |  96 ++
 arch/arm/boot/dts/exynos4x12.dtsi  | 124 +
 arch/arm/boot/dts/exynos5250.dtsi  | 147 -
 4 files changed, 451 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/exynos/system-mmu.txt

diff --git a/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
b/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
new file mode 100644
index 000..9c30a36
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/exynos/system-mmu.txt
@@ -0,0 +1,86 @@
+* Samsung Exynos System MMU
+
+Samsung's Exynos architecture includes System MMU that enables scattered
+physical chunks to be visible as a contiguous region to DMA-capabile peripheral
+devices like MFC, FIMC, FIMD, GScaler, FIMC-IS and so forth.
+
+System MMU is a sort of IOMMU and support identical translation table format to
+ARMv7 translation tables with minimum set of page properties including access
+permissions, shareability and security protection. In addition System MMU has
+another capabilities like L2 TLB or block-fetch buffers to minimize translation
+latency
+
+Each System MMU is included in the H/W block of a peripheral device. Thus, it 
is
+important to specify that a System MMU is dedicated to which peripheral device
+before using System MMU. System initialization must specify the relationships
+between a System MMU and a peripheral device that owns the System MMU.
+
+Some device drivers may control several peripheral devices with a single device
+descriptor like MFC. Since handling a System MMU with IOMMU API requires a
+device descriptor that needs the System MMU, it is best to combine the System
+MMUs of the peripheral devices and control them with a single System MMU device
+descriptor. If it is unable to combine them into a single device descriptor,
+they can be linked with each other by the means of device.parent relationship.
+
+Required properties:
+- compatible: Should be samsung,exynos-sysmmu.
+- reg: Tuples of base address and size of System MMU registers. The number of
+   tuples can be more than one if two or more System MMUs are controlled
+   by a single device descriptor.
+- interrupt-parent: The phandle of the interrupt controller of System MMU
+- interrupts: Tuples of numbers that indicates the interrupt source. The
+  number of elements in the tuple is dependent upon
+ 'interrupt-parent' property. The number of tuples in this property
+ must be the same with 'reg' property.
+
+Optional properties:
+- mmuname: Strings of the name of System MMU for debugging purpose. The number
+  of strings must be the same with the number of tuples in 'reg'
+  property.
+- mmu-master: phandle to the device node that owns System MMU. Only the device
+  that is specified whith this property can control System MMU with
+  IOMMU API.
+
+Examples:
+
+MFC has 2 System MMUs for each port that MFC is attached. Thus it seems natural
+to define 2 System MMUs for each port of the MFC:
+
+   sysmmu-mfc-l {
+   mmuname = mfc_l;
+   reg = 0x1121 0x1000;
+   compatible = samsung,exynos-sysmmu;
+   interrupt-parent = combiner;
+   interrupts = 8 5;
+   mmu-master = mfc;
+   };
+
+   sysmmu-mfc-r {
+   mmuname = mfc_r;
+   reg = 0x1120 0x1000;
+   compatible = samsung,exynos-sysmmu;
+   interrupt-parent = combiner;
+   interrupts = 6 2;
+   mmu-master = mfc;
+   };
+
+Actually, MFC device driver requires sub-devices that represents each port and
+above 'mmu-master' properties of sysmmu-mfc-l and sysmmu-mfc-r have the 
phandles
+to those sub-devices.
+
+However, it is also a good idea that treats the above System MMUs as one System
+MMU because those System MMUs are actually required by the MFC device:
+
+   sysmmu-mfc {
+   mmuname = mfc_l, mfc_r;
+   reg = 0x1121 0x1000
+  0x1120 0x1000;
+   compatible = samsung,exynos-sysmmu;
+   interrupt-parent = combiner;
+   interrupts = 8 5
+ 6 2;
+   mmu-master = mfc;
+   };
+
+If System MMU of MFC is defined like the above, the number of elements and the
+order of list in 'mmuname', 'reg' and 'interrupts' must be the same.
diff --git a/arch/arm/boot/dts/exynos4210.dtsi 
b/arch/arm/boot/dts/exynos4210.dtsi
index 939f639..d7a7a06 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -71,4 +71,100 @@
reg = 0x100C 0x100;
 

[PATCH v5 07/14] iommu/exynos: support for device tree

2012-12-11 Thread Cho KyongHo
This commit adds device tree support for System MMU.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/Kconfig|   2 +-
 drivers/iommu/exynos-iommu.c | 282 ++-
 2 files changed, 174 insertions(+), 110 deletions(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index e39f9db..64586f1 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -168,7 +168,7 @@ config TEGRA_IOMMU_SMMU
 
 config EXYNOS_IOMMU
bool Exynos IOMMU Support
-   depends on ARCH_EXYNOS  EXYNOS_DEV_SYSMMU
+   depends on ARCH_EXYNOS
select IOMMU_API
help
  Support for the IOMMU(System MMU) of Samsung Exynos application
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 5847508..5b35820 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1,6 +1,6 @@
-/* linux/drivers/iommu/exynos_iommu.c
+/* linux/drivers/iommu/exynos-iommu.c
  *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
  * http://www.samsung.com
  *
  * This program is free software; you can redistribute it and/or modify
@@ -12,6 +12,7 @@
 #define DEBUG
 #endif
 
+#include linux/kernel.h
 #include linux/io.h
 #include linux/interrupt.h
 #include linux/platform_device.h
@@ -25,11 +26,10 @@
 #include linux/list.h
 #include linux/memblock.h
 #include linux/export.h
+#include linux/of.h
+#include linux/of_platform.h
 
 #include asm/cacheflush.h
-#include asm/pgtable.h
-
-#include mach/sysmmu.h
 
 /* We does not consider super section mapping (16MB) */
 #define SECT_ORDER 20
@@ -161,14 +161,13 @@ struct sysmmu_drvdata {
struct list_head node; /* entry of exynos_iommu_domain.clients */
struct device *sysmmu;  /* System MMU's device descriptor */
struct device *dev; /* Owner of system MMU */
-   char *dbgname;
int nsfrs;
-   void __iomem **sfrbases;
-   struct clk *clk[2];
+   struct clk *clk;
int activations;
spinlock_t lock;
struct iommu_domain *domain;
unsigned long pgtable;
+   void __iomem *sfrbases[0];
 };
 
 static bool set_sysmmu_active(struct sysmmu_drvdata *data)
@@ -373,10 +372,8 @@ static bool __exynos_sysmmu_disable(struct sysmmu_drvdata 
*data)
for (i = 0; i  data-nsfrs; i++)
__raw_writel(CTRL_DISABLE, data-sfrbases[i] + REG_MMU_CTRL);
 
-   if (data-clk[1])
-   clk_disable(data-clk[1]);
-   if (data-clk[0])
-   clk_disable(data-clk[0]);
+   if (data-clk)
+   clk_disable(data-clk);
 
disabled = true;
data-pgtable = 0;
@@ -385,10 +382,10 @@ finish:
spin_unlock_irqrestore(data-lock, flags);
 
if (disabled)
-   dev_dbg(data-sysmmu, (%s) Disabled\n, data-dbgname);
+   dev_dbg(data-sysmmu, Disabled\n);
else
-   dev_dbg(data-sysmmu, (%s) %d times left to be disabled\n,
-   data-dbgname, data-activations);
+   dev_dbg(data-sysmmu, %d times left to be disabled\n,
+   data-activations);
 
return disabled;
 }
@@ -415,14 +412,12 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata 
*data,
ret = 1;
}
 
-   dev_dbg(data-sysmmu, (%s) Already enabled\n, data-dbgname);
+   dev_dbg(data-sysmmu, Already enabled\n);
goto finish;
}
 
-   if (data-clk[0])
-   clk_enable(data-clk[0]);
-   if (data-clk[1])
-   clk_enable(data-clk[1]);
+   if (data-clk)
+   clk_enable(data-clk);
 
data-pgtable = pgtable;
 
@@ -442,7 +437,7 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata 
*data,
 
data-domain = domain;
 
-   dev_dbg(data-sysmmu, (%s) Enabled\n, data-dbgname);
+   dev_dbg(data-sysmmu, Enabled\n);
 finish:
spin_unlock_irqrestore(data-lock, flags);
 
@@ -458,7 +453,7 @@ int exynos_sysmmu_enable(struct device *dev, unsigned long 
pgtable)
 
ret = pm_runtime_get_sync(data-sysmmu);
if (ret  0) {
-   dev_dbg(data-sysmmu, (%s) Failed to enable\n, data-dbgname);
+   dev_dbg(data-sysmmu, Failed to enable\n);
return ret;
}
 
@@ -466,8 +461,8 @@ int exynos_sysmmu_enable(struct device *dev, unsigned long 
pgtable)
if (WARN_ON(ret  0)) {
pm_runtime_put(data-sysmmu);
dev_err(data-sysmmu,
-   (%s) Already enabled with page table %#lx\n,
-   data-dbgname, data-pgtable);
+   Already enabled with page table %#lx\n,
+   data-pgtable);
} else {
data-dev = dev;
}
@@ -504,8 +499,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, 
unsigned 

[PATCH v5 09/14] ARM: EXYNOS: remove system mmu initialization from exynos tree

2012-12-11 Thread Cho KyongHo
This removes System MMU initialization from arch/arm/mach-exynos/
to move them to DT and the exynos-iommu driver except gating clock
definitions.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 arch/arm/mach-exynos/Kconfig   |   5 -
 arch/arm/mach-exynos/Makefile  |   1 -
 arch/arm/mach-exynos/clock-exynos4.c   |  41 +++--
 arch/arm/mach-exynos/clock-exynos4210.c|   9 +-
 arch/arm/mach-exynos/clock-exynos4212.c|  23 ++-
 arch/arm/mach-exynos/clock-exynos5.c   |  62 ---
 arch/arm/mach-exynos/dev-sysmmu.c  | 274 -
 arch/arm/mach-exynos/include/mach/sysmmu.h |  66 ---
 arch/arm/mach-exynos/mach-exynos4-dt.c |  34 
 arch/arm/mach-exynos/mach-exynos5-dt.c |  30 
 10 files changed, 137 insertions(+), 408 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/dev-sysmmu.c
 delete mode 100644 arch/arm/mach-exynos/include/mach/sysmmu.h

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index bb3b09a..d5157d7 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -94,11 +94,6 @@ config EXYNOS4_SETUP_FIMD0
help
  Common setup code for FIMD0.
 
-config EXYNOS_DEV_SYSMMU
-   bool
-   help
- Common setup code for SYSTEM MMU in EXYNOS platforms
-
 config EXYNOS4_DEV_DWMCI
bool
help
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 1797dee..7460ba2 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -53,7 +53,6 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI)+= dev-ahci.o
 obj-$(CONFIG_EXYNOS4_DEV_DWMCI)+= dev-dwmci.o
 obj-$(CONFIG_EXYNOS_DEV_DMA)   += dma.o
 obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o
-obj-$(CONFIG_EXYNOS_DEV_SYSMMU)+= dev-sysmmu.o
 
 obj-$(CONFIG_ARCH_EXYNOS)  += setup-i2c0.o
 obj-$(CONFIG_EXYNOS4_SETUP_FIMC)   += setup-fimc.o
diff --git a/arch/arm/mach-exynos/clock-exynos4.c 
b/arch/arm/mach-exynos/clock-exynos4.c
index efead60..c81a0ca 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -24,7 +24,6 @@
 
 #include mach/map.h
 #include mach/regs-clock.h
-#include mach/sysmmu.h
 
 #include common.h
 #include clock-exynos4.h
@@ -709,53 +708,53 @@ static struct clk exynos4_init_clocks_off[] = {
.enable = exynos4_clk_ip_peril_ctrl,
.ctrlbit= (1  14),
}, {
-   .name   = SYSMMU_CLOCK_NAME,
-   .devname= SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
+   .name   = sysmmu,
+   .devname= exynos-sysmmu.0,
.enable = exynos4_clk_ip_mfc_ctrl,
.ctrlbit= (1  1),
}, {
-   .name   = SYSMMU_CLOCK_NAME,
-   .devname= SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
+   .name   = sysmmu,
+   .devname= exynos-sysmmu.1,
.enable = exynos4_clk_ip_mfc_ctrl,
.ctrlbit= (1  2),
}, {
-   .name   = SYSMMU_CLOCK_NAME,
-   .devname= SYSMMU_CLOCK_DEVNAME(tv, 2),
+   .name   = sysmmu,
+   .devname= exynos-sysmmu.2,
.enable = exynos4_clk_ip_tv_ctrl,
.ctrlbit= (1  4),
}, {
-   .name   = SYSMMU_CLOCK_NAME,
-   .devname= SYSMMU_CLOCK_DEVNAME(jpeg, 3),
+   .name   = sysmmu,
+   .devname= exynos-sysmmu.3,
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit= (1  11),
}, {
-   .name   = SYSMMU_CLOCK_NAME,
-   .devname= SYSMMU_CLOCK_DEVNAME(rot, 4),
+   .name   = sysmmu,
+   .devname= exynos-sysmmu.4,
.enable = exynos4_clk_ip_image_ctrl,
.ctrlbit= (1  4),
}, {
-   .name   = SYSMMU_CLOCK_NAME,
-   .devname= SYSMMU_CLOCK_DEVNAME(fimc0, 5),
+   .name   = sysmmu,
+   .devname= exynos-sysmmu.5,
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit= (1  7),
}, {
-   .name   = SYSMMU_CLOCK_NAME,
-   .devname= SYSMMU_CLOCK_DEVNAME(fimc1, 6),
+   .name   = sysmmu,
+   .devname= exynos-sysmmu.6,
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit= (1  8),
}, {
-   .name   = SYSMMU_CLOCK_NAME,
-   .devname= SYSMMU_CLOCK_DEVNAME(fimc2, 7),
+   .name   = sysmmu,
+   .devname= 

[PATCH v5 13/14] iommu/exynos: add literal name of System MMU for debugging

2012-12-11 Thread Cho KyongHo
This commit adds System MMU name to the driver data of each System
MMU. It is used by fault information.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 72 
 1 file changed, 59 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 70921e9..9753e0e 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -26,6 +26,7 @@
 #include linux/list.h
 #include linux/memblock.h
 #include linux/export.h
+#include linux/string.h
 #include linux/of.h
 #include linux/of_platform.h
 
@@ -180,6 +181,7 @@ struct exynos_iommu_domain {
short *lv2entcnt; /* free lv2 entry counter for each section */
spinlock_t lock; /* lock for this structure */
spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
+   const char *fault_info; /* debugging information for fault */
 };
 
 /* exynos_iommu_owner
@@ -224,6 +226,7 @@ struct sysmmu_drvdata {
struct iommu_domain *domain;
unsigned long pgtable;
bool runtime_active;
+   const char **mmuname;
void __iomem *sfrbases[0];
 };
 
@@ -601,25 +604,29 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void 
*dev_id)
 {
/* SYSMMU is in blocked when interrupt occurred. */
struct sysmmu_drvdata *data = dev_id;
-   struct resource *irqres;
-   struct platform_device *pdev;
+   struct exynos_iommu_owner *owner = NULL;
enum exynos_sysmmu_inttype itype = SYSMMU_FAULT_UNKNOWN;
unsigned long addr = -1;
-
int i, ret = -ENOSYS;
 
-   spin_lock(data-lock);
+   if (data-master)
+   owner = data-master-archdata.iommu;
+
+   if (owner)
+   spin_lock(owner-lock);
 
WARN_ON(!is_sysmmu_active(data));
 
-   pdev = to_platform_device(data-sysmmu);
-   for (i = 0; i  (pdev-num_resources / 2); i++) {
-   irqres = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+   for (i = 0; i  data-nsfrs; i++) {
+   struct resource *irqres;
+   irqres = platform_get_resource(
+   to_platform_device(data-sysmmu),
+   IORESOURCE_IRQ, i);
if (irqres  ((int)irqres-start == irq))
break;
}
 
-   if (i  pdev-num_resources) {
+   if (i  data-nsfrs) {
itype = (enum exynos_sysmmu_inttype)
__ffs(__raw_readl(data-sfrbases[i] + REG_INT_STATUS));
if (WARN_ON(!((itype = 0)  (itype  SYSMMU_FAULT_UNKNOWN
@@ -629,11 +636,17 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void 
*dev_id)
data-sfrbases[i] + fault_reg_offset[itype]);
}
 
-   if (data-domain)
+   if ((itype = SYSMMU_FAULTS_NUM) || (itype  SYSMMU_PAGEFAULT))
+   itype = SYSMMU_FAULT_UNKNOWN;
+
+   if (data-domain) {
+   struct exynos_iommu_domain *priv = data-domain-priv;
+   priv-fault_info = data-mmuname[i];
ret = report_iommu_fault(data-domain,
data-master, addr, itype);
-   else
+   } else {
__show_fault_information(__va(data-pgtable), itype, addr);
+   }
 
if (ret == -ENOSYS)
pr_err(NO SYSTEM MMU FAULT HANDLER REGISTERED FOR %s\n,
@@ -651,7 +664,8 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
 
sysmmu_unblock(data-sfrbases[i]);
 
-   spin_unlock(data-lock);
+   if (owner)
+   spin_unlock(owner-lock);
 
return IRQ_HANDLED;
 }
@@ -1028,6 +1042,30 @@ err_dev_put:
return ret;
 }
 
+static void __init __sysmmu_init_mmuname(struct device *sysmmu,
+   struct sysmmu_drvdata *drvdata)
+{
+   int i;
+   const char *mmuname;
+
+   if (of_property_count_strings(sysmmu-of_node, mmuname) !=
+   drvdata-nsfrs)
+   return;
+
+   drvdata-mmuname = (void *)drvdata-sfrbases +
+   sizeof(drvdata-sfrbases[0]) * drvdata-nsfrs;
+
+   for (i = 0; i  drvdata-nsfrs; i++) {
+   if (of_property_read_string_index(sysmmu-of_node,
+   mmuname, i, mmuname))
+   dev_err(sysmmu, Failed read mmuname[%d]\n, i);
+   else
+   drvdata-mmuname[i] = kstrdup(mmuname, GFP_KERNEL);
+   if (!drvdata-mmuname[i])
+   drvdata-mmuname[i] = noname;
+   }
+}
+
 static int __init exynos_sysmmu_probe(struct platform_device *pdev)
 {
int i, ret;
@@ -1039,9 +1077,14 @@ static int __init exynos_sysmmu_probe(struct 
platform_device *pdev)
return -ENODEV;
}
 
+   ret = of_property_count_strings(pdev-dev.of_node, mmuname);
+

[PATCH v5 14/14] iommu/exynos: add debugfs entries for System MMU

2012-12-11 Thread Cho KyongHo
This commit adds debugfs directory and nodes for inspecting internal
state of System MMU.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 204 +--
 1 file changed, 198 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 9753e0e..78c0eb7 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -26,12 +26,17 @@
 #include linux/list.h
 #include linux/memblock.h
 #include linux/export.h
+#include linux/fs.h
+#include linux/seq_file.h
+#include linux/debugfs.h
 #include linux/string.h
 #include linux/of.h
 #include linux/of_platform.h
 
 #include asm/cacheflush.h
 
+#define MODULE_NAME exynos-sysmmu
+
 /* We does not consider super section mapping (16MB) */
 #define SECT_ORDER 20
 #define LPAGE_ORDER 16
@@ -223,6 +228,7 @@ struct sysmmu_drvdata {
struct sysmmu_prefbuf pbufs[MAX_NUM_PBUF];
int num_pbufs;
struct sysmmu_version ver;
+   struct dentry *debugfs_root;
struct iommu_domain *domain;
unsigned long pgtable;
bool runtime_active;
@@ -1066,6 +1072,8 @@ static void __init __sysmmu_init_mmuname(struct device 
*sysmmu,
}
 }
 
+static void __create_debugfs_entry(struct sysmmu_drvdata *drvdata);
+
 static int __init exynos_sysmmu_probe(struct platform_device *pdev)
 {
int i, ret;
@@ -1134,6 +1142,8 @@ static int __init exynos_sysmmu_probe(struct 
platform_device *pdev)
 
data-runtime_active = !pm_runtime_enabled(dev);
 
+   __create_debugfs_entry(data);
+
platform_set_drvdata(pdev, data);
 
dev-archdata.iommu = sysmmu_placeholder;
@@ -1238,7 +1248,7 @@ static struct platform_driver exynos_sysmmu_driver 
__refdata = {
.probe  = exynos_sysmmu_probe,
.driver = {
.owner  = THIS_MODULE,
-   .name   = exynos-sysmmu,
+   .name   = MODULE_NAME,
.pm = __pm_ops,
.of_match_table = of_match_ptr(sysmmu_of_match),
}
@@ -1631,6 +1641,8 @@ static struct iommu_ops exynos_iommu_ops = {
.pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
 };
 
+static struct dentry *sysmmu_debugfs_root; /* /sys/kernel/debug/sysmmu */
+
 static int __init exynos_iommu_init(void)
 {
int ret;
@@ -1642,17 +1654,197 @@ static int __init exynos_iommu_init(void)
return -ENOMEM;
}
 
-   ret = platform_driver_register(exynos_sysmmu_driver);
+   ret = bus_set_iommu(platform_bus_type, exynos_iommu_ops);
+   if (ret) {
+   kmem_cache_destroy(lv2table_kmem_cache);
+   pr_err(%s: Failed to register IOMMU ops\n, __func__);
+   return -EFAULT;
+   }
 
-   if (ret == 0)
-   ret = bus_set_iommu(platform_bus_type, exynos_iommu_ops);
+   sysmmu_debugfs_root = debugfs_create_dir(sysmmu, NULL);
+   if (!sysmmu_debugfs_root)
+   pr_err(%s: Failed to create debugfs entry, 'sysmmu'\n,
+   __func__);
+   if (IS_ERR(sysmmu_debugfs_root))
+   sysmmu_debugfs_root = NULL;
 
+   ret = platform_driver_register(exynos_sysmmu_driver);
if (ret) {
-   pr_err(%s: Failed to register exynos-iommu driver.\n,
-   __func__);
kmem_cache_destroy(lv2table_kmem_cache);
+   pr_err(%s: Failed to register System MMU driver\n, __func__);
}
 
return ret;
 }
 subsys_initcall(exynos_iommu_init);
+
+static int debug_string_show(struct seq_file *s, void *unused)
+{
+   char *str = s-private;
+
+   seq_printf(s, %s\n, str);
+
+   return 0;
+}
+
+static int debug_sysmmu_list_show(struct seq_file *s, void *unused)
+{
+   struct sysmmu_drvdata *drvdata = s-private;
+   struct platform_device *pdev = to_platform_device(drvdata-sysmmu);
+   int idx, maj, min, ret;
+
+   seq_printf(s, SysMMU Name | Ver | SFR Base\n);
+
+   if (pm_runtime_enabled(drvdata-sysmmu)) {
+   ret = pm_runtime_get_sync(drvdata-sysmmu);
+   if (ret  0)
+   return ret;
+   }
+
+   for (idx = 0; idx  drvdata-nsfrs; idx++) {
+   struct resource *res;
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, idx);
+   if (!res)
+   break;
+
+   maj = __sysmmu_version(drvdata, idx, min);
+
+   if (drvdata-mmuname) {
+   if (maj == 0)
+   seq_printf(s, %11.s | N/A | 0x%08x\n,
+   drvdata-mmuname[idx], res-start);
+   else
+   seq_printf(s, %11.s | %d.%d | 0x%08x\n,
+   

[PATCH v5 08/14] iommu/exynos: set System MMU as the parent of client device

2012-12-11 Thread Cho KyongHo
This commit sets System MM as the parent of the client device for
power management. If System MMU is the parent of a device, it is
guaranteed that System MMU is suspended later than the device and
resumed earlier. Runtime suspend/resume on the device is also
propagated to the System MMU.
If a device is configured to have more than one System MMU, the
advantage of power management also works and the System MMUs are
also have relationships of parent and child. In this situation,
the client device is still the descendant of its System MMUs.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 510 +--
 1 file changed, 342 insertions(+), 168 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 5b35820..a0e5ee1 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -101,6 +101,17 @@
 #define REG_PB1_SADDR  0x054
 #define REG_PB1_EADDR  0x058
 
+static void *sysmmu_placeholder; /* Inidcate if a device is System MMU */
+
+#define is_sysmmu(sysmmu) (sysmmu-archdata.iommu == sysmmu_placeholder)
+#define has_sysmmu(dev)
\
+   (dev-parent  dev-archdata.iommu  is_sysmmu(dev-parent))
+#define for_each_sysmmu(dev, sysmmu)   \
+   for (sysmmu = dev-parent; sysmmu  is_sysmmu(sysmmu); \
+   sysmmu = sysmmu-parent)
+#define for_each_sysmmu_until(dev, sysmmu, until)  \
+   for (sysmmu = dev-parent; sysmmu != until; sysmmu = sysmmu-parent)
+
 static struct kmem_cache *lv2table_kmem_cache;
 
 static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova)
@@ -157,10 +168,19 @@ struct exynos_iommu_domain {
spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
 };
 
+/* exynos_iommu_owner
+ * Metadata attached to the owner of a group of System MMUs that belong
+ * to the same owner device.
+ */
+struct exynos_iommu_owner {
+   struct list_head client; /* entry of exynos_iommu_domain.clients */
+   struct device *dev;
+   spinlock_t lock;/* Lock to preserve consistency of System MMU */
+};
+
 struct sysmmu_drvdata {
-   struct list_head node; /* entry of exynos_iommu_domain.clients */
struct device *sysmmu;  /* System MMU's device descriptor */
-   struct device *dev; /* Owner of system MMU */
+   struct device *master;  /* Client device that needs System MMU */
int nsfrs;
struct clk *clk;
int activations;
@@ -241,44 +261,50 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
unsigned long base0, unsigned long size0,
unsigned long base1, unsigned long size1)
 {
-   struct sysmmu_drvdata *data = dev_get_drvdata(dev-archdata.iommu);
-   unsigned long flags;
-   int i;
+   struct device *sysmmu;
 
-   BUG_ON((base0 + size0) = base0);
-   BUG_ON((size1  0)  ((base1 + size1) = base1));
+   for_each_sysmmu(dev, sysmmu) {
+   int i;
+   unsigned long flags;
+   struct sysmmu_drvdata *data = dev_get_drvdata(sysmmu);
 
-   spin_lock_irqsave(data-lock, flags);
-   if (!is_sysmmu_active(data))
-   goto finish;
+   BUG_ON((base0 + size0) = base0);
+   BUG_ON((size1  0)  ((base1 + size1) = base1));
 
-   for (i = 0; i  data-nsfrs; i++) {
-   if ((readl(data-sfrbases[i] + REG_MMU_VERSION)  28) == 3) {
-   if (!sysmmu_block(data-sfrbases[i]))
-   continue;
+   spin_lock_irqsave(data-lock, flags);
+   if (!is_sysmmu_active(data)) {
+   spin_unlock_irqrestore(data-lock, flags);
+   continue;
+   }
 
-   if (size1 == 0) {
-   if (size0 = SZ_128K) {
-   base1 = base0;
-   size1 = size0;
-   } else {
-   size1 = size0 -
+   for (i = 0; i  data-nsfrs; i++) {
+   if ((readl(data-sfrbases[i] + REG_MMU_VERSION)  28)
+   == 3) {
+   if (!sysmmu_block(data-sfrbases[i]))
+   continue;
+
+   if (size1 == 0) {
+   if (size0 = SZ_128K) {
+   base1 = base0;
+   size1 = size0;
+   } else {
+   size1 = size0 -
ALIGN(size0 / 2, SZ_64K);

[PATCH v5 10/14] iommu/exynos: add support for runtime pm and suspend/resume

2012-12-11 Thread Cho KyongHo
This change enables the client device drivers not to care about
the state of System MMU since the internal state of System MMU
is controlled by the runtime PM and suspend/resume callback functions.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 176 ++-
 1 file changed, 89 insertions(+), 87 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index a0e5ee1..c3c5b7b 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -187,6 +187,7 @@ struct sysmmu_drvdata {
spinlock_t lock;
struct iommu_domain *domain;
unsigned long pgtable;
+   bool runtime_active;
void __iomem *sfrbases[0];
 };
 
@@ -409,7 +410,8 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data)
data-pgtable = 0;
data-domain = NULL;
 
-   __sysmmu_disable_nocount(data);
+   if (data-runtime_active)
+   __sysmmu_disable_nocount(data);
 
dev_dbg(data-sysmmu, Disabled\n);
} else  {
@@ -422,30 +424,6 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data)
return disabled;
 }
 
-static bool __exynos_sysmmu_disable(struct device *dev)
-{
-   unsigned long flags;
-   bool disabled = true;
-   struct exynos_iommu_owner *owner = dev-archdata.iommu;
-   struct device *sysmmu;
-
-   BUG_ON(!has_sysmmu(dev));
-
-   spin_lock_irqsave(owner-lock, flags);
-
-   /* Every call to __sysmmu_disable() must return same result */
-   for_each_sysmmu(dev, sysmmu) {
-   struct sysmmu_drvdata *data = dev_get_drvdata(sysmmu);
-   disabled = __sysmmu_disable(data);
-   if (disabled)
-   data-master = NULL;
-   }
-
-   spin_unlock_irqrestore(owner-lock, flags);
-
-   return disabled;
-}
-
 static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
 {
int i;
@@ -481,7 +459,8 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
data-pgtable = pgtable;
data-domain = domain;
 
-   __sysmmu_enable_nocount(data);
+   if (data-runtime_active)
+   __sysmmu_enable_nocount(data);
 
dev_dbg(data-sysmmu, Enabled\n);
} else {
@@ -537,42 +516,31 @@ static int __exynos_sysmmu_enable(struct device *dev, 
unsigned long pgtable,
 
 int exynos_sysmmu_enable(struct device *dev, unsigned long pgtable)
 {
-   int ret;
-   struct device *sysmmu;
-
BUG_ON(!memblock_is_memory(pgtable));
 
-   for_each_sysmmu(dev, sysmmu) {
-   ret = pm_runtime_get_sync(sysmmu);
-   if (ret  0)
-   break;
-   }
-
-   if (ret  0) {
-   struct device *start;
-   for_each_sysmmu_until(dev, start, sysmmu)
-   pm_runtime_put(start);
-
-   return ret;
-   }
-
-   ret = __exynos_sysmmu_enable(dev, pgtable, NULL);
-   if (ret  0)
-   for_each_sysmmu(dev, sysmmu)
-   pm_runtime_put(sysmmu);
-
-   return ret;
+   return __exynos_sysmmu_enable(dev, pgtable, NULL);
 }
 
 bool exynos_sysmmu_disable(struct device *dev)
 {
-   bool disabled;
+   unsigned long flags;
+   bool disabled = true;
+   struct exynos_iommu_owner *owner = dev-archdata.iommu;
struct device *sysmmu;
 
-   disabled = __exynos_sysmmu_disable(dev);
+   BUG_ON(!has_sysmmu(dev));
+
+   spin_lock_irqsave(owner-lock, flags);
+
+   /* Every call to __sysmmu_disable() must return same result */
+   for_each_sysmmu(dev, sysmmu) {
+   struct sysmmu_drvdata *drvdata = dev_get_drvdata(sysmmu);
+   disabled = __sysmmu_disable(drvdata);
+   if (disabled)
+   drvdata-master = NULL;
+   }
 
-   for_each_sysmmu(dev, sysmmu)
-   pm_runtime_put(sysmmu);
+   spin_unlock_irqrestore(owner-lock, flags);
 
return disabled;
 }
@@ -588,7 +556,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, 
unsigned long iova)
data = dev_get_drvdata(sysmmu);
 
spin_lock_irqsave(data-lock, flags);
-   if (is_sysmmu_active(data)) {
+   if (is_sysmmu_active(data) 
+   data-runtime_active) {
int i;
for (i = 0; i  data-nsfrs; i++) {
if (sysmmu_block(data-sfrbases[i])) {
@@ -817,7 +786,7 @@ static int __init exynos_sysmmu_probe(struct 
platform_device *pdev)
data-sysmmu = dev;
spin_lock_init(data-lock);
 
-   pm_runtime_enable(dev);
+   data-runtime_active = !pm_runtime_enabled(dev);
 
platform_set_drvdata(pdev, data);
 
@@ -828,6 +797,64 @@ static 

[PATCH v5 11/14] iommu/exynos: add support for System MMU 3.2 and 3.3

2012-12-11 Thread Cho KyongHo
Since System MMU 3.2 and 3.3 have more prefetch buffers than 2, the
existing function to set prefetch buffers, exynos_sysmmu_set_prefbuf()
is not able to support them.
This commit removes exynos_sysmmu_set_prefbuf() and introduces new
interface, exynos_sysmmu_set_pbuf() that can pass information of
more buffers than 2. It is safe to remove the existing function
because there is no device driver in the kernel yet that calls the
removed function.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 370 +--
 1 file changed, 322 insertions(+), 48 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index c3c5b7b..a558c51 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -80,6 +80,14 @@
 #define CTRL_BLOCK 0x7
 #define CTRL_DISABLE   0x0
 
+#define CFG_LRU0x1
+#define CFG_QOS(n) ((n  0xF)  7)
+#define CFG_MASK   0x0150 /* Selecting bit 0-15, 20, 22 and 24 */
+#define CFG_ACGEN  (1  24) /* System MMU 3.3 only */
+#define CFG_SYSSEL (1  22) /* System MMU 3.2 only */
+#define CFG_FLPDCACHE  (1  20) /* System MMU 3.2+ only */
+#define CFG_SHAREABLE  (1  12) /* System MMU 3.x only */
+
 #define REG_MMU_CTRL   0x000
 #define REG_MMU_CFG0x004
 #define REG_MMU_STATUS 0x008
@@ -88,6 +96,10 @@
 #define REG_PT_BASE_ADDR   0x014
 #define REG_INT_STATUS 0x018
 #define REG_INT_CLEAR  0x01C
+#define REG_PB_INFO0x400
+#define REG_PB_LMM 0x404
+#define REG_PB_INDICATE0x408
+#define REG_PB_CFG 0x40C
 
 #define REG_PAGE_FAULT_ADDR0x024
 #define REG_AW_FAULT_ADDR  0x028
@@ -96,10 +108,12 @@
 
 #define REG_MMU_VERSION0x034
 
-#define REG_PB0_SADDR  0x04C
-#define REG_PB0_EADDR  0x050
-#define REG_PB1_SADDR  0x054
-#define REG_PB1_EADDR  0x058
+#define MMU_MAJ_VER(reg)   (reg  28)
+#define MMU_MIN_VER(reg)   ((reg  21)  0x7F)
+
+#define MAX_NUM_PBUF   6
+
+#define NUM_MINOR_OF_SYSMMU_V3 4
 
 static void *sysmmu_placeholder; /* Inidcate if a device is System MMU */
 
@@ -178,6 +192,19 @@ struct exynos_iommu_owner {
spinlock_t lock;/* Lock to preserve consistency of System MMU */
 };
 
+#define SYSMMU_PBUFCFG_TLB_UPDATE  (1  16)
+#define SYSMMU_PBUFCFG_ASCENDING   (1  12)
+#define SYSMMU_PBUFCFG_DSECENDING  (0  12) /* default */
+#define SYSMMU_PBUFCFG_PREFETCH(1  8)
+#define SYSMMU_PBUFCFG_WRITE   (1  4)
+#define SYSMMU_PBUFCFG_READ(0  4) /* default */
+
+struct sysmmu_prefbuf {
+   unsigned long base;
+   unsigned long size;
+   unsigned long config;
+};
+
 struct sysmmu_drvdata {
struct device *sysmmu;  /* System MMU's device descriptor */
struct device *master;  /* Client device that needs System MMU */
@@ -185,6 +212,8 @@ struct sysmmu_drvdata {
struct clk *clk;
int activations;
spinlock_t lock;
+   struct sysmmu_prefbuf pbufs[MAX_NUM_PBUF];
+   int num_pbufs;
struct iommu_domain *domain;
unsigned long pgtable;
bool runtime_active;
@@ -210,6 +239,21 @@ static bool is_sysmmu_active(struct sysmmu_drvdata *data)
return data-activations  0;
 }
 
+static unsigned int __sysmmu_version(struct sysmmu_drvdata *drvdata,
+   int idx, unsigned int *minor)
+{
+   unsigned int major;
+
+   major = readl(drvdata-sfrbases[idx] + REG_MMU_VERSION);
+
+   if (minor)
+   *minor = MMU_MIN_VER(major);
+
+   major = MMU_MAJ_VER(major);
+
+   return major;
+}
+
 static void sysmmu_unblock(void __iomem *sfrbase)
 {
__raw_writel(CTRL_ENABLE, sfrbase + REG_MMU_CTRL);
@@ -245,32 +289,235 @@ static void __sysmmu_tlb_invalidate_entry(void __iomem 
*sfrbase,
 static void __sysmmu_set_ptbase(void __iomem *sfrbase,
   unsigned long pgd)
 {
-   __raw_writel(0x1, sfrbase + REG_MMU_CFG); /* 16KB LV1, LRU */
__raw_writel(pgd, sfrbase + REG_PT_BASE_ADDR);
 
__sysmmu_tlb_invalidate(sfrbase);
 }
 
-static void __sysmmu_set_prefbuf(void __iomem *sfrbase, unsigned long base,
-   unsigned long size, int idx)
+static void __sysmmu_set_prefbuf(void __iomem *pbufbase, unsigned long base,
+   unsigned long size, int idx)
+{
+   __raw_writel(base, pbufbase + idx * 8);
+   __raw_writel(size - 1 + base,  pbufbase + 4 + idx * 8);
+}
+
+/*
+ * Offset of prefetch buffer setting registers are different
+ * between SysMMU 3.1 and 3.2. 3.3 has a single prefetch buffer setting.
+ */
+static unsigned short
+   pbuf_offset[NUM_MINOR_OF_SYSMMU_V3] = {0x04C, 0x04C, 0x070, 0x410};
+
+/**
+ * __sysmmu_sort_prefbuf - sort the given @prefbuf in descending order.
+ * @prefbuf: 

[PATCH v5 12/14] iommu/exynos: pass version information from DT

2012-12-11 Thread Cho KyongHo
System MMUs in some implementation of Exynos core does not include
correct version information in the System MMU. If the version
information is not correct, exynos-iommu driver cannot take advantages
of feature of higher versions of System MMu like prefetching page
table entries prior to TLB miss.

This commit allows passing version information from DT to the driver.
If DT does not pass version information, the driver will read the
information from System MMU.

Signed-off-by: KyongHo Cho pullip@samsung.com
---
 drivers/iommu/exynos-iommu.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index a558c51..70921e9 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -205,6 +205,12 @@ struct sysmmu_prefbuf {
unsigned long config;
 };
 
+struct sysmmu_version {
+   unsigned char major; /* major = 0 means that driver must use MMU_VERSION
+   register instead of this structure */
+   unsigned char minor;
+};
+
 struct sysmmu_drvdata {
struct device *sysmmu;  /* System MMU's device descriptor */
struct device *master;  /* Client device that needs System MMU */
@@ -214,6 +220,7 @@ struct sysmmu_drvdata {
spinlock_t lock;
struct sysmmu_prefbuf pbufs[MAX_NUM_PBUF];
int num_pbufs;
+   struct sysmmu_version ver;
struct iommu_domain *domain;
unsigned long pgtable;
bool runtime_active;
@@ -246,6 +253,20 @@ static unsigned int __sysmmu_version(struct sysmmu_drvdata 
*drvdata,
 
major = readl(drvdata-sfrbases[idx] + REG_MMU_VERSION);
 
+   if ((MMU_MAJ_VER(major) == 0) || (MMU_MAJ_VER(major)  3)) {
+   /* register MMU_VERSION is used for special purpose */
+   if (drvdata-ver.major == 0) {
+   /* min ver. is not important for System MMU 1 and 2 */
+   major = 1;
+   } else {
+   if (minor)
+   *minor = drvdata-ver.minor;
+   major = drvdata-ver.major;
+   }
+
+   return major;
+   }
+
if (minor)
*minor = MMU_MIN_VER(major);
 
@@ -933,8 +954,15 @@ static int __init __sysmmu_setup(struct device *sysmmu,
const char *compat;
struct platform_device *pmaster = NULL;
u32 master_inst_no = -1;
+   u32 ver[2];
int ret;
 
+   if (!of_property_read_u32_array(sysmmu-of_node, version, ver, 2)) {
+   drvdata-ver.major = (unsigned char)ver[0];
+   drvdata-ver.minor = (unsigned char)ver[1];
+   dev_dbg(sysmmu, Found version %d.%d\n, ver[0], ver[1]);
+   }
+
drvdata-pbufs[0].base = 0;
drvdata-pbufs[0].size = ~0;
drvdata-num_pbufs = 1;
-- 
1.8.0


--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC 01/12] s5p-csis: Add device tree support

2012-12-11 Thread Sylwester Nawrocki
Hello Grant,

On 12/11/2012 09:36 AM, Grant Likely wrote:
 On Mon, 10 Dec 2012 20:45:55 +0100, Sylwester Nawrocki 
 s.nawro...@samsung.com wrote:
 s5p-csis is platform device driver for MIPI-CSI frontend to the FIMC
 (camera host interface DMA engine and image processor). This patch
 adds support for instantiating the MIPI-CSIS devices from DT and
 parsing all SoC and board specific properties from device tree.

 Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 ---
  .../bindings/media/soc/samsung-mipi-csis.txt   |   82 +++
  drivers/media/platform/s5p-fimc/mipi-csis.c|  155 
 +++-
  drivers/media/platform/s5p-fimc/mipi-csis.h|1 +
  3 files changed, 202 insertions(+), 36 deletions(-)
  create mode 100644 
 Documentation/devicetree/bindings/media/soc/samsung-mipi-csis.txt

 diff --git 
 a/Documentation/devicetree/bindings/media/soc/samsung-mipi-csis.txt 
 b/Documentation/devicetree/bindings/media/soc/samsung-mipi-csis.txt
 new file mode 100644
 index 000..f57cbdc
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/media/soc/samsung-mipi-csis.txt
 @@ -0,0 +1,82 @@
 +Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver (MIPI CSIS)
 +-
 +
 +Required properties:
 +
 +- compatible  : samsung,s5pv210-csis for S5PV210 SoCs,
 +samsung,exynos4210-csis for Exynos4210 and later SoCs;
 +- reg : physical base address and size of the device memory 
 mapped
 +registers;
 +- interrupts  : should contain MIPI CSIS interrupt; the format of the
 +interrupt specifier depends on the interrupt controller;
 +- max-data-lanes  : maximum number of data lanes supported (SoC specific);
 +- vddio-supply: MIPI CSIS I/O and PLL voltage supply (e.g. 1.8V);
 +- vddcore-supply  : MIPI CSIS Core voltage supply (e.g. 1.1V).
 +
 +Optional properties:
 +
 +- clock-frequency : The IP's main (system bus) clock frequency in Hz, 
 default
 +value when this property is not specified is 166 MHz;
 +- samsung,csis,wclk : CSI-2 wrapper clock selection. If this property is 
 present
 +external clock from CMU will be used, if not bus clock will
 +be selected.
 +
 +The device node should contain one 'port' child node with one child 
 'endpoint'
 +node, as outlined in the common media bindings specification. See
 +Documentation/devicetree/bindings/media/v4l2.txt for details. The following 
 are
 +properties specific to those nodes. (TODO: update the file path)
 +
 +port node
 +-
 +
 +- reg : (required) must be 2 for camera C input (CSIS0) or 
 3 for
 +camera D input (CSIS1);
 
 'reg' has a very specific definition. If you're going to use a reg
 property here, then the parent nodes need to have
 #address-cells=1;#size-cells=0; properties to define the address
 specifier format.
 
 However since you're identifying port numbers that aren't really
 addresses I would suggest simply changing this property to something
 like 'port-num'.
 
 Otherwise the binding looks good.

Thank you for the review. Indeed I should have said about #address-cells,
#size-cells here. I thought using 'reg' was agreed during previous discussions
on the mailing lists (e.g. [1]), so I just carried on with 'reg'.
I should just have addressed the comments from Stephen and Rob, instead of
just resending same version of the documentation. I'll try to take care of
it in the next post. i.e. rename 'link' node to 'endpoint' and 'remote'
phandle to 'remote-endpoint'.

I'm not really sure what advantage 'reg' gives over a new property.
Would it still be OK to have port nodes names followed by indexes with
port-num instead of reg, e.g.

foo {
port@0 {
port-num = 0;
};

port@1 {
port-num = 1;
};
};
?


[1] http://www.spinics.net/lists/linux-sh/msg13383.html

--

Thanks,
Sylwester

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC 01/12] s5p-csis: Add device tree support

2012-12-11 Thread Grant Likely
On Tue, 11 Dec 2012 12:24:23 +0100, Sylwester Nawrocki s.nawro...@samsung.com 
wrote:
 Hello Grant,
 
 On 12/11/2012 09:36 AM, Grant Likely wrote:
  On Mon, 10 Dec 2012 20:45:55 +0100, Sylwester Nawrocki 
  s.nawro...@samsung.com wrote:
  s5p-csis is platform device driver for MIPI-CSI frontend to the FIMC
  (camera host interface DMA engine and image processor). This patch
  adds support for instantiating the MIPI-CSIS devices from DT and
  parsing all SoC and board specific properties from device tree.
 
  Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com
  Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
  ---
   .../bindings/media/soc/samsung-mipi-csis.txt   |   82 +++
   drivers/media/platform/s5p-fimc/mipi-csis.c|  155 
  +++-
   drivers/media/platform/s5p-fimc/mipi-csis.h|1 +
   3 files changed, 202 insertions(+), 36 deletions(-)
   create mode 100644 
  Documentation/devicetree/bindings/media/soc/samsung-mipi-csis.txt
 
  diff --git 
  a/Documentation/devicetree/bindings/media/soc/samsung-mipi-csis.txt 
  b/Documentation/devicetree/bindings/media/soc/samsung-mipi-csis.txt
  new file mode 100644
  index 000..f57cbdc
  --- /dev/null
  +++ b/Documentation/devicetree/bindings/media/soc/samsung-mipi-csis.txt
  @@ -0,0 +1,82 @@
  +Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver (MIPI CSIS)
  +-
  +
  +Required properties:
  +
  +- compatible: samsung,s5pv210-csis for S5PV210 SoCs,
  +  samsung,exynos4210-csis for Exynos4210 and later SoCs;
  +- reg   : physical base address and size of the device memory 
  mapped
  +  registers;
  +- interrupts  : should contain MIPI CSIS interrupt; the format of the
  +  interrupt specifier depends on the interrupt controller;
  +- max-data-lanes  : maximum number of data lanes supported (SoC specific);
  +- vddio-supply: MIPI CSIS I/O and PLL voltage supply (e.g. 1.8V);
  +- vddcore-supply  : MIPI CSIS Core voltage supply (e.g. 1.1V).
  +
  +Optional properties:
  +
  +- clock-frequency : The IP's main (system bus) clock frequency in Hz, 
  default
  +  value when this property is not specified is 166 MHz;
  +- samsung,csis,wclk : CSI-2 wrapper clock selection. If this property is 
  present
  +  external clock from CMU will be used, if not bus clock will
  +  be selected.
  +
  +The device node should contain one 'port' child node with one child 
  'endpoint'
  +node, as outlined in the common media bindings specification. See
  +Documentation/devicetree/bindings/media/v4l2.txt for details. The 
  following are
  +properties specific to those nodes. (TODO: update the file path)
  +
  +port node
  +-
  +
  +- reg   : (required) must be 2 for camera C input (CSIS0) or 
  3 for
  +  camera D input (CSIS1);
  
  'reg' has a very specific definition. If you're going to use a reg
  property here, then the parent nodes need to have
  #address-cells=1;#size-cells=0; properties to define the address
  specifier format.
  
  However since you're identifying port numbers that aren't really
  addresses I would suggest simply changing this property to something
  like 'port-num'.
  
  Otherwise the binding looks good.
 
 Thank you for the review. Indeed I should have said about #address-cells,
 #size-cells here. I thought using 'reg' was agreed during previous discussions
 on the mailing lists (e.g. [1]), so I just carried on with 'reg'.
 I should just have addressed the comments from Stephen and Rob, instead of
 just resending same version of the documentation. I'll try to take care of
 it in the next post. i.e. rename 'link' node to 'endpoint' and 'remote'
 phandle to 'remote-endpoint'.

Could be. I can't remember what has been discussed from one day to the
next.  :-)  If you've got #address/#size-cells in the binding, then reg is
fine. If that's what you've already got, then just leave it. As long as
the conventions are intact.

g.
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 03/19] MAINTAINERS: remove arch/arm/plat-s5p/

2012-12-11 Thread Cesar Eduardo Barros
These files were merged into plat-samsung.

Acked-by: Kukjin Kim kgene@samsung.com
Cc: Ben Dooks ben-li...@fluff.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-soc@vger.kernel.org
Signed-off-by: Cesar Eduardo Barros ces...@cesarb.net
---
 MAINTAINERS | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f4890a3..e013f00 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1074,7 +1074,6 @@ W:http://www.fluff.org/ben/linux/
 S: Maintained
 F: arch/arm/plat-samsung/
 F: arch/arm/plat-s3c24xx/
-F: arch/arm/plat-s5p/
 F: arch/arm/mach-s3c24*/
 F: arch/arm/mach-s3c64xx/
 F: drivers/*/*s3c2410*
@@ -1105,7 +1104,6 @@ M:Sylwester Nawrocki s.nawro...@samsung.com
 L: linux-arm-ker...@lists.infradead.org
 L: linux-me...@vger.kernel.org
 S: Maintained
-F: arch/arm/plat-s5p/dev-fimc*
 F: arch/arm/plat-samsung/include/plat/*fimc*
 F: drivers/media/platform/s5p-fimc/
 
@@ -1116,7 +1114,7 @@ M:Jeongtae Park jtp.p...@samsung.com
 L: linux-arm-ker...@lists.infradead.org
 L: linux-me...@vger.kernel.org
 S: Maintained
-F: arch/arm/plat-s5p/dev-mfc.c
+F: arch/arm/plat-samsung/s5p-dev-mfc.c
 F: drivers/media/platform/s5p-mfc/
 
 ARM/SAMSUNG S5P SERIES TV SUBSYSTEM SUPPORT
-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/3] add mie driver for exynos

2012-12-11 Thread Stéphane Marchesin
On Mon, Dec 10, 2012 at 1:27 AM, Inki Dae inki@samsung.com wrote:


 2012/12/10 Stéphane Marchesin stephane.marche...@gmail.com

 On Sun, Dec 9, 2012 at 10:26 PM, Inki Dae inki@samsung.com wrote:
 
 
  2012/12/6 R. Chandrasekar rcse...@samsung.com
 
  From: R. Chandrasekar rcse...@samsung.com
 
  this patch set adds the driver support for the dithering functionality
  of
  the
  mobile image enhancement (mie) module.
 
  device tree support is added for mie.
 
  fimd adds the mie module as plugin and calls the dithering function.
  dithere is
  required when the panels bpp is less then fimd output.
 
  though mie mie has other functionalities, current system uses only
  dithereing.
 
 
  Please, move mie module into drivers/video/exynos. The mie is a
  interface
  between fimd and lcd panel(or mipi-dsi, eDP) to enhance image to be
  displayed. And it seems like that this doesn't need drm
  framework-relevant
  interfaces, such as gem.

 Well, if you want to support it from the DRM, it should live in
 drivers/gpu/drm, and I don't think you should add another platform
 driver in the first place. The profusion of platform drivers in exynos
 makes it really difficult to support suspend/resume and initialization
 properly as many devices which operate separately need to sync through
 global variables.


 MIE could be used by linux framebuffer-based specific driver(s3c-fb) also.

Yes, but it is a DRM driver we're talking about here. Again it is
really difficult to work with it across suspend-resume. I don't think
the DRM was ever meant to be a collection of independent platform
drivers.

 If linux framebuffer-based driver want to use this mie module, should the
 mie module be placed in drivers/video coping it? I think it's not good so
 it's better way to use this mie module commonly without duplicated codes.
 And mipi-dsi and eDP drivers also have their own platform device/driver and
 are being used by exynos drm driver or s3c-fb driver. Of course, for some
 IPs such as mie between display controller and lcd panel, It seems like that
 there should be proper framework or interfaces in drivers/video/exynos or
 somewhere so that other frameworks can use it commonly. And drm and linux
 framebuffer drivers should call the interfaces.

For the short term, I think it's fine to duplicate the code.

For the longer term, I think framebuffer support should be provided by
the drm framebuffer compat layer, and s3c-fb should disappear. This is
what has been done with all the other DRM drivers.

Stéphane



 Thanks,
 Inki Dae

 Stéphane


 
  And also, please refer to the below link, Common Display Framework, for
  more
  generic way.
 
 
  http://lists.freedesktop.org/archives/dri-devel/2012-November/030888.html
 
  Thanks,
  Inki Dae
 
 
  R. Chandrasekar (3):
DTS: exynos: add device tree support for exynos mie
drm: fimd: add mie plugin support for dithering
drm: mie: add mie driver for exynos
 
   arch/arm/boot/dts/exynos5250.dtsi   |7 +-
   drivers/gpu/drm/exynos/Kconfig  |7 +
   drivers/gpu/drm/exynos/Makefile |1 +
   drivers/gpu/drm/exynos/exynos_drm_fimd.c|   58 +-
   drivers/gpu/drm/exynos/exynos_drm_fimd_common.h |   20 ++
   drivers/gpu/drm/exynos/exynos_drm_mie.c |  250
  +++
   drivers/gpu/drm/exynos/exynos_drm_mie.h |   50 +
   drivers/gpu/drm/exynos/exynos_regs-mie.h|   75 +++
   8 files changed, 465 insertions(+), 3 deletions(-)
   create mode 100644 drivers/gpu/drm/exynos/exynos_drm_fimd_common.h
   create mode 100644 drivers/gpu/drm/exynos/exynos_drm_mie.c
   create mode 100644 drivers/gpu/drm/exynos/exynos_drm_mie.h
   create mode 100644 drivers/gpu/drm/exynos/exynos_regs-mie.h
 
  --
  1.7.9.5
 
  ___
  dri-devel mailing list
  dri-de...@lists.freedesktop.org
  http://lists.freedesktop.org/mailman/listinfo/dri-devel
 
 
 
  ___
  dri-devel mailing list
  dri-de...@lists.freedesktop.org
  http://lists.freedesktop.org/mailman/listinfo/dri-devel
 
 ___
 dri-devel mailing list
 dri-de...@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/dri-devel


--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] regulator: s5m8767: Fix probe failure due to stack corruption

2012-12-11 Thread Inderpal Singh
The function sec_reg_read invokes regmap_read which expects unsigned int *
as the destination address. The existing driver is passing address of local
variable val which is u8. This causes the stack corruption and following
dump is observed during probe.

Hence change val from u8 to unsigned int.

Unable to handle kernel paging request at virtual address 02410020
pgd = c0004000
[02410020] *pgd=
Internal error: Oops: 8005 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0Not tainted  (3.6.0-00696-g98a28b18-dirty #27)
PC is at 0x2410020
LR is at _regulator_get_voltage+0x3c/0x70
pc : [02410020]lr : [c02395d4]psr: 2013
sp : cf839b68  ip :   fp : cf92d410
r10: cfd0  r9 : c06d9878  r8 : f0a0
r7 : cf839b70  r6 : cf92d400  r5 : 0011  r4 : cf00
r3 : 02410020  r2 :   r1 : 0048  r0 : cf00
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
...
.

[c02395d4] (_regulator_get_voltage+0x3c/0x70) from [c023ad80] 
(print_constraints+0x50/0x36c)
[c023ad80] (print_constraints+0x50/0x36c) from [c023e504] 
(set_machine_constraints+0xe8/0x2b0)
[c023e504] (set_machine_constraints+0xe8/0x2b0) from [c023e9c8] 
(regulator_register+0x2fc/0x604)
[c023e9c8] (regulator_register+0x2fc/0x604) from [c049d628] 
(s5m8767_pmic_probe+0x688/0x718)
[c049d628] (s5m8767_pmic_probe+0x688/0x718) from [c029915c] 
(platform_drv_probe+0x18/0x1c)
[c029915c] (platform_drv_probe+0x18/0x1c) from [c0297dd0] 
(really_probe+0x68/0x1f4)
[c0297dd0] (really_probe+0x68/0x1f4) from [c0298070] 
(driver_probe_device+0x30/0x48)

Signed-off-by: Inderpal Singh inderpal.si...@linaro.org
---
 drivers/regulator/s5m8767.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index 8ef5b33..9e6850f 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -214,7 +214,7 @@ static int s5m8767_reg_is_enabled(struct regulator_dev 
*rdev)
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg;
int mask = 0xc0, enable_ctrl;
-   u8 val;
+   unsigned int val;
 
ret = s5m8767_get_register(rdev, reg, enable_ctrl);
if (ret == -EINVAL)
@@ -306,7 +306,7 @@ static int s5m8767_get_voltage_sel(struct regulator_dev 
*rdev)
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int reg, mask, ret;
int reg_id = rdev_get_id(rdev);
-   u8 val;
+   unsigned int val;
 
ret = s5m8767_get_voltage_register(rdev, reg);
if (ret)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] DMA: PL330: add device tree property for DMA_MEMCPY capability

2012-12-11 Thread Jassi Brar
On Fri, Nov 30, 2012 at 4:26 PM, Bartlomiej Zolnierkiewicz
b.zolnier...@samsung.com wrote:

 Thank you for explaining it.  Here is a patch implementing the idea:

 From: Bartlomiej Zolnierkiewicz b.zolnier...@samsung.com
 Subject: [PATCH] DMA: PL330: add peripherals map to the device tree

 Add device tree (DT) property (peri-map) for storing indices
 of peripherals connected to DMAC and fix DT nodes of client
 drivers to use 'dma peripheral id' instead of 'dma request id'.
 Also instead of setting DMA_MEMCPY capability unconditionally in
 pl330_probe() do it only when peri-map DT property is present
 (idea from Jassi Brar).  It fixes the issue on ARM EXYNOS
 platforms using DT where pdma controller erroneously was used
 for DMA_MEMCPY operations instead of mdma one (it seems to work
 correctly but at the cost of worse performance).

Sorry, we need to change it as per new generic dma DT bindings
  
http://git.infradead.org/users/vkoul/slave-dma.git/blob/refs/heads/next:/Documentation/devicetree/bindings/dma/dma.txt

Thanks.
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html