[PATCH 12/16] iommu/shmobile: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/shmobile-iommu.c | 39 +++
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/shmobile-iommu.c b/drivers/iommu/shmobile-iommu.c
index f1b0077..a028751 100644
--- a/drivers/iommu/shmobile-iommu.c
+++ b/drivers/iommu/shmobile-iommu.c
@@ -42,11 +42,17 @@ struct shmobile_iommu_domain {
spinlock_t map_lock;
spinlock_t attached_list_lock;
struct list_head attached_list;
+   struct iommu_domain domain;
 };
 
 static struct shmobile_iommu_archdata *ipmmu_archdata;
 static struct kmem_cache *l1cache, *l2cache;
 
+static struct shmobile_iommu_domain *to_sh_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct shmobile_iommu_domain, domain);
+}
+
 static int pgtable_alloc(struct shmobile_iommu_domain_pgtable *pgtable,
 struct kmem_cache *cache, size_t size)
 {
@@ -82,31 +88,33 @@ static void pgtable_write(struct 
shmobile_iommu_domain_pgtable *pgtable,
   sizeof(val) * count, DMA_TO_DEVICE);
 }
 
-static int shmobile_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *shmobile_iommu_domain_alloc(unsigned type)
 {
struct shmobile_iommu_domain *sh_domain;
int i, ret;
 
-   sh_domain = kmalloc(sizeof(*sh_domain), GFP_KERNEL);
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
+   sh_domain = kzalloc(sizeof(*sh_domain), GFP_KERNEL);
if (!sh_domain)
-   return -ENOMEM;
+   return NULL;
ret = pgtable_alloc(sh_domain-l1, l1cache, L1_SIZE);
if (ret  0) {
kfree(sh_domain);
-   return ret;
+   return NULL;
}
for (i = 0; i  L1_LEN; i++)
sh_domain-l2[i].pgtable = NULL;
spin_lock_init(sh_domain-map_lock);
spin_lock_init(sh_domain-attached_list_lock);
INIT_LIST_HEAD(sh_domain-attached_list);
-   domain-priv = sh_domain;
-   return 0;
+   return sh_domain-domain;
 }
 
-static void shmobile_iommu_domain_destroy(struct iommu_domain *domain)
+static void shmobile_iommu_domain_free(struct iommu_domain *domain)
 {
-   struct shmobile_iommu_domain *sh_domain = domain-priv;
+   struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
int i;
 
for (i = 0; i  L1_LEN; i++) {
@@ -115,14 +123,13 @@ static void shmobile_iommu_domain_destroy(struct 
iommu_domain *domain)
}
pgtable_free(sh_domain-l1, l1cache, L1_SIZE);
kfree(sh_domain);
-   domain-priv = NULL;
 }
 
 static int shmobile_iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
 {
struct shmobile_iommu_archdata *archdata = dev-archdata.iommu;
-   struct shmobile_iommu_domain *sh_domain = domain-priv;
+   struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
int ret = -EBUSY;
 
if (!archdata)
@@ -151,7 +158,7 @@ static void shmobile_iommu_detach_device(struct 
iommu_domain *domain,
 struct device *dev)
 {
struct shmobile_iommu_archdata *archdata = dev-archdata.iommu;
-   struct shmobile_iommu_domain *sh_domain = domain-priv;
+   struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
 
if (!archdata)
return;
@@ -214,7 +221,7 @@ static int shmobile_iommu_map(struct iommu_domain *domain, 
unsigned long iova,
  phys_addr_t paddr, size_t size, int prot)
 {
struct shmobile_iommu_domain_pgtable l2 = { .pgtable = NULL };
-   struct shmobile_iommu_domain *sh_domain = domain-priv;
+   struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
unsigned int l1index, l2index;
int ret;
 
@@ -258,7 +265,7 @@ static size_t shmobile_iommu_unmap(struct iommu_domain 
*domain,
   unsigned long iova, size_t size)
 {
struct shmobile_iommu_domain_pgtable l2 = { .pgtable = NULL };
-   struct shmobile_iommu_domain *sh_domain = domain-priv;
+   struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
unsigned int l1index, l2index;
uint32_t l2entry = 0;
size_t ret = 0;
@@ -298,7 +305,7 @@ done:
 static phys_addr_t shmobile_iommu_iova_to_phys(struct iommu_domain *domain,
   dma_addr_t iova)
 {
-   struct shmobile_iommu_domain *sh_domain = domain-priv;
+   struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
uint32_t l1entry = 0, l2entry = 0;
unsigned int l1index, l2index;
 
@@ -355,8 +362,8 @@ static int shmobile_iommu_add_device(struct device *dev)
 }
 
 static const 

[PATCH 15/16] iommu/fsl: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/fsl_pamu_domain.c | 60 ++---
 drivers/iommu/fsl_pamu_domain.h |  2 +-
 2 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index ceebd28..1d45293 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -33,6 +33,11 @@ static struct kmem_cache *fsl_pamu_domain_cache;
 static struct kmem_cache *iommu_devinfo_cache;
 static DEFINE_SPINLOCK(device_domain_lock);
 
+static struct fsl_dma_domain *to_fsl_dma_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct fsl_dma_domain, iommu_domain);
+}
+
 static int __init iommu_init_mempool(void)
 {
fsl_pamu_domain_cache = kmem_cache_create(fsl_pamu_domain,
@@ -65,7 +70,7 @@ static phys_addr_t get_phys_addr(struct fsl_dma_domain 
*dma_domain, dma_addr_t i
struct dma_window *win_ptr = dma_domain-win_arr[0];
struct iommu_domain_geometry *geom;
 
-   geom = dma_domain-iommu_domain-geometry;
+   geom = dma_domain-iommu_domain.geometry;
 
if (!win_cnt || !dma_domain-geom_size) {
pr_debug(Number of windows/geometry not configured for the 
domain\n);
@@ -123,7 +128,7 @@ static int map_win(int liodn, struct fsl_dma_domain 
*dma_domain)
 {
int ret;
struct dma_window *wnd = dma_domain-win_arr[0];
-   phys_addr_t wnd_addr = 
dma_domain-iommu_domain-geometry.aperture_start;
+   phys_addr_t wnd_addr = dma_domain-iommu_domain.geometry.aperture_start;
unsigned long flags;
 
spin_lock_irqsave(iommu_lock, flags);
@@ -172,7 +177,7 @@ static int update_liodn(int liodn, struct fsl_dma_domain 
*dma_domain, u32 wnd_nr
} else {
phys_addr_t wnd_addr;
 
-   wnd_addr = dma_domain-iommu_domain-geometry.aperture_start;
+   wnd_addr = dma_domain-iommu_domain.geometry.aperture_start;
 
ret = pamu_config_ppaace(liodn, wnd_addr,
 wnd-size,
@@ -384,7 +389,7 @@ static void attach_device(struct fsl_dma_domain 
*dma_domain, int liodn, struct d
 static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain,
 dma_addr_t iova)
 {
-   struct fsl_dma_domain *dma_domain = domain-priv;
+   struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 
if (iova  domain-geometry.aperture_start ||
iova  domain-geometry.aperture_end)
@@ -398,11 +403,9 @@ static bool fsl_pamu_capable(enum iommu_cap cap)
return cap == IOMMU_CAP_CACHE_COHERENCY;
 }
 
-static void fsl_pamu_domain_destroy(struct iommu_domain *domain)
+static void fsl_pamu_domain_free(struct iommu_domain *domain)
 {
-   struct fsl_dma_domain *dma_domain = domain-priv;
-
-   domain-priv = NULL;
+   struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
 
/* remove all the devices from the device list */
detach_device(NULL, dma_domain);
@@ -413,23 +416,24 @@ static void fsl_pamu_domain_destroy(struct iommu_domain 
*domain)
kmem_cache_free(fsl_pamu_domain_cache, dma_domain);
 }
 
-static int fsl_pamu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *fsl_pamu_domain_alloc(unsigned type)
 {
struct fsl_dma_domain *dma_domain;
 
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
dma_domain = iommu_alloc_dma_domain();
if (!dma_domain) {
pr_debug(dma_domain allocation failed\n);
-   return -ENOMEM;
+   return NULL;
}
-   domain-priv = dma_domain;
-   dma_domain-iommu_domain = domain;
/* defaul geometry 64 GB i.e. maximum system address */
-   domain-geometry.aperture_start = 0;
-   domain-geometry.aperture_end = (1ULL  36) - 1;
-   domain-geometry.force_aperture = true;
+   dma_domain-iommu_domain. geometry.aperture_start = 0;
+   dma_domain-iommu_domain.geometry.aperture_end = (1ULL  36) - 1;
+   dma_domain-iommu_domain.geometry.force_aperture = true;
 
-   return 0;
+   return dma_domain-iommu_domain;
 }
 
 /* Configure geometry settings for all LIODNs associated with domain */
@@ -499,7 +503,7 @@ static int disable_domain_win(struct fsl_dma_domain 
*dma_domain, u32 wnd_nr)
 
 static void fsl_pamu_window_disable(struct iommu_domain *domain, u32 wnd_nr)
 {
-   struct fsl_dma_domain *dma_domain = domain-priv;
+   struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
unsigned long flags;
int ret;
 
@@ -530,7 +534,7 @@ static void fsl_pamu_window_disable(struct iommu_domain 
*domain, u32 wnd_nr)
 static int fsl_pamu_window_enable(struct iommu_domain *domain, u32 wnd_nr,
   

[PATCH 16/16] iommu: Remove domain_init and domain_free iommu_ops

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

All drivers have been converted to the new domain_alloc and
domain_free iommu-ops. So remove the old ones and get rid of
iommu_domain-priv too, as this is no longer needed when the
struct iommu_domain is embedded in the private structures of
the iommu drivers.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/iommu.c | 30 ++
 include/linux/iommu.h |  3 ---
 2 files changed, 2 insertions(+), 31 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 656b949..d4f527e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -900,51 +900,25 @@ EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
 
 struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
 {
-   const struct iommu_ops *ops;
struct iommu_domain *domain;
 
if (bus == NULL || bus-iommu_ops == NULL)
return NULL;
 
-   ops = bus-iommu_ops;
-
-   if (ops-domain_alloc)
-   domain = ops-domain_alloc(IOMMU_DOMAIN_UNMANAGED);
-   else
-   domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-
+   domain = bus-iommu_ops-domain_alloc(IOMMU_DOMAIN_UNMANAGED);
if (!domain)
return NULL;
 
domain-ops  = bus-iommu_ops;
domain-type = IOMMU_DOMAIN_UNMANAGED;
 
-   if (ops-domain_init  domain-ops-domain_init(domain))
-   goto out_free;
-
return domain;
-
-out_free:
-   if (ops-domain_free)
-   ops-domain_free(domain);
-   else
-   kfree(domain);
-
-   return NULL;
 }
 EXPORT_SYMBOL_GPL(iommu_domain_alloc);
 
 void iommu_domain_free(struct iommu_domain *domain)
 {
-   const struct iommu_ops *ops = domain-ops;
-
-   if (likely(ops-domain_destroy != NULL))
-   ops-domain_destroy(domain);
-
-   if (ops-domain_free)
-   ops-domain_free(domain);
-   else
-   kfree(domain);
+   domain-ops-domain_free(domain);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_free);
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 72d03fe..0546b87 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -78,7 +78,6 @@ struct iommu_domain_geometry {
 struct iommu_domain {
unsigned type;
const struct iommu_ops *ops;
-   void *priv;
iommu_fault_handler_t handler;
void *handler_token;
struct iommu_domain_geometry geometry;
@@ -138,8 +137,6 @@ enum iommu_attr {
  */
 struct iommu_ops {
bool (*capable)(enum iommu_cap);
-   int (*domain_init)(struct iommu_domain *domain);
-   void (*domain_destroy)(struct iommu_domain *domain);
 
/* Domain allocation and freeing by the iommu driver */
struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
-- 
1.9.1

--
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 00/16 v2] iommu: Move domain allocation into drivers

2015-03-26 Thread Joerg Roedel
Changes v1-v2:

* Rebased to v4.0-rc5
* Converted domain-types to a bit-field

Hi,

here is patch-set to replace the existing domain_init and
domain_destroy iommu-ops with the new domain_alloc and
domain_free callbacks

The new callbacks move the allocation of iommu domains into
the iommu driver, allowing them to put a generic
iommu_domain struct into their own domain struct. This makes
domain handling in the drivers more cache efficient and
prepares the introduction of default domains in another
patch-set.

While at it, this patch-set also introduces domain types.
These are internal to the iommu core code for now, there are
three of them:

* DMA-API domains
* Identity mapped domains
* Domains unmanaged by the iommu-core, used for
  iommu-api so that the users can create their own
  mappings

The patches have been compile tested for x86, ARM and PPC
and runtime tested on x86 (Intel VT-d and AMD IOMMU).

Please review.

Thanks,

Joerg

Joerg Roedel (15):
  iommu: Introduce domain_alloc and domain_free iommu_ops
  iommu: Introduce iommu domain types
  iommu/amd: Make use of domain_alloc and domain_free
  iommu/vt-d: Make use of domain_alloc and domain_free
  iommu/omap: Make use of domain_alloc and domain_free
  iommu/arm-smmu: Make use of domain_alloc and domain_free
  iommu/exynos: Make use of domain_alloc and domain_free
  iommu/tegra-smmu: Make use of domain_alloc and domain_free
  iommu/tegra-gart: Make use of domain_alloc and domain_free
  iommu/msm: Make use of domain_alloc and domain_free
  iommu/shmobile: Make use of domain_alloc and domain_free
  iommu/ipmmu-vmsa: Make use of domain_alloc and domain_free
  iommu/rockchip: Make use of domain_alloc and domain_free
  iommu/fsl: Make use of domain_alloc and domain_free
  iommu: Remove domain_init and domain_free iommu_ops

 drivers/iommu/amd_iommu.c   | 84 +--
 drivers/iommu/amd_iommu_types.h |  7 ++--
 drivers/iommu/arm-smmu.c| 46 +-
 drivers/iommu/exynos-iommu.c| 87 ++---
 drivers/iommu/fsl_pamu_domain.c | 60 +++-
 drivers/iommu/fsl_pamu_domain.h |  2 +-
 drivers/iommu/intel-iommu.c | 48 +--
 drivers/iommu/iommu.c   | 20 ++
 drivers/iommu/ipmmu-vmsa.c  | 43 +++-
 drivers/iommu/msm_iommu.c   | 73 +-
 drivers/iommu/omap-iommu.c  | 49 +--
 drivers/iommu/rockchip-iommu.c  | 40 +++
 drivers/iommu/shmobile-iommu.c  | 40 +++
 drivers/iommu/tegra-gart.c  | 67 +--
 drivers/iommu/tegra-smmu.c  | 41 ++-
 include/linux/iommu.h   | 17 ++--
 16 files changed, 407 insertions(+), 317 deletions(-)

-- 
1.8.4.5
Joerg Roedel (16):
  iommu: Introduce domain_alloc and domain_free iommu_ops
  iommu: Introduce iommu domain types
  iommu: Only allow iommu_map/unmap for paging domains
  iommu/amd: Make use of domain_alloc and domain_free
  iommu/vt-d: Make use of domain_alloc and domain_free
  iommu/omap: Make use of domain_alloc and domain_free
  iommu/arm-smmu: Make use of domain_alloc and domain_free
  iommu/exynos: Make use of domain_alloc and domain_free
  iommu/tegra-smmu: Make use of domain_alloc and domain_free
  iommu/tegra-gart: Make use of domain_alloc and domain_free
  iommu/msm: Make use of domain_alloc and domain_free
  iommu/shmobile: Make use of domain_alloc and domain_free
  iommu/ipmmu-vmsa: Make use of domain_alloc and domain_free
  iommu/rockchip: Make use of domain_alloc and domain_free
  iommu/fsl: Make use of domain_alloc and domain_free
  iommu: Remove domain_init and domain_free iommu_ops

 drivers/iommu/amd_iommu.c   | 84 +--
 drivers/iommu/amd_iommu_types.h |  7 ++--
 drivers/iommu/arm-smmu.c| 46 +-
 drivers/iommu/exynos-iommu.c| 87 ++---
 drivers/iommu/fsl_pamu_domain.c | 60 +++-
 drivers/iommu/fsl_pamu_domain.h |  2 +-
 drivers/iommu/intel-iommu.c | 48 +--
 drivers/iommu/iommu.c   | 26 +---
 drivers/iommu/ipmmu-vmsa.c  | 41 ++-
 drivers/iommu/msm_iommu.c   | 73 +-
 drivers/iommu/omap-iommu.c  | 49 +--
 drivers/iommu/rockchip-iommu.c  | 40 +++
 drivers/iommu/shmobile-iommu.c  | 39 ++
 drivers/iommu/tegra-gart.c  | 67 +--
 drivers/iommu/tegra-smmu.c  | 41 ++-
 include/linux/iommu.h   | 33 ++--
 16 files changed, 427 insertions(+), 316 deletions(-)

-- 
1.9.1

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

[PATCH 08/16] iommu/exynos: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/exynos-iommu.c | 87 
 1 file changed, 47 insertions(+), 40 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index dc14fec4..3e89850 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -200,6 +200,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 */
+   struct iommu_domain domain; /* generic domain data structure */
 };
 
 struct sysmmu_drvdata {
@@ -214,6 +215,11 @@ struct sysmmu_drvdata {
phys_addr_t pgtable;
 };
 
+static struct exynos_iommu_domain *to_exynos_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct exynos_iommu_domain, domain);
+}
+
 static bool set_sysmmu_active(struct sysmmu_drvdata *data)
 {
/* return true if the System MMU was not active previously
@@ -696,58 +702,60 @@ static inline void pgtable_flush(void *vastart, void 
*vaend)
virt_to_phys(vaend));
 }
 
-static int exynos_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
 {
-   struct exynos_iommu_domain *priv;
+   struct exynos_iommu_domain *exynos_domain;
int i;
 
-   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-   if (!priv)
-   return -ENOMEM;
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
+   exynos_domain = kzalloc(sizeof(*exynos_domain), GFP_KERNEL);
+   if (!exynos_domain)
+   return NULL;
 
-   priv-pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
-   if (!priv-pgtable)
+   exynos_domain-pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 
2);
+   if (!exynos_domain-pgtable)
goto err_pgtable;
 
-   priv-lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
-   if (!priv-lv2entcnt)
+   exynos_domain-lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | 
__GFP_ZERO, 1);
+   if (!exynos_domain-lv2entcnt)
goto err_counter;
 
/* Workaround for System MMU v3.3 to prevent caching 1MiB mapping */
for (i = 0; i  NUM_LV1ENTRIES; i += 8) {
-   priv-pgtable[i + 0] = ZERO_LV2LINK;
-   priv-pgtable[i + 1] = ZERO_LV2LINK;
-   priv-pgtable[i + 2] = ZERO_LV2LINK;
-   priv-pgtable[i + 3] = ZERO_LV2LINK;
-   priv-pgtable[i + 4] = ZERO_LV2LINK;
-   priv-pgtable[i + 5] = ZERO_LV2LINK;
-   priv-pgtable[i + 6] = ZERO_LV2LINK;
-   priv-pgtable[i + 7] = ZERO_LV2LINK;
+   exynos_domain-pgtable[i + 0] = ZERO_LV2LINK;
+   exynos_domain-pgtable[i + 1] = ZERO_LV2LINK;
+   exynos_domain-pgtable[i + 2] = ZERO_LV2LINK;
+   exynos_domain-pgtable[i + 3] = ZERO_LV2LINK;
+   exynos_domain-pgtable[i + 4] = ZERO_LV2LINK;
+   exynos_domain-pgtable[i + 5] = ZERO_LV2LINK;
+   exynos_domain-pgtable[i + 6] = ZERO_LV2LINK;
+   exynos_domain-pgtable[i + 7] = ZERO_LV2LINK;
}
 
-   pgtable_flush(priv-pgtable, priv-pgtable + NUM_LV1ENTRIES);
+   pgtable_flush(exynos_domain-pgtable, exynos_domain-pgtable + 
NUM_LV1ENTRIES);
 
-   spin_lock_init(priv-lock);
-   spin_lock_init(priv-pgtablelock);
-   INIT_LIST_HEAD(priv-clients);
+   spin_lock_init(exynos_domain-lock);
+   spin_lock_init(exynos_domain-pgtablelock);
+   INIT_LIST_HEAD(exynos_domain-clients);
 
-   domain-geometry.aperture_start = 0;
-   domain-geometry.aperture_end   = ~0UL;
-   domain-geometry.force_aperture = true;
+   exynos_domain-domain.geometry.aperture_start = 0;
+   exynos_domain-domain.geometry.aperture_end   = ~0UL;
+   exynos_domain-domain.geometry.force_aperture = true;
 
-   domain-priv = priv;
-   return 0;
+   return exynos_domain-domain;
 
 err_counter:
-   free_pages((unsigned long)priv-pgtable, 2);
+   free_pages((unsigned long)exynos_domain-pgtable, 2);
 err_pgtable:
-   kfree(priv);
-   return -ENOMEM;
+   kfree(exynos_domain);
+   return NULL;
 }
 
-static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+static void exynos_iommu_domain_free(struct iommu_domain *domain)
 {
-   struct exynos_iommu_domain *priv = domain-priv;
+   struct exynos_iommu_domain *priv = to_exynos_domain(domain);
struct exynos_iommu_owner *owner;
unsigned long flags;
int i;
@@ -773,15 +781,14 @@ static void exynos_iommu_domain_destroy(struct 
iommu_domain *domain)
 

[PATCH 02/16] iommu: Introduce iommu domain types

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

This allows to handle domains differently based on their
type in the future. An IOMMU driver can implement certain
optimizations for DMA-API domains for example.

The domain types can be extended later and some of the
existing domain attributes can be migrated to become domain
flags.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/iommu.c |  5 +++--
 include/linux/iommu.h | 27 ++-
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 11de262..4920605 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -909,14 +909,15 @@ struct iommu_domain *iommu_domain_alloc(struct bus_type 
*bus)
ops = bus-iommu_ops;
 
if (ops-domain_alloc)
-   domain = ops-domain_alloc();
+   domain = ops-domain_alloc(IOMMU_DOMAIN_UNMANAGED);
else
domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 
if (!domain)
return NULL;
 
-   domain-ops = bus-iommu_ops;
+   domain-ops  = bus-iommu_ops;
+   domain-type = IOMMU_DOMAIN_UNMANAGED;
 
if (ops-domain_init  domain-ops-domain_init(domain))
goto out_free;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 69d1d12..72d03fe 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -51,7 +51,32 @@ struct iommu_domain_geometry {
bool force_aperture;   /* DMA only allowed in mappable range? */
 };
 
+/* Domain feature flags */
+#define __IOMMU_DOMAIN_PAGING  (1U  0)  /* Support for iommu_map/unmap */
+#define __IOMMU_DOMAIN_DMA_API (1U  1)  /* Domain for use in DMA-API
+ implementation  */
+#define __IOMMU_DOMAIN_PT  (1U  2)  /* Domain is identity mapped   */
+
+/*
+ * This are the possible domain-types
+ *
+ * IOMMU_DOMAIN_BLOCKED- All DMA is blocked, can be used to isolate
+ *   devices
+ * IOMMU_DOMAIN_IDENTITY   - DMA addresses are system physical addresses
+ * IOMMU_DOMAIN_UNMANAGED  - DMA mappings managed by IOMMU-API user, used
+ *   for VMs
+ * IOMMU_DOMAIN_DMA- Internally used for DMA-API implementations.
+ *   This flag allows IOMMU drivers to implement
+ *   certain optimizations for these domains
+ */
+#define IOMMU_DOMAIN_BLOCKED   (0U)
+#define IOMMU_DOMAIN_IDENTITY  (__IOMMU_DOMAIN_PT)
+#define IOMMU_DOMAIN_UNMANAGED (__IOMMU_DOMAIN_PAGING)
+#define IOMMU_DOMAIN_DMA   (__IOMMU_DOMAIN_PAGING |\
+__IOMMU_DOMAIN_DMA_API)
+
 struct iommu_domain {
+   unsigned type;
const struct iommu_ops *ops;
void *priv;
iommu_fault_handler_t handler;
@@ -117,7 +142,7 @@ struct iommu_ops {
void (*domain_destroy)(struct iommu_domain *domain);
 
/* Domain allocation and freeing by the iommu driver */
-   struct iommu_domain *(*domain_alloc)(void);
+   struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
void (*domain_free)(struct iommu_domain *);
 
int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
-- 
1.9.1

--
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 14/16] iommu/rockchip: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/rockchip-iommu.c | 40 
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 9f74fdd..4015560 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -80,6 +80,8 @@ struct rk_iommu_domain {
u32 *dt; /* page directory table */
spinlock_t iommus_lock; /* lock for iommus list */
spinlock_t dt_lock; /* lock for modifying page directory table */
+
+   struct iommu_domain domain;
 };
 
 struct rk_iommu {
@@ -100,6 +102,11 @@ static inline void rk_table_flush(u32 *va, unsigned int 
count)
outer_flush_range(pa_start, pa_end);
 }
 
+static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct rk_iommu_domain, domain);
+}
+
 /**
  * Inspired by _wait_for in intel_drv.h
  * This is NOT safe for use in interrupt context.
@@ -503,7 +510,7 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
 static phys_addr_t rk_iommu_iova_to_phys(struct iommu_domain *domain,
 dma_addr_t iova)
 {
-   struct rk_iommu_domain *rk_domain = domain-priv;
+   struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
unsigned long flags;
phys_addr_t pt_phys, phys = 0;
u32 dte, pte;
@@ -639,7 +646,7 @@ unwind:
 static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
phys_addr_t paddr, size_t size, int prot)
 {
-   struct rk_iommu_domain *rk_domain = domain-priv;
+   struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
unsigned long flags;
dma_addr_t iova = (dma_addr_t)_iova;
u32 *page_table, *pte_addr;
@@ -670,7 +677,7 @@ static int rk_iommu_map(struct iommu_domain *domain, 
unsigned long _iova,
 static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
 size_t size)
 {
-   struct rk_iommu_domain *rk_domain = domain-priv;
+   struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
unsigned long flags;
dma_addr_t iova = (dma_addr_t)_iova;
phys_addr_t pt_phys;
@@ -726,7 +733,7 @@ static int rk_iommu_attach_device(struct iommu_domain 
*domain,
  struct device *dev)
 {
struct rk_iommu *iommu;
-   struct rk_iommu_domain *rk_domain = domain-priv;
+   struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
unsigned long flags;
int ret;
phys_addr_t dte_addr;
@@ -778,7 +785,7 @@ static void rk_iommu_detach_device(struct iommu_domain 
*domain,
   struct device *dev)
 {
struct rk_iommu *iommu;
-   struct rk_iommu_domain *rk_domain = domain-priv;
+   struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
unsigned long flags;
 
/* Allow 'virtual devices' (eg drm) to detach from domain */
@@ -804,13 +811,16 @@ static void rk_iommu_detach_device(struct iommu_domain 
*domain,
dev_info(dev, Detached from iommu domain\n);
 }
 
-static int rk_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 {
struct rk_iommu_domain *rk_domain;
 
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
rk_domain = kzalloc(sizeof(*rk_domain), GFP_KERNEL);
if (!rk_domain)
-   return -ENOMEM;
+   return NULL;
 
/*
 * rk32xx iommus use a 2 level pagetable.
@@ -827,17 +837,16 @@ static int rk_iommu_domain_init(struct iommu_domain 
*domain)
spin_lock_init(rk_domain-dt_lock);
INIT_LIST_HEAD(rk_domain-iommus);
 
-   domain-priv = rk_domain;
+   return rk_domain-domain;
 
-   return 0;
 err_dt:
kfree(rk_domain);
-   return -ENOMEM;
+   return NULL;
 }
 
-static void rk_iommu_domain_destroy(struct iommu_domain *domain)
+static void rk_iommu_domain_free(struct iommu_domain *domain)
 {
-   struct rk_iommu_domain *rk_domain = domain-priv;
+   struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
int i;
 
WARN_ON(!list_empty(rk_domain-iommus));
@@ -852,8 +861,7 @@ static void rk_iommu_domain_destroy(struct iommu_domain 
*domain)
}
 
free_page((unsigned long)rk_domain-dt);
-   kfree(domain-priv);
-   domain-priv = NULL;
+   kfree(rk_domain);
 }
 
 static bool rk_iommu_is_dev_iommu_master(struct device *dev)
@@ -952,8 +960,8 @@ static void rk_iommu_remove_device(struct device *dev)
 }
 
 static const struct iommu_ops rk_iommu_ops = {
-   .domain_init = rk_iommu_domain_init,
-   .domain_destroy = rk_iommu_domain_destroy,
+   

[PATCH 13/16] iommu/ipmmu-vmsa: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/ipmmu-vmsa.c | 41 +++--
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 10186ca..274c08d 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -38,7 +38,7 @@ struct ipmmu_vmsa_device {
 
 struct ipmmu_vmsa_domain {
struct ipmmu_vmsa_device *mmu;
-   struct iommu_domain *io_domain;
+   struct iommu_domain io_domain;
 
struct io_pgtable_cfg cfg;
struct io_pgtable_ops *iop;
@@ -56,6 +56,11 @@ struct ipmmu_vmsa_archdata {
 static DEFINE_SPINLOCK(ipmmu_devices_lock);
 static LIST_HEAD(ipmmu_devices);
 
+static struct ipmmu_vmsa_domain *to_vmsa_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct ipmmu_vmsa_domain, io_domain);
+}
+
 #define TLB_LOOP_TIMEOUT   100 /* 100us */
 
 /* 
-
@@ -428,7 +433,7 @@ static irqreturn_t ipmmu_domain_irq(struct 
ipmmu_vmsa_domain *domain)
 * TODO: We need to look up the faulty device based on the I/O VA. Use
 * the IOMMU device for now.
 */
-   if (!report_iommu_fault(domain-io_domain, mmu-dev, iova, 0))
+   if (!report_iommu_fault(domain-io_domain, mmu-dev, iova, 0))
return IRQ_HANDLED;
 
dev_err_ratelimited(mmu-dev,
@@ -448,7 +453,7 @@ static irqreturn_t ipmmu_irq(int irq, void *dev)
return IRQ_NONE;
 
io_domain = mmu-mapping-domain;
-   domain = io_domain-priv;
+   domain = to_vmsa_domain(io_domain);
 
return ipmmu_domain_irq(domain);
 }
@@ -457,25 +462,25 @@ static irqreturn_t ipmmu_irq(int irq, void *dev)
  * IOMMU Operations
  */
 
-static int ipmmu_domain_init(struct iommu_domain *io_domain)
+static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
 {
struct ipmmu_vmsa_domain *domain;
 
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
domain = kzalloc(sizeof(*domain), GFP_KERNEL);
if (!domain)
-   return -ENOMEM;
+   return NULL;
 
spin_lock_init(domain-lock);
 
-   io_domain-priv = domain;
-   domain-io_domain = io_domain;
-
-   return 0;
+   return domain-io_domain;
 }
 
-static void ipmmu_domain_destroy(struct iommu_domain *io_domain)
+static void ipmmu_domain_free(struct iommu_domain *io_domain)
 {
-   struct ipmmu_vmsa_domain *domain = io_domain-priv;
+   struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
/*
 * Free the domain resources. We assume that all devices have already
@@ -491,7 +496,7 @@ static int ipmmu_attach_device(struct iommu_domain 
*io_domain,
 {
struct ipmmu_vmsa_archdata *archdata = dev-archdata.iommu;
struct ipmmu_vmsa_device *mmu = archdata-mmu;
-   struct ipmmu_vmsa_domain *domain = io_domain-priv;
+   struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
unsigned long flags;
unsigned int i;
int ret = 0;
@@ -532,7 +537,7 @@ static void ipmmu_detach_device(struct iommu_domain 
*io_domain,
struct device *dev)
 {
struct ipmmu_vmsa_archdata *archdata = dev-archdata.iommu;
-   struct ipmmu_vmsa_domain *domain = io_domain-priv;
+   struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
unsigned int i;
 
for (i = 0; i  archdata-num_utlbs; ++i)
@@ -546,7 +551,7 @@ static void ipmmu_detach_device(struct iommu_domain 
*io_domain,
 static int ipmmu_map(struct iommu_domain *io_domain, unsigned long iova,
 phys_addr_t paddr, size_t size, int prot)
 {
-   struct ipmmu_vmsa_domain *domain = io_domain-priv;
+   struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
if (!domain)
return -ENODEV;
@@ -557,7 +562,7 @@ static int ipmmu_map(struct iommu_domain *io_domain, 
unsigned long iova,
 static size_t ipmmu_unmap(struct iommu_domain *io_domain, unsigned long iova,
  size_t size)
 {
-   struct ipmmu_vmsa_domain *domain = io_domain-priv;
+   struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
return domain-iop-unmap(domain-iop, iova, size);
 }
@@ -565,7 +570,7 @@ static size_t ipmmu_unmap(struct iommu_domain *io_domain, 
unsigned long iova,
 static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain,
  dma_addr_t iova)
 {
-   struct ipmmu_vmsa_domain *domain = io_domain-priv;
+   struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
/* TODO: Is locking needed ? */
 
@@ -737,8 +742,8 @@ static void ipmmu_remove_device(struct device *dev)
 }
 
 static 

[PATCH 10/16] iommu/tegra-gart: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/tegra-gart.c | 67 +++---
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index c48da05..fc588a1 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -63,11 +63,21 @@ struct gart_device {
struct device   *dev;
 };
 
+struct gart_domain {
+   struct iommu_domain domain; /* generic domain handle */
+   struct gart_device *gart;   /* link to gart device   */
+};
+
 static struct gart_device *gart_handle; /* unique for a system */
 
 #define GART_PTE(_pfn) \
(GART_ENTRY_PHYS_ADDR_VALID | ((_pfn)  PAGE_SHIFT))
 
+static struct gart_domain *to_gart_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct gart_domain, domain);
+}
+
 /*
  * Any interaction between any block on PPSB and a block on APB or AHB
  * must have these read-back to ensure the APB/AHB bus transaction is
@@ -156,6 +166,7 @@ static inline bool gart_iova_range_valid(struct gart_device 
*gart,
 static int gart_iommu_attach_dev(struct iommu_domain *domain,
 struct device *dev)
 {
+   struct gart_domain *gart_domain = to_gart_domain(domain);
struct gart_device *gart;
struct gart_client *client, *c;
int err = 0;
@@ -163,7 +174,7 @@ static int gart_iommu_attach_dev(struct iommu_domain 
*domain,
gart = gart_handle;
if (!gart)
return -EINVAL;
-   domain-priv = gart;
+   gart_domain-gart = gart;
 
domain-geometry.aperture_start = gart-iovmm_base;
domain-geometry.aperture_end   = gart-iovmm_base +
@@ -198,7 +209,8 @@ fail:
 static void gart_iommu_detach_dev(struct iommu_domain *domain,
  struct device *dev)
 {
-   struct gart_device *gart = domain-priv;
+   struct gart_domain *gart_domain = to_gart_domain(domain);
+   struct gart_device *gart = gart_domain-gart;
struct gart_client *c;
 
spin_lock(gart-client_lock);
@@ -216,33 +228,44 @@ out:
spin_unlock(gart-client_lock);
 }
 
-static int gart_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *gart_iommu_domain_alloc(unsigned type)
 {
-   return 0;
+   struct gart_domain *gart_domain;
+
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
+   gart_domain = kzalloc(sizeof(*gart_domain), GFP_KERNEL);
+   if (!gart_domain)
+   return NULL;
+
+   return gart_domain-domain;
 }
 
-static void gart_iommu_domain_destroy(struct iommu_domain *domain)
+static void gart_iommu_domain_free(struct iommu_domain *domain)
 {
-   struct gart_device *gart = domain-priv;
-
-   if (!gart)
-   return;
+   struct gart_domain *gart_domain = to_gart_domain(domain);
+   struct gart_device *gart = gart_domain-gart;
 
-   spin_lock(gart-client_lock);
-   if (!list_empty(gart-client)) {
-   struct gart_client *c;
+   if (gart) {
+   spin_lock(gart-client_lock);
+   if (!list_empty(gart-client)) {
+   struct gart_client *c;
 
-   list_for_each_entry(c, gart-client, list)
-   gart_iommu_detach_dev(domain, c-dev);
+   list_for_each_entry(c, gart-client, list)
+   gart_iommu_detach_dev(domain, c-dev);
+   }
+   spin_unlock(gart-client_lock);
}
-   spin_unlock(gart-client_lock);
-   domain-priv = NULL;
+
+   kfree(gart_domain);
 }
 
 static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,
  phys_addr_t pa, size_t bytes, int prot)
 {
-   struct gart_device *gart = domain-priv;
+   struct gart_domain *gart_domain = to_gart_domain(domain);
+   struct gart_device *gart = gart_domain-gart;
unsigned long flags;
unsigned long pfn;
 
@@ -265,7 +288,8 @@ static int gart_iommu_map(struct iommu_domain *domain, 
unsigned long iova,
 static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
   size_t bytes)
 {
-   struct gart_device *gart = domain-priv;
+   struct gart_domain *gart_domain = to_gart_domain(domain);
+   struct gart_device *gart = gart_domain-gart;
unsigned long flags;
 
if (!gart_iova_range_valid(gart, iova, bytes))
@@ -281,7 +305,8 @@ static size_t gart_iommu_unmap(struct iommu_domain *domain, 
unsigned long iova,
 static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain,
   dma_addr_t iova)
 {
-   struct gart_device 

[PATCH 11/16] iommu/msm: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/msm_iommu.c | 73 +++
 1 file changed, 36 insertions(+), 37 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index e1b0537..15a2063 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -52,8 +52,14 @@ DEFINE_SPINLOCK(msm_iommu_lock);
 struct msm_priv {
unsigned long *pgtable;
struct list_head list_attached;
+   struct iommu_domain domain;
 };
 
+static struct msm_priv *to_msm_priv(struct iommu_domain *dom)
+{
+   return container_of(dom, struct msm_priv, domain);
+}
+
 static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
 {
int ret;
@@ -79,7 +85,7 @@ static void __disable_clocks(struct msm_iommu_drvdata 
*drvdata)
 
 static int __flush_iotlb(struct iommu_domain *domain)
 {
-   struct msm_priv *priv = domain-priv;
+   struct msm_priv *priv = to_msm_priv(domain);
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
int ret = 0;
@@ -209,10 +215,14 @@ static void __program_context(void __iomem *base, int 
ctx, phys_addr_t pgtable)
SET_M(base, ctx, 1);
 }
 
-static int msm_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *msm_iommu_domain_alloc(unsigned type)
 {
-   struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+   struct msm_priv *priv;
 
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
+   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
goto fail_nomem;
 
@@ -224,20 +234,19 @@ static int msm_iommu_domain_init(struct iommu_domain 
*domain)
goto fail_nomem;
 
memset(priv-pgtable, 0, SZ_16K);
-   domain-priv = priv;
 
-   domain-geometry.aperture_start = 0;
-   domain-geometry.aperture_end   = (1ULL  32) - 1;
-   domain-geometry.force_aperture = true;
+   priv-domain.geometry.aperture_start = 0;
+   priv-domain.geometry.aperture_end   = (1ULL  32) - 1;
+   priv-domain.geometry.force_aperture = true;
 
-   return 0;
+   return priv-domain;
 
 fail_nomem:
kfree(priv);
-   return -ENOMEM;
+   return NULL;
 }
 
-static void msm_iommu_domain_destroy(struct iommu_domain *domain)
+static void msm_iommu_domain_free(struct iommu_domain *domain)
 {
struct msm_priv *priv;
unsigned long flags;
@@ -245,20 +254,17 @@ static void msm_iommu_domain_destroy(struct iommu_domain 
*domain)
int i;
 
spin_lock_irqsave(msm_iommu_lock, flags);
-   priv = domain-priv;
-   domain-priv = NULL;
+   priv = to_msm_priv(domain);
 
-   if (priv) {
-   fl_table = priv-pgtable;
+   fl_table = priv-pgtable;
 
-   for (i = 0; i  NUM_FL_PTE; i++)
-   if ((fl_table[i]  0x03) == FL_TYPE_TABLE)
-   free_page((unsigned long) __va(((fl_table[i]) 
-   FL_BASE_MASK)));
+   for (i = 0; i  NUM_FL_PTE; i++)
+   if ((fl_table[i]  0x03) == FL_TYPE_TABLE)
+   free_page((unsigned long) __va(((fl_table[i]) 
+   FL_BASE_MASK)));
 
-   free_pages((unsigned long)priv-pgtable, get_order(SZ_16K));
-   priv-pgtable = NULL;
-   }
+   free_pages((unsigned long)priv-pgtable, get_order(SZ_16K));
+   priv-pgtable = NULL;
 
kfree(priv);
spin_unlock_irqrestore(msm_iommu_lock, flags);
@@ -276,9 +282,9 @@ static int msm_iommu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
 
spin_lock_irqsave(msm_iommu_lock, flags);
 
-   priv = domain-priv;
+   priv = to_msm_priv(domain);
 
-   if (!priv || !dev) {
+   if (!dev) {
ret = -EINVAL;
goto fail;
}
@@ -330,9 +336,9 @@ static void msm_iommu_detach_dev(struct iommu_domain 
*domain,
int ret;
 
spin_lock_irqsave(msm_iommu_lock, flags);
-   priv = domain-priv;
+   priv = to_msm_priv(domain);
 
-   if (!priv || !dev)
+   if (!dev)
goto fail;
 
iommu_drvdata = dev_get_drvdata(dev-parent);
@@ -382,11 +388,7 @@ static int msm_iommu_map(struct iommu_domain *domain, 
unsigned long va,
goto fail;
}
 
-   priv = domain-priv;
-   if (!priv) {
-   ret = -EINVAL;
-   goto fail;
-   }
+   priv = to_msm_priv(domain);
 
fl_table = priv-pgtable;
 
@@ -484,10 +486,7 @@ static size_t msm_iommu_unmap(struct iommu_domain *domain, 
unsigned long va,
 
spin_lock_irqsave(msm_iommu_lock, flags);
 
-   priv = domain-priv;
-
-   if (!priv)
-  

[PATCH 03/16] iommu: Only allow iommu_map/unmap for paging domains

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Check for the new __IOMMU_DOMAIN_PAGING flag before calling
into the iommu drivers -map and -unmap call-backs.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/iommu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 4920605..656b949 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1063,6 +1063,9 @@ int iommu_map(struct iommu_domain *domain, unsigned long 
iova,
 domain-ops-pgsize_bitmap == 0UL))
return -ENODEV;
 
+   if (unlikely(!(domain-type  __IOMMU_DOMAIN_PAGING)))
+   return -EINVAL;
+
/* find out the minimum page size supported */
min_pagesz = 1  __ffs(domain-ops-pgsize_bitmap);
 
@@ -1114,6 +1117,9 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned 
long iova, size_t size)
 domain-ops-pgsize_bitmap == 0UL))
return -ENODEV;
 
+   if (unlikely(!(domain-type  __IOMMU_DOMAIN_PAGING)))
+   return -EINVAL;
+
/* find out the minimum page size supported */
min_pagesz = 1  __ffs(domain-ops-pgsize_bitmap);
 
-- 
1.9.1

--
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 07/16] iommu/arm-smmu: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/arm-smmu.c | 46 +++---
 1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fc13dd5..5575c3d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -343,6 +343,7 @@ struct arm_smmu_domain {
struct arm_smmu_cfg cfg;
enum arm_smmu_domain_stage  stage;
struct mutexinit_mutex; /* Protects smmu pointer */
+   struct iommu_domain domain;
 };
 
 static struct iommu_ops arm_smmu_ops;
@@ -360,6 +361,11 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct arm_smmu_domain, domain);
+}
+
 static void parse_driver_options(struct arm_smmu_device *smmu)
 {
int i = 0;
@@ -645,7 +651,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void 
*dev)
u32 fsr, far, fsynr, resume;
unsigned long iova;
struct iommu_domain *domain = dev;
-   struct arm_smmu_domain *smmu_domain = domain-priv;
+   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_cfg *cfg = smmu_domain-cfg;
struct arm_smmu_device *smmu = smmu_domain-smmu;
void __iomem *cb_base;
@@ -836,7 +842,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain 
*domain,
struct io_pgtable_ops *pgtbl_ops;
struct io_pgtable_cfg pgtbl_cfg;
enum io_pgtable_fmt fmt;
-   struct arm_smmu_domain *smmu_domain = domain-priv;
+   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_cfg *cfg = smmu_domain-cfg;
 
mutex_lock(smmu_domain-init_mutex);
@@ -958,7 +964,7 @@ out_unlock:
 
 static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
 {
-   struct arm_smmu_domain *smmu_domain = domain-priv;
+   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_device *smmu = smmu_domain-smmu;
struct arm_smmu_cfg *cfg = smmu_domain-cfg;
void __iomem *cb_base;
@@ -985,10 +991,12 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
__arm_smmu_free_bitmap(smmu-context_map, cfg-cbndx);
 }
 
-static int arm_smmu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 {
struct arm_smmu_domain *smmu_domain;
 
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
/*
 * Allocate the domain and initialise some of its data structures.
 * We can't really do anything meaningful until we've added a
@@ -996,17 +1004,17 @@ static int arm_smmu_domain_init(struct iommu_domain 
*domain)
 */
smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL);
if (!smmu_domain)
-   return -ENOMEM;
+   return NULL;
 
mutex_init(smmu_domain-init_mutex);
spin_lock_init(smmu_domain-pgtbl_lock);
-   domain-priv = smmu_domain;
-   return 0;
+
+   return smmu_domain-domain;
 }
 
-static void arm_smmu_domain_destroy(struct iommu_domain *domain)
+static void arm_smmu_domain_free(struct iommu_domain *domain)
 {
-   struct arm_smmu_domain *smmu_domain = domain-priv;
+   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 
/*
 * Free the domain resources. We assume that all devices have
@@ -1143,7 +1151,7 @@ static void arm_smmu_domain_remove_master(struct 
arm_smmu_domain *smmu_domain,
 static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
int ret;
-   struct arm_smmu_domain *smmu_domain = domain-priv;
+   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_device *smmu;
struct arm_smmu_master_cfg *cfg;
 
@@ -1187,7 +1195,7 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
 
 static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device 
*dev)
 {
-   struct arm_smmu_domain *smmu_domain = domain-priv;
+   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_master_cfg *cfg;
 
cfg = find_smmu_master_cfg(dev);
@@ -1203,7 +1211,7 @@ static int arm_smmu_map(struct iommu_domain *domain, 
unsigned long iova,
 {
int ret;
unsigned long flags;
-   struct arm_smmu_domain *smmu_domain = domain-priv;
+   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct io_pgtable_ops *ops= smmu_domain-pgtbl_ops;
 
if (!ops)
@@ -1220,7 +1228,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, 

[PATCH 09/16] iommu/tegra-smmu: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement domain_alloc and domain_free iommu-ops as a
replacement for domain_init/domain_destroy.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/tegra-smmu.c | 41 +++--
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 6e134c7..7208297 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -31,7 +31,7 @@ struct tegra_smmu {
 };
 
 struct tegra_smmu_as {
-   struct iommu_domain *domain;
+   struct iommu_domain domain;
struct tegra_smmu *smmu;
unsigned int use_count;
struct page *count;
@@ -40,6 +40,11 @@ struct tegra_smmu_as {
u32 attr;
 };
 
+static struct tegra_smmu_as *to_smmu_as(struct iommu_domain *dom)
+{
+   return container_of(dom, struct tegra_smmu_as, domain);
+}
+
 static inline void smmu_writel(struct tegra_smmu *smmu, u32 value,
   unsigned long offset)
 {
@@ -224,30 +229,32 @@ static bool tegra_smmu_capable(enum iommu_cap cap)
return false;
 }
 
-static int tegra_smmu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
 {
struct tegra_smmu_as *as;
unsigned int i;
uint32_t *pd;
 
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
as = kzalloc(sizeof(*as), GFP_KERNEL);
if (!as)
-   return -ENOMEM;
+   return NULL;
 
as-attr = SMMU_PD_READABLE | SMMU_PD_WRITABLE | SMMU_PD_NONSECURE;
-   as-domain = domain;
 
as-pd = alloc_page(GFP_KERNEL | __GFP_DMA);
if (!as-pd) {
kfree(as);
-   return -ENOMEM;
+   return NULL;
}
 
as-count = alloc_page(GFP_KERNEL);
if (!as-count) {
__free_page(as-pd);
kfree(as);
-   return -ENOMEM;
+   return NULL;
}
 
/* clear PDEs */
@@ -264,14 +271,12 @@ static int tegra_smmu_domain_init(struct iommu_domain 
*domain)
for (i = 0; i  SMMU_NUM_PDE; i++)
pd[i] = 0;
 
-   domain-priv = as;
-
-   return 0;
+   return as-domain;
 }
 
-static void tegra_smmu_domain_destroy(struct iommu_domain *domain)
+static void tegra_smmu_domain_free(struct iommu_domain *domain)
 {
-   struct tegra_smmu_as *as = domain-priv;
+   struct tegra_smmu_as *as = to_smmu_as(domain);
 
/* TODO: free page directory and page tables */
ClearPageReserved(as-pd);
@@ -395,7 +400,7 @@ static int tegra_smmu_attach_dev(struct iommu_domain 
*domain,
 struct device *dev)
 {
struct tegra_smmu *smmu = dev-archdata.iommu;
-   struct tegra_smmu_as *as = domain-priv;
+   struct tegra_smmu_as *as = to_smmu_as(domain);
struct device_node *np = dev-of_node;
struct of_phandle_args args;
unsigned int index = 0;
@@ -428,7 +433,7 @@ static int tegra_smmu_attach_dev(struct iommu_domain 
*domain,
 
 static void tegra_smmu_detach_dev(struct iommu_domain *domain, struct device 
*dev)
 {
-   struct tegra_smmu_as *as = domain-priv;
+   struct tegra_smmu_as *as = to_smmu_as(domain);
struct device_node *np = dev-of_node;
struct tegra_smmu *smmu = as-smmu;
struct of_phandle_args args;
@@ -524,7 +529,7 @@ static void as_put_pte(struct tegra_smmu_as *as, dma_addr_t 
iova)
 static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
  phys_addr_t paddr, size_t size, int prot)
 {
-   struct tegra_smmu_as *as = domain-priv;
+   struct tegra_smmu_as *as = to_smmu_as(domain);
struct tegra_smmu *smmu = as-smmu;
unsigned long offset;
struct page *page;
@@ -548,7 +553,7 @@ static int tegra_smmu_map(struct iommu_domain *domain, 
unsigned long iova,
 static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
   size_t size)
 {
-   struct tegra_smmu_as *as = domain-priv;
+   struct tegra_smmu_as *as = to_smmu_as(domain);
struct tegra_smmu *smmu = as-smmu;
unsigned long offset;
struct page *page;
@@ -572,7 +577,7 @@ static size_t tegra_smmu_unmap(struct iommu_domain *domain, 
unsigned long iova,
 static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain,
   dma_addr_t iova)
 {
-   struct tegra_smmu_as *as = domain-priv;
+   struct tegra_smmu_as *as = to_smmu_as(domain);
struct page *page;
unsigned long pfn;
u32 *pte;
@@ -633,8 +638,8 @@ static void tegra_smmu_remove_device(struct device *dev)
 
 static const struct iommu_ops tegra_smmu_ops = {
.capable = tegra_smmu_capable,
-   .domain_init = tegra_smmu_domain_init,
-   .domain_destroy = tegra_smmu_domain_destroy,
+   

[PATCH 05/16] iommu/vt-d: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Get rid of domain_init and domain_destroy and implement
domain_alloc/domain_free instead.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/intel-iommu.c | 48 ++---
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index ae4c1a8..a312e49 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -339,7 +339,7 @@ struct dmar_domain {
DECLARE_BITMAP(iommu_bmp, DMAR_UNITS_SUPPORTED);
/* bitmap of iommus this domain uses*/
 
-   struct list_head devices;   /* all devices' list */
+   struct list_head devices;   /* all devices' list */
struct iova_domain iovad;   /* iova's that belong to this domain */
 
struct dma_pte  *pgd;   /* virtual address */
@@ -358,6 +358,9 @@ struct dmar_domain {
   2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
spinlock_t  iommu_lock; /* protect iommu set in domain */
u64 max_addr;   /* maximum mapped address */
+
+   struct iommu_domain domain; /* generic domain data structure for
+  iommu core */
 };
 
 /* PCI domain-device relationship */
@@ -449,6 +452,12 @@ static LIST_HEAD(device_domain_list);
 
 static const struct iommu_ops intel_iommu_ops;
 
+/* Convert generic 'struct iommu_domain to private struct dmar_domain */
+static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct dmar_domain, domain);
+}
+
 static int __init intel_iommu_setup(char *str)
 {
if (!str)
@@ -4340,44 +4349,45 @@ static int md_domain_init(struct dmar_domain *domain, 
int guest_width)
return 0;
 }
 
-static int intel_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 {
struct dmar_domain *dmar_domain;
+   struct iommu_domain *domain;
+
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
 
dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
if (!dmar_domain) {
printk(KERN_ERR
intel_iommu_domain_init: dmar_domain == NULL\n);
-   return -ENOMEM;
+   return NULL;
}
if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
printk(KERN_ERR
intel_iommu_domain_init() failed\n);
domain_exit(dmar_domain);
-   return -ENOMEM;
+   return NULL;
}
domain_update_iommu_cap(dmar_domain);
-   domain-priv = dmar_domain;
 
+   domain = dmar_domain-domain;
domain-geometry.aperture_start = 0;
domain-geometry.aperture_end   = __DOMAIN_MAX_ADDR(dmar_domain-gaw);
domain-geometry.force_aperture = true;
 
-   return 0;
+   return domain;
 }
 
-static void intel_iommu_domain_destroy(struct iommu_domain *domain)
+static void intel_iommu_domain_free(struct iommu_domain *domain)
 {
-   struct dmar_domain *dmar_domain = domain-priv;
-
-   domain-priv = NULL;
-   domain_exit(dmar_domain);
+   domain_exit(to_dmar_domain(domain));
 }
 
 static int intel_iommu_attach_device(struct iommu_domain *domain,
 struct device *dev)
 {
-   struct dmar_domain *dmar_domain = domain-priv;
+   struct dmar_domain *dmar_domain = to_dmar_domain(domain);
struct intel_iommu *iommu;
int addr_width;
u8 bus, devfn;
@@ -4442,16 +4452,14 @@ static int intel_iommu_attach_device(struct 
iommu_domain *domain,
 static void intel_iommu_detach_device(struct iommu_domain *domain,
  struct device *dev)
 {
-   struct dmar_domain *dmar_domain = domain-priv;
-
-   domain_remove_one_dev_info(dmar_domain, dev);
+   domain_remove_one_dev_info(to_dmar_domain(domain), dev);
 }
 
 static int intel_iommu_map(struct iommu_domain *domain,
   unsigned long iova, phys_addr_t hpa,
   size_t size, int iommu_prot)
 {
-   struct dmar_domain *dmar_domain = domain-priv;
+   struct dmar_domain *dmar_domain = to_dmar_domain(domain);
u64 max_addr;
int prot = 0;
int ret;
@@ -4488,7 +4496,7 @@ static int intel_iommu_map(struct iommu_domain *domain,
 static size_t intel_iommu_unmap(struct iommu_domain *domain,
unsigned long iova, size_t size)
 {
-   struct dmar_domain *dmar_domain = domain-priv;
+   struct dmar_domain *dmar_domain = to_dmar_domain(domain);
struct page *freelist = NULL;
struct intel_iommu *iommu;
unsigned long start_pfn, last_pfn;
@@ -4536,7 +4544,7 @@ static size_t intel_iommu_unmap(struct iommu_domain 
*domain,
 static 

[PATCH 04/16] iommu/amd: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement the new iommu-ops function pointers and remove the
obsolete domain_init and domain_destroy functions.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/amd_iommu.c   | 84 ++---
 drivers/iommu/amd_iommu_types.h |  7 ++--
 2 files changed, 48 insertions(+), 43 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 48882c1..e8c412d 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -126,6 +126,11 @@ static int __init alloc_passthrough_domain(void);
  *
  /
 
+static struct protection_domain *to_pdomain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct protection_domain, domain);
+}
+
 static struct iommu_dev_data *alloc_dev_data(u16 devid)
 {
struct iommu_dev_data *dev_data;
@@ -3236,42 +3241,45 @@ static int __init alloc_passthrough_domain(void)
 
return 0;
 }
-static int amd_iommu_domain_init(struct iommu_domain *dom)
+
+static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
 {
-   struct protection_domain *domain;
+   struct protection_domain *pdomain;
 
-   domain = protection_domain_alloc();
-   if (!domain)
-   goto out_free;
+   /* We only support unmanaged domains for now */
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
 
-   domain-mode= PAGE_MODE_3_LEVEL;
-   domain-pt_root = (void *)get_zeroed_page(GFP_KERNEL);
-   if (!domain-pt_root)
+   pdomain = protection_domain_alloc();
+   if (!pdomain)
goto out_free;
 
-   domain-iommu_domain = dom;
-
-   dom-priv = domain;
+   pdomain-mode= PAGE_MODE_3_LEVEL;
+   pdomain-pt_root = (void *)get_zeroed_page(GFP_KERNEL);
+   if (!pdomain-pt_root)
+   goto out_free;
 
-   dom-geometry.aperture_start = 0;
-   dom-geometry.aperture_end   = ~0ULL;
-   dom-geometry.force_aperture = true;
+   pdomain-domain.geometry.aperture_start = 0;
+   pdomain-domain.geometry.aperture_end   = ~0ULL;
+   pdomain-domain.geometry.force_aperture = true;
 
-   return 0;
+   return pdomain-domain;
 
 out_free:
-   protection_domain_free(domain);
+   protection_domain_free(pdomain);
 
-   return -ENOMEM;
+   return NULL;
 }
 
-static void amd_iommu_domain_destroy(struct iommu_domain *dom)
+static void amd_iommu_domain_free(struct iommu_domain *dom)
 {
-   struct protection_domain *domain = dom-priv;
+   struct protection_domain *domain;
 
-   if (!domain)
+   if (!dom)
return;
 
+   domain = to_pdomain(dom);
+
if (domain-dev_cnt  0)
cleanup_domain(domain);
 
@@ -3284,8 +3292,6 @@ static void amd_iommu_domain_destroy(struct iommu_domain 
*dom)
free_gcr3_table(domain);
 
protection_domain_free(domain);
-
-   dom-priv = NULL;
 }
 
 static void amd_iommu_detach_device(struct iommu_domain *dom,
@@ -3313,7 +3319,7 @@ static void amd_iommu_detach_device(struct iommu_domain 
*dom,
 static int amd_iommu_attach_device(struct iommu_domain *dom,
   struct device *dev)
 {
-   struct protection_domain *domain = dom-priv;
+   struct protection_domain *domain = to_pdomain(dom);
struct iommu_dev_data *dev_data;
struct amd_iommu *iommu;
int ret;
@@ -3340,7 +3346,7 @@ static int amd_iommu_attach_device(struct iommu_domain 
*dom,
 static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
 phys_addr_t paddr, size_t page_size, int iommu_prot)
 {
-   struct protection_domain *domain = dom-priv;
+   struct protection_domain *domain = to_pdomain(dom);
int prot = 0;
int ret;
 
@@ -3362,7 +3368,7 @@ static int amd_iommu_map(struct iommu_domain *dom, 
unsigned long iova,
 static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
   size_t page_size)
 {
-   struct protection_domain *domain = dom-priv;
+   struct protection_domain *domain = to_pdomain(dom);
size_t unmap_size;
 
if (domain-mode == PAGE_MODE_NONE)
@@ -3380,7 +3386,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, 
unsigned long iova,
 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
  dma_addr_t iova)
 {
-   struct protection_domain *domain = dom-priv;
+   struct protection_domain *domain = to_pdomain(dom);
unsigned long offset_mask;
phys_addr_t paddr;
u64 *pte, __pte;
@@ -3420,8 +3426,8 @@ static bool amd_iommu_capable(enum iommu_cap cap)
 
 static const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
-   .domain_init = amd_iommu_domain_init,
-   .domain_destroy = amd_iommu_domain_destroy,
+ 

[PATCH 01/16] iommu: Introduce domain_alloc and domain_free iommu_ops

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

These new call-backs defer the allocation and destruction of
'struct iommu_domain' to the iommu driver. This allows
drivers to embed this struct into their private domain
structures and to get rid of the domain_init and
domain_destroy call-backs when all drivers have been
converted.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/iommu.c | 29 +
 include/linux/iommu.h |  5 +
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 72e683d..11de262 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -900,26 +900,34 @@ EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
 
 struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
 {
+   const struct iommu_ops *ops;
struct iommu_domain *domain;
-   int ret;
 
if (bus == NULL || bus-iommu_ops == NULL)
return NULL;
 
-   domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+   ops = bus-iommu_ops;
+
+   if (ops-domain_alloc)
+   domain = ops-domain_alloc();
+   else
+   domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+
if (!domain)
return NULL;
 
domain-ops = bus-iommu_ops;
 
-   ret = domain-ops-domain_init(domain);
-   if (ret)
+   if (ops-domain_init  domain-ops-domain_init(domain))
goto out_free;
 
return domain;
 
 out_free:
-   kfree(domain);
+   if (ops-domain_free)
+   ops-domain_free(domain);
+   else
+   kfree(domain);
 
return NULL;
 }
@@ -927,10 +935,15 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
 
 void iommu_domain_free(struct iommu_domain *domain)
 {
-   if (likely(domain-ops-domain_destroy != NULL))
-   domain-ops-domain_destroy(domain);
+   const struct iommu_ops *ops = domain-ops;
 
-   kfree(domain);
+   if (likely(ops-domain_destroy != NULL))
+   ops-domain_destroy(domain);
+
+   if (ops-domain_free)
+   ops-domain_free(domain);
+   else
+   kfree(domain);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_free);
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 38daa45..69d1d12 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -115,6 +115,11 @@ struct iommu_ops {
bool (*capable)(enum iommu_cap);
int (*domain_init)(struct iommu_domain *domain);
void (*domain_destroy)(struct iommu_domain *domain);
+
+   /* Domain allocation and freeing by the iommu driver */
+   struct iommu_domain *(*domain_alloc)(void);
+   void (*domain_free)(struct iommu_domain *);
+
int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
int (*map)(struct iommu_domain *domain, unsigned long iova,
-- 
1.9.1

--
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 06/16] iommu/omap: Make use of domain_alloc and domain_free

2015-03-26 Thread Joerg Roedel
From: Joerg Roedel jroe...@suse.de

Implement the new domain_alloc and domain_free call-backs
and remove the old domain_init/destroy ones.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
 drivers/iommu/omap-iommu.c | 49 +++---
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index a4ba851..a22c33d 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -59,6 +59,7 @@ struct omap_iommu_domain {
struct omap_iommu *iommu_dev;
struct device *dev;
spinlock_t lock;
+   struct iommu_domain domain;
 };
 
 #define MMU_LOCK_BASE_SHIFT10
@@ -80,6 +81,15 @@ static struct platform_driver omap_iommu_driver;
 static struct kmem_cache *iopte_cachep;
 
 /**
+ * to_omap_domain - Get struct omap_iommu_domain from generic iommu_domain
+ * @dom:   generic iommu domain handle
+ **/
+static struct omap_iommu_domain *to_omap_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct omap_iommu_domain, domain);
+}
+
+/**
  * omap_iommu_save_ctx - Save registers for pm off-mode support
  * @dev:   client device
  **/
@@ -901,7 +911,7 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
u32 *iopgd, *iopte;
struct omap_iommu *obj = data;
struct iommu_domain *domain = obj-domain;
-   struct omap_iommu_domain *omap_domain = domain-priv;
+   struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 
if (!omap_domain-iommu_dev)
return IRQ_NONE;
@@ -1113,7 +1123,7 @@ static u32 iotlb_init_entry(struct iotlb_entry *e, u32 
da, u32 pa, int pgsz)
 static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
 phys_addr_t pa, size_t bytes, int prot)
 {
-   struct omap_iommu_domain *omap_domain = domain-priv;
+   struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
struct omap_iommu *oiommu = omap_domain-iommu_dev;
struct device *dev = oiommu-dev;
struct iotlb_entry e;
@@ -1140,7 +1150,7 @@ static int omap_iommu_map(struct iommu_domain *domain, 
unsigned long da,
 static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,
size_t size)
 {
-   struct omap_iommu_domain *omap_domain = domain-priv;
+   struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
struct omap_iommu *oiommu = omap_domain-iommu_dev;
struct device *dev = oiommu-dev;
 
@@ -1152,7 +1162,7 @@ static size_t omap_iommu_unmap(struct iommu_domain 
*domain, unsigned long da,
 static int
 omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
-   struct omap_iommu_domain *omap_domain = domain-priv;
+   struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
struct omap_iommu *oiommu;
struct omap_iommu_arch_data *arch_data = dev-archdata.iommu;
int ret = 0;
@@ -1212,17 +1222,20 @@ static void _omap_iommu_detach_dev(struct 
omap_iommu_domain *omap_domain,
 static void omap_iommu_detach_dev(struct iommu_domain *domain,
 struct device *dev)
 {
-   struct omap_iommu_domain *omap_domain = domain-priv;
+   struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 
spin_lock(omap_domain-lock);
_omap_iommu_detach_dev(omap_domain, dev);
spin_unlock(omap_domain-lock);
 }
 
-static int omap_iommu_domain_init(struct iommu_domain *domain)
+static struct iommu_domain *omap_iommu_domain_alloc(unsigned type)
 {
struct omap_iommu_domain *omap_domain;
 
+   if (type != IOMMU_DOMAIN_UNMANAGED)
+   return NULL;
+
omap_domain = kzalloc(sizeof(*omap_domain), GFP_KERNEL);
if (!omap_domain) {
pr_err(kzalloc failed\n);
@@ -1244,25 +1257,21 @@ static int omap_iommu_domain_init(struct iommu_domain 
*domain)
clean_dcache_area(omap_domain-pgtable, IOPGD_TABLE_SIZE);
spin_lock_init(omap_domain-lock);
 
-   domain-priv = omap_domain;
+   omap_domain-domain.geometry.aperture_start = 0;
+   omap_domain-domain.geometry.aperture_end   = (1ULL  32) - 1;
+   omap_domain-domain.geometry.force_aperture = true;
 
-   domain-geometry.aperture_start = 0;
-   domain-geometry.aperture_end   = (1ULL  32) - 1;
-   domain-geometry.force_aperture = true;
-
-   return 0;
+   return omap_domain-domain;
 
 fail_nomem:
kfree(omap_domain);
 out:
-   return -ENOMEM;
+   return NULL;
 }
 
-static void omap_iommu_domain_destroy(struct iommu_domain *domain)
+static void omap_iommu_domain_free(struct iommu_domain *domain)
 {
-   struct omap_iommu_domain *omap_domain = domain-priv;
-
-   domain-priv = NULL;
+   struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
 
/*
 * An iommu device is still attached
@@ -1278,7 +1287,7 @@ static void 

Re: [PATCH 02/16] iommu: Introduce iommu domain types

2015-03-26 Thread Swapna Nannapaneni
X

Sent from my BlackBerry 10 smartphone on the TELUS network.
  Original Message  
From: Joerg Roedel
Sentuv: Thursday, March 26, 2015 8:51 AM
To: io...@lists.linux-foundation.org
Cc: Will Deacon; Kukjin Kim; David Woodhouse; Heiko Stuebner; Hiroshi Doyu; 
Stephen Warren; Thierry Reding; Alexandre Courbot; Alex Williamson; Arnd 
Bergmann; Yingjoe Chen; linux-ker...@vger.kernel.org; 
linux-arm-ker...@lists.infradead.org; linux-samsung-soc@vger.kernel.org; 
linux-rockc...@lists.infradead.org; linux-te...@vger.kernel.org; Joerg Roedel; 
jroe...@suse.de
Subject: [PATCH 02/16] iommu: Introduce iommu domain types

From: Joerg Roedel jroe...@suse.de

This allows to handle domains differently based on their
type in the future. An IOMMU driver can implement certain
optimizations for DMA-API domains for example.

The domain types can be extended later and some of the
existing domain attributes can be migrated to become domain
flags.

Signed-off-by: Joerg Roedel jroe...@suse.de
---
drivers/iommu/iommu.c | 5 +++--
include/linux/iommu.h | 27 ++-
2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 11de262..4920605 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -909,14 +909,15 @@ struct iommu_domain *iommu_domain_alloc(struct bus_type 
*bus)
ops = bus-iommu_ops;

if (ops-domain_alloc)
-domain = ops-domain_alloc();
+domain = ops-domain_alloc(IOMMU_DOMAIN_UNMANAGED);
else
domain = kzalloc(sizeof(*domain), GFP_KERNEL);

if (!domain)
return NULL;

-   domain-ops = bus-iommu_ops;
+   domain-ops = bus-iommu_ops;
+   domain-type = IOMMU_DOMAIN_UNMANAGED;

if (ops-domain_init  domain-ops-domain_init(domain))
goto out_free;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 69d1d12..72d03fe 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -51,7 +51,32 @@ struct iommu_domain_geometry {
bool force_aperture; /* DMA only allowed in mappable range? */
};

+/* Domain feature flags */
+#define __IOMMU_DOMAIN_PAGING  (1U  0) /* Support for iommu_map/unmap */
+#define __IOMMU_DOMAIN_DMA_API (1U  1) /* Domain for use in DMA-API
+implementation */
+#define __IOMMU_DOMAIN_PT  (1U  2) /* Domain is identity mapped */
+
+/*
+ * This are the possible domain-types
+ *
+ * IOMMU_DOMAIN_BLOCKED- All DMA is blocked, can be used to isolate
+ *  devices
+ * IOMMU_DOMAIN_IDENTITY   - DMA addresses are system physical addresses
+ * IOMMU_DOMAIN_UNMANAGED  - DMA mappings managed by IOMMU-API user, used
+ *  for VMs
+ * IOMMU_DOMAIN_DMA- Internally used for DMA-API implementations.
+ *  This flag allows IOMMU drivers to implement
+ *  certain optimizations for these domains
+ */
+#define IOMMU_DOMAIN_BLOCKED   (0U)
+#define IOMMU_DOMAIN_IDENTITY  (__IOMMU_DOMAIN_PT)
+#define IOMMU_DOMAIN_UNMANAGED (__IOMMU_DOMAIN_PAGING)
+#define IOMMU_DOMAIN_DMA   (__IOMMU_DOMAIN_PAGING |\
+__IOMMU_DOMAIN_DMA_API)
+
struct iommu_domain {
+   unsigned type;
const struct iommu_ops *ops;
void *priv;
iommu_fault_handler_t handler;
@@ -117,7 +142,7 @@ struct iommu_ops {
void (*domain_destroy)(struct iommu_domain *domain);

/* Domain allocation and freeing by the iommu driver */
-   struct iommu_domain *(*domain_alloc)(void);
+   struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
void (*domain_free)(struct iommu_domain *);

int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
-- 
1.9.1

--
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
--
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 5/6] pwm: samsung: Fix output race on disabling

2015-03-26 Thread Anand Moon
From: Sjoerd Simons sjoerd.sim...@collabora.co.uk

When disabling the samsung PWM the output state remains at the level it
was in the end of a pwm cycle. In other words, calling pwm_disable when
at 100% duty will keep the output active, while at all other setting the
output will go/stay inactive. On top of that the samsung PWM settings are
double-buffered, which means the new settings only get applied at the
start of a new PWM cycle.

This results in a race if the PWM is at 100% duty and a driver calls:
  pwm_config (pwm, 0, period);
  pwm_disable (pwm);

In this case the PWMs output will unexpectedly stay active, unless a new
PWM cycle happened to start between the register writes in _config and
_disable. As far as i can tell this is a regression introduced by 3bdf878,
before that a call to pwm_config would call pwm_samsung_enable which,
while heavy-handed, made sure the expected settings were live.

To resolve this, while not re-introducing the issues 3bdf878 (flickering
as the PWM got reset while in a PWM cycle). Only force an update of the
settings when at 100% duty, which shouldn't have a noticeable effect on
the output but is enough to ensure the behaviour is as expected on
disable.

Signed-off-by: Sjoerd Simons sjoerd.sim...@collabora.co.uk
Signed-off-by: Anand Moon linux.am...@gmail.com
---
 drivers/pwm/pwm-samsung.c | 31 ++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index 3e9b583..649f6c4 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -269,12 +269,31 @@ static void pwm_samsung_disable(struct pwm_chip *chip, 
struct pwm_device *pwm)
spin_unlock_irqrestore(samsung_pwm_lock, flags);
 }
 
+static void pwm_samsung_manual_update(struct samsung_pwm_chip *chip,
+ struct pwm_device *pwm)
+{
+   unsigned int tcon_chan = to_tcon_channel(pwm-hwpwm);
+   u32 tcon;
+   unsigned long flags;
+
+   spin_lock_irqsave(samsung_pwm_lock, flags);
+
+   tcon = readl(chip-base + REG_TCON);
+   tcon |= TCON_MANUALUPDATE(tcon_chan);
+   writel(tcon, chip-base + REG_TCON);
+
+   tcon = ~TCON_MANUALUPDATE(tcon_chan);
+   writel(tcon, chip-base + REG_TCON);
+
+   spin_unlock_irqrestore(samsung_pwm_lock, flags);
+}
+
 static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
  int duty_ns, int period_ns)
 {
struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
-   u32 tin_ns = chan-tin_ns, tcnt, tcmp;
+   u32 tin_ns = chan-tin_ns, tcnt, tcmp, oldtcmp;
 
/*
 * We currently avoid using 64bit arithmetic by using the
@@ -288,6 +307,7 @@ static int pwm_samsung_config(struct pwm_chip *chip, struct 
pwm_device *pwm,
return 0;
 
tcnt = readl(our_chip-base + REG_TCNTB(pwm-hwpwm));
+   oldtcmp = readl(our_chip-base + REG_TCMPB(pwm-hwpwm));
 
/* We need tick count for calculation, not last tick. */
++tcnt;
@@ -335,6 +355,15 @@ static int pwm_samsung_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
writel(tcnt, our_chip-base + REG_TCNTB(pwm-hwpwm));
writel(tcmp, our_chip-base + REG_TCMPB(pwm-hwpwm));
 
+   /* In case the PWM is currently at 100% duty, force a manual update
+* to prevent the signal staying high in the pwm is disabled shortly
+* afer this update (before it autoreloaded the new values) .
+*/
+   if (oldtcmp == (u32) -1) {
+   dev_dbg(our_chip-chip.dev, Forcing manual update);
+   pwm_samsung_manual_update(our_chip, pwm);
+   }
+
chan-period_ns = period_ns;
chan-tin_ns = tin_ns;
chan-duty_ns = duty_ns;
-- 
1.9.1

--
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 1/6] ARM: dts :exynos5422-odroidxu3 Add pwm-fan node to the Odroid-XU3 board.

2015-03-26 Thread Anand Moon
Add pwm-fan node to the OdroidXU3 board.

Tested on OdroidXU3 board.

Signed-off-by: Anand Moon linux.am...@gmail.com
---
 arch/arm/boot/dts/exynos5422-odroidxu3.dts | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts 
b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index a519c86..eaec006 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -278,6 +278,15 @@
rtc@101E {
status = okay;
};
+
+   fan0: pwm-fan {
+   compatible = pwm-fan;
+   pwms = pwm 0 20972 0;
+   cooling-min-state = 0;
+   cooling-max-state = 3;
+   #cooling-cells = 2;
+   cooling-levels = 0 90 130 170 230;
+   };
 };
 
 hdmi {
@@ -369,3 +378,10 @@
shunt-resistor = 1;
};
 };
+
+pwm {
+   pinctrl-0 = pwm0_out;
+   pinctrl-names = default;
+   samsung,pwm-outputs = 0;
+   status = okay;
+};
-- 
1.9.1

--
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 3/6] ARM:dts exynos5422 Update the thermal sensor for tmu_cpu0

2015-03-26 Thread Anand Moon
Move the registration of thermal sensors for tmu_cpu0 from exynos5420.dtsi
to exynos5-cpu-thermal.dtsi, to avoid duplicate registration of the sensors.

Tested on OdroidXU3 board.

Signed-off-by: Anand Moon linux.am...@gmail.com
---
 arch/arm/boot/dts/exynos5-cpu-thermal.dtsi | 58 ++
 arch/arm/boot/dts/exynos5420.dtsi  |  4 ---
 arch/arm/boot/dts/exynos5422-odroidxu3.dts |  1 +
 3 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos5-cpu-thermal.dtsi

diff --git a/arch/arm/boot/dts/exynos5-cpu-thermal.dtsi 
b/arch/arm/boot/dts/exynos5-cpu-thermal.dtsi
new file mode 100644
index 000..8fede70
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5-cpu-thermal.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Device tree sources for Exynos5 thermal zone
+ *
+ * Copyright (c) 2014 Lukasz Majewski l.majew...@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include dt-bindings/thermal/thermal.h
+
+/ {
+   thermal-zones {
+   cpu0_thermal: cpu0-thermal {
+   thermal-sensors = tmu_cpu0;
+   polling-delay-passive = 0;
+   polling-delay = 0;
+   trips {
+   cpu_alert0: cpu-alert-0 {
+   temperature = 48000; /* ms */
+   hysteresis = 3000; /* ms */
+   type = active;
+   };
+   cpu_alert1: cpu-alert-1 {
+   temperature = 53000; /* ms */
+   hysteresis = 3000; /* ms */
+   type = active;
+   };
+   cpu_alert2: cpu-alert-2 {
+   temperature = 59000; /* ms */
+   hysteresis = 3000; /* ms */
+   type = active;
+   };
+   cpu_crit0: cpu-crit-0 {
+   temperature = 75000; /* ms */
+   hysteresis = 0; /* ms */
+   type = critical;
+   };
+   };
+   cooling-maps {
+   map0 {
+trip = cpu_alert0;
+cooling-device = fan0 0 1;
+   };
+   map1 {
+trip = cpu_alert1;
+cooling-device = fan0 1 2;
+   };
+   map2 {
+trip = cpu_alert2;
+cooling-device = fan0 2 3;
+   };
+   };
+   };
+   };
+};
diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
b/arch/arm/boot/dts/exynos5420.dtsi
index 6b49f3c..eb0f16c 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -827,10 +827,6 @@
};
 
thermal-zones {
-   cpu0_thermal: cpu0-thermal {
-   thermal-sensors = tmu_cpu0;
-   #include exynos5420-trip-points.dtsi
-   };
cpu1_thermal: cpu1-thermal {
   thermal-sensors = tmu_cpu1;
   #include exynos5420-trip-points.dtsi
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts 
b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index eaec006..c8b3e3e 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -12,6 +12,7 @@
 
 /dts-v1/;
 #include exynos5800.dtsi
+#include exynos5-cpu-thermal.dtsi
 
 / {
model = Hardkernel Odroid XU3;
-- 
1.9.1

--
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 2/6] ARM: dts exynos5420 update the cooling cells for core cpu0

2015-03-26 Thread Anand Moon
update the cooling level for cpu0 to avoid following message.

root@odroidxu3:~# dmesg | grep ther
[0.241511] /thermal-zones/cpu-thermal/cooling-maps/map0:
 could not get #cooling-cells for /cpus/cpu@0

Signed-off-by: Anand Moon linux.am...@gmail.com
---
 arch/arm/boot/dts/exynos5420.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
b/arch/arm/boot/dts/exynos5420.dtsi
index c0e98cf..6b49f3c 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -61,6 +61,10 @@
reg = 0x0;
clock-frequency = 18;
cci-control-port = cci_control1;
+
+   cooling-min-level = 10;
+   cooling-max-level = 7;
+   #cooling-cells = 2; /* min followed by max */
};
 
cpu1: cpu@1 {
-- 
1.9.1

--
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 v2 1/1] ARM: exynos_defconfig: Enable options to mount a rootfs via NFS

2015-03-26 Thread Kukjin Kim
On 03/26/15 04:08, Javier Martinez Canillas wrote:
 This patch enables the options to mount a rootfs over NFS and also support
 for automatic configuration of IP addresses during boot as needed by NFS.
 
 Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk
 ---
 
 Changes since v1:
  - Found a typo in the changelog after posting the patch. Sorry for the noise.
 
  arch/arm/configs/exynos_defconfig | 6 ++
  1 file changed, 6 insertions(+)
 
 diff --git a/arch/arm/configs/exynos_defconfig 
 b/arch/arm/configs/exynos_defconfig
 index 72a4fffd603e..02be4c072497 100644
 --- a/arch/arm/configs/exynos_defconfig
 +++ b/arch/arm/configs/exynos_defconfig
 @@ -36,6 +36,10 @@ CONFIG_PACKET=y
  CONFIG_UNIX=y
  CONFIG_NET_KEY=y
  CONFIG_INET=y
 +CONFIG_IP_PNP=y
 +CONFIG_IP_PNP_DHCP=y
 +CONFIG_IP_PNP_BOOTP=y
 +CONFIG_IP_PNP_RARP=y
  CONFIG_WIRELESS=y
  CONFIG_CFG80211=y
  CONFIG_MWIFIEX=y
 @@ -206,6 +210,8 @@ CONFIG_TMPFS=y
  CONFIG_TMPFS_POSIX_ACL=y
  CONFIG_CRAMFS=y
  CONFIG_ROMFS_FS=y
 +CONFIG_NFS_FS=y
 +CONFIG_ROOT_NFS=y
  CONFIG_NLS_CODEPAGE_437=y
  CONFIG_NLS_ASCII=y
  CONFIG_NLS_ISO8859_1=y

Applied, thanks.

- Kukjin
--
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 6/6] hwmon: pwm-fan: Update the duty cycle inorder to control the pwm-fan

2015-03-26 Thread Anand Moon
Below changes depend on following patch.
https://patchwork.kernel.org/patch/5944061/

Update the pwm_config with duty then update the pwm_disable
to poweroff the cpu fan.

Tested on OdroidXU3 board.

Signed-off-by: Anand Moon linux.am...@gmail.com
---
 drivers/hwmon/pwm-fan.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
index 7c83dc4..f25c841 100644
--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -44,26 +44,24 @@ static int  __set_pwm(struct pwm_fan_ctx *ctx, unsigned 
long pwm)
int ret = 0;
 
mutex_lock(ctx-lock);
+
if (ctx-pwm_value == pwm)
goto exit_set_pwm_err;
 
-   if (pwm == 0) {
-   pwm_disable(ctx-pwm);
-   goto exit_set_pwm;
-   }
-
duty = DIV_ROUND_UP(pwm * (ctx-pwm-period - 1), MAX_PWM);
ret = pwm_config(ctx-pwm, duty, ctx-pwm-period);
if (ret)
goto exit_set_pwm_err;
 
+   if (pwm == 0)
+   pwm_disable(ctx-pwm);
+
if (ctx-pwm_value == 0) {
ret = pwm_enable(ctx-pwm);
if (ret)
goto exit_set_pwm_err;
}
 
-exit_set_pwm:
ctx-pwm_value = pwm;
 exit_set_pwm_err:
mutex_unlock(ctx-lock);
-- 
1.9.1

--
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 4/6] ARM: dts: OdroidXU3: Enable TMU at Exynos5422 base.

2015-03-26 Thread Anand Moon
This commit enables TMU IP block on the Exynos5422 OdroidXU3
device.

Tested on OdroidXU3 board.

Signed-off-by: Anand Moon linux.am...@gmail.com
---
 arch/arm/boot/dts/exynos5422-odroidxu3.dts | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts 
b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index c8b3e3e..e1635b5 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -288,6 +288,31 @@
#cooling-cells = 2;
cooling-levels = 0 90 130 170 230;
};
+
+   tmu@1006 {
+   vtmu-supply = ldo10_reg;
+   status = okay;
+   };
+
+   tmu@10064000 {
+   vtmu-supply = ldo10_reg;
+   status = okay;
+   };
+
+   tmu@10068000 {
+   vtmu-supply = ldo10_reg;
+   status = okay;
+   };
+
+   tmu@1006c000 {
+   vtmu-supply = ldo10_reg;
+   status = okay;
+   };
+
+   tmu@100a {
+   vtmu-supply = ldo10_reg;
+   status = okay;
+   };
 };
 
 hdmi {
-- 
1.9.1

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


Exynos5422 odroidxu3 pwm-fan control using thermal sensors

2015-03-26 Thread Anand Moon
This work depeds upon work done by Lukasz Majewski l.majew...@samsung.com
 and Sjoerd Simons sjoerd.sim...@collabora.co.uk regarding the pwm-fan.

-Anand Moon
--
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 v4 0/4] ARM: EXYNOS: cpuidle: add AFTR mode support for Exynos3250

2015-03-26 Thread Kukjin Kim
On 03/19/15 14:11, Chanwoo Choi wrote:
 Hi Bartlomiej,
 
Hi,

 I tested this patch-set for AFTR mode.
 When CPU1 is offline state, I checked that CPU0 enter the AFTR mode.
 
 Tested-by: Chanwoo Choi cw00.c...@samsung.com
 
Thanks for your test.

 Best Regards,
 Chanwoo Choi
 
 On 03/19/2015 01:00 AM, Bartlomiej Zolnierkiewicz wrote:
 Hi,

 This patch series adds support for AFTR idle mode on boards with
 Exynos3250 SoC and allows EXYNOS cpuidle driver usage on these
 boards.

 It has been tested on Samsung Rinato board (Gear 2).

 Depends on:
 - for-next branch (commit: 77105c882ba6) of linux-samsung.git
   kernel tree

 Changes since v3:
 - enhanced patch description for patch #1
 - added Reviewed-by/Tested-by tags from Krzysztof
 - enhanced C2_STATE BOOT mode flag comment
 - moved exynos_{set,clear}_boot_flag() to firmware.c
 - added patch description to patch #3

 Changes since v2:
 - rebased on top of for-next branch (commit: 77105c882ba6) of
   linux-samsung.git kernel tree

 Changes since v1:
 - rebased on top of for-next branch (commit: ce275c369a0b) of
   linux-samsung.git kernel tree
 - fixed lockup on hotplug by using dsb_sev() instead of IPI in
   exynos_boot_secondary() on Exynos3250

 Best regards,
 --
 Bartlomiej Zolnierkiewicz
 Samsung RD Institute Poland
 Samsung Electronics


 Bartlomiej Zolnierkiewicz (4):
   ARM: EXYNOS: fix CPU1 hotplug on Exynos3250
   ARM: EXYNOS: add code for setting/clearing boot flag
   ARM: EXYNOS: cpuidle: add AFTR mode support for Exynos3250
   ARM: EXYNOS: cpuidle: allow driver usage on Exynos3250 SoC

  arch/arm/mach-exynos/common.h   |  6 ++
  arch/arm/mach-exynos/exynos.c   |  1 +
  arch/arm/mach-exynos/firmware.c | 33 -
  arch/arm/mach-exynos/platsmp.c  | 23 ---
  arch/arm/mach-exynos/pm.c   | 12 +++-
  arch/arm/mach-exynos/regs-pmu.h |  3 +++
  arch/arm/mach-exynos/smc.h  |  9 +
  7 files changed, 82 insertions(+), 5 deletions(-)

Applied this whole series.

Thanks,
Kukjin
--
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] drm: Exynos: Respect framebuffer pitch for FIMD/Mixer

2015-03-26 Thread Tobias Jakobi
Inki Dae wrote:
 Hello Javier,
 
 Applied.
 
 Could you use right prefix of the subject like below when you post patch?
 
 'drm/exynos: ...', not 'drm: Exynos: ...'
 
 Your email will be filtered from my mailbox if you don't use the right
 prefix so I couldn't check and take care of your patch.
I would suggest to change (or drop) the filter settings then. I don't
think you can expect people to jump through these hoops to reach a
maintainer of a kernel subsystem. Especially since this not 'documented'
anywhere.



With best wishes,
Tobias

--
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 1/1] serial: samsung: Clear operation mode on UART shutdown

2015-03-26 Thread Greg Kroah-Hartman
On Fri, Mar 20, 2015 at 01:19:44PM +0100, Javier Martinez Canillas wrote:
 Hello,
 
 On 03/13/2015 12:38 PM, Javier Martinez Canillas wrote:
  Exynos serial ports operate either in a DMA-based or interrupt-based
  modes. In DMA-based mode, the UART generates a transfer data request
  and a Transmission (Tx) interrupt in interrupt-based mode.
  
  The Tx IRQ is only unmasked in interrupt-based mode and it was done
  in s3c24xx_serial_start_tx(). Commit ba019a3e2ad5 (serial: samsung:
  remove redundant interrupt enabling) removed the IRQ enable on that
  function since it is enabled when the mode is set in enable_tx_pio().
  
  The problem is that enable_tx_pio() is only called if the port mode
  has not been set before but the mode was not cleared on .shutdown().
  
  So if the UART was shutdown and then started up again, the mode set
  will remain and the Tx IRQ won't be unmasked.
  
  This caused a hang on at least Exynos5250, Exynos5420 and Exynos5800
  when the system is rebooted or powered off.
  
  Fixes: ba019a3e2ad5 (serial: samsung: remove redundant interrupt enabling)
  Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk
  ---
  
  I noticed this issue on an Exynos5250 Snow, Exynos5420 Peach Pit and Exynos
  5800 Peach Pi Chromebooks. This patch fixes the issue on all of them.
  
  The offending commit landed in v4.0-rc1 so this fix is -rc material.
  
   drivers/tty/serial/samsung.c | 1 +
   1 file changed, 1 insertion(+)
  
  diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
  index af821a908720..cf08876922f1 100644
  --- a/drivers/tty/serial/samsung.c
  +++ b/drivers/tty/serial/samsung.c
  @@ -963,6 +963,7 @@ static void s3c24xx_serial_shutdown(struct uart_port 
  *port)
  free_irq(ourport-tx_irq, ourport);
  tx_enabled(port) = 0;
  ourport-tx_claimed = 0;
  +   ourport-tx_mode = 0;
  }
   
  if (ourport-rx_claimed) {
  
 
 Any comments about this patch? 3.14-rc5 will most likely be released this 
 weekend
 so we are running out of time to fix this issue before 3.14 is released.

3.14 was released months ago...
--
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 1/1] serial: samsung: Clear operation mode on UART shutdown

2015-03-26 Thread Javier Martinez Canillas
On 03/26/2015 10:57 PM, Greg Kroah-Hartman wrote:
 On Fri, Mar 20, 2015 at 01:19:44PM +0100, Javier Martinez Canillas wrote:
  The offending commit landed in v4.0-rc1 so this fix is -rc material.
  
   drivers/tty/serial/samsung.c | 1 +
   1 file changed, 1 insertion(+)
  
  diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
  index af821a908720..cf08876922f1 100644
  --- a/drivers/tty/serial/samsung.c
  +++ b/drivers/tty/serial/samsung.c
  @@ -963,6 +963,7 @@ static void s3c24xx_serial_shutdown(struct uart_port 
  *port)
 free_irq(ourport-tx_irq, ourport);
 tx_enabled(port) = 0;
 ourport-tx_claimed = 0;
  +  ourport-tx_mode = 0;
 }
   
 if (ourport-rx_claimed) {
  
 
 Any comments about this patch? 3.14-rc5 will most likely be released this 
 weekend
 so we are running out of time to fix this issue before 3.14 is released.
 
 3.14 was released months ago...
 

err... I don't know what I was thinking when I wrote this, I obviously
meant 4.0. It seems the 3.1 prefix stuck in my head :)

Best regards,
Javier
--
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 1/3] drm/exynos: mixer: add 2x scaling to mixer_graph_buffer

2015-03-26 Thread Tobias Jakobi
Hello!


Gustavo Padovan wrote:
 I would keep calling these two vars x_ratio and y_ratio. I don't see a reason
 to change the name here.
Right, I'm going to change this. Also I was thinking of basing the patch
on your latest cleanup series (the 'drm/exynos: remove struct *_win_data
abstraction on planes' one).

Then it would just be:
static int mixer_setup_scale(const struct exynos_drm_plane *plane,
unsigned int *x_ratio, unsigned int *y_ratio)

Also that would automatically fix your other comment below [*].


 Use EPERM or ENOTSUPP. Or even true/false.
Will do!


 You need to fix style here
 
 if (mixer_setup_scale(win_data-src_width, win_data-src_height,  
   
   win_data-crtc_width, win_data-crtc_height,
   
   x_ratio, y_ratio))
   
 return; 
With [*] this would just be:
if (mixer_setup_scale(plane, x_ratio, y_ratio)) return;

What do you think?


 I think your patch is good after these things get fixes and we can go with it
 and drop mine. Then I'll just rebase the alpha channel fix patch on top of
 this one.
Might I suggest to extend the alpha channel patch in this way:
https://github.com/tobiasjakobi/linux-odroid/commit/e3aad184eda2cade4d59a874e459a8ff265ed75f

With this we get at least some pixelformat validation into the driver.


With best wishes,
Tobias


--
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] drm: Exynos: Respect framebuffer pitch for FIMD/Mixer

2015-03-26 Thread Inki Dae
On 2015년 03월 27일 09:15, Tobias Jakobi wrote:
 Inki Dae wrote:
 Hello Javier,

 Applied.

 Could you use right prefix of the subject like below when you post patch?

 'drm/exynos: ...', not 'drm: Exynos: ...'

 Your email will be filtered from my mailbox if you don't use the right
 prefix so I couldn't check and take care of your patch.
 I would suggest to change (or drop) the filter settings then. I don't

Filters of my mailbox are considered for two cases, one is DRI mailing
list, other is drm/exynos.
So if you don't use the drm/exynos prefix, then I would try to find your
patch in DRI mailing list - I sometimes check the mailing list. However,
the mailing list have so much emails so it'd be not easy to pick up only
exynos relevant patches among the email lists. As a result, you would
get the my review lately.

 think you can expect people to jump through these hoops to reach a
 maintainer of a kernel subsystem. Especially since this not 'documented'
 anywhere.

Right, this is not documented but if you have ever checked exynos drm
driver tree, then I think you could know how we use the prefix. Of
course, I don't like to force the use of this prefix but if you and
other people use prefix in the manner of them, exynos drm tree would be
a little bit messy. i.e., DRM: EXYNOS, drm: exynos, drm: Exynos,
drm/exynos, drm/exynos: fimd, drm: exynos: fimd, DRM: EXYNOS: FIMD, ...
 so many cases  Do you really want this?

So I will always say please, use right prefix Otherwise, I will change
it while merging as is.
And I see that other drm drivers have their own way which is not
documented but just implicitly.

Thanks,
Inki Dae

 
 
 
 With best wishes,
 Tobias
 
 

--
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] drm: Exynos: Respect framebuffer pitch for FIMD/Mixer

2015-03-26 Thread Inki Dae
Hi Daniel,

On 2015년 03월 26일 23:48, Daniel Stone wrote:
 Hi Inki,
 
 On Thu, 26 Mar, 2015 at 2:32 PM, Inki Dae inki@samsung.com wrote:
 Applied.
 
 Thanks very much.
 
 Could you use right prefix of the subject like below when you post patch?

 'drm/exynos: ...', not 'drm: Exynos: ...'

 Your email will be filtered from my mailbox if you don't use the right
 prefix so I couldn't check and take care of your patch.
 
 Ah, I didn't realise this. Maybe it could be good to not filter if the
 patch is also directly addressed/CCed to you, rather than a list?
 Gustavo Padovan is following this convention and I also will in future,
 but I guess it might lead to some patches being dropped from casual
 contributors if they don't know this.

Sorry for confusing. I don't really want to drop the patches which don't
use right prefix - undocumented. I have two filters, one is DRI mailing
list, other is drm/exynos. So if you use other prefix, your patch is
filtered and stored in my dri-devel mailbox. But as you may know, the
mailbox would always be full with many emails which contains various
type patches, exynos, omap, sti, radeon, intel and so no. So it wouldn't
be easy to pick up only your patch among them. So I'd like to recommend
you to use drm/exynos prefix so that I could review and pick it up
easily and quickly.

Thanks,
Inki Dae

 
 Cheers,
 Daniel
 

 Thanks,
 Inki Dae

 On 2015년 03월 24일 17:57, Javier Martinez Canillas wrote:
  Hello Inki,

  On Tue, Mar 17, 2015 at 2:24 PM, Daniel Stone
 dani...@collabora.com wrote:
  When performing a modeset, use the framebuffer pitch value to set FIMD
  IMG_SIZE and Mixer SPAN registers. These are both defined as pitch
 - the
  distance between contiguous lines (bytes for FIMD, pixels for mixer).

  Fixes display on Snow (1366x768).

  Signed-off-by: Daniel Stone dani...@collabora.com
  Tested-by: Javier Martinez Canillas javier.marti...@collabora.co.uk

  Any comments on this patch? It would be great to pick this sooner
  rather than later since it fixes (at least) display output on Snow and
  HDMI output on Peach Pit/Pi.

  Best regards,
  Javier



 

--
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 -v2 2/8] drm/exynos: remove unused exynos_crtc-win_enable() callback

2015-03-26 Thread Gustavo Padovan
From: Gustavo Padovan gustavo.pado...@collabora.co.uk

None of the exynos crtc drivers implements win_enable() so remove it for
better clarity of the code.

Signed-off-by: Gustavo Padovan gustavo.pado...@collabora.co.uk
---
 drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 9afd390..4e8f0b0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -174,7 +174,6 @@ struct exynos_drm_display {
  * hardware overlay is updated.
  * @win_mode_set: copy drm overlay info to hw specific overlay info.
  * @win_commit: apply hardware specific overlay data to registers.
- * @win_enable: enable hardware specific overlay.
  * @win_disable: disable hardware specific overlay.
  * @te_handler: trigger to transfer video image at the tearing effect
  * synchronization signal if there is a page flip request.
@@ -192,7 +191,6 @@ struct exynos_drm_crtc_ops {
void (*win_mode_set)(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane);
void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos);
-   void (*win_enable)(struct exynos_drm_crtc *crtc, int zpos);
void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos);
void (*te_handler)(struct exynos_drm_crtc *crtc);
 };
-- 
2.1.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 -v2 5/8] drm/exynos: make zpos property immutable

2015-03-26 Thread Gustavo Padovan
From: Gustavo Padovan gustavo.pado...@collabora.co.uk

We already set each plane zpos at init, after that changes to zpos are
not expected. This patch turns zpos into a read-only property so now it is
impossible to set zpos.

Signed-off-by: Gustavo Padovan gustavo.pado...@collabora.co.uk
---
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 21 ++---
 1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 504bd6e..2fbac9b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -184,27 +184,10 @@ static void exynos_plane_destroy(struct drm_plane *plane)
drm_plane_cleanup(plane);
 }
 
-static int exynos_plane_set_property(struct drm_plane *plane,
-struct drm_property *property,
-uint64_t val)
-{
-   struct drm_device *dev = plane-dev;
-   struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
-   struct exynos_drm_private *dev_priv = dev-dev_private;
-
-   if (property == dev_priv-plane_zpos_property) {
-   exynos_plane-zpos = val;
-   return 0;
-   }
-
-   return -EINVAL;
-}
-
 static struct drm_plane_funcs exynos_plane_funcs = {
.update_plane   = exynos_update_plane,
.disable_plane  = exynos_disable_plane,
.destroy= exynos_plane_destroy,
-   .set_property   = exynos_plane_set_property,
 };
 
 static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
@@ -216,8 +199,8 @@ static void exynos_plane_attach_zpos_property(struct 
drm_plane *plane,
 
prop = dev_priv-plane_zpos_property;
if (!prop) {
-   prop = drm_property_create_range(dev, 0, zpos, 0,
-MAX_PLANE - 1);
+   prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE,
+zpos, 0, MAX_PLANE - 1);
if (!prop)
return;
 
-- 
2.1.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 -v2 0/8] drm/exynos: clean up patches (preparing for atomic)

2015-03-26 Thread Gustavo Padovan
From: Gustavo Padovan gustavo.pado...@collabora.co.uk

Hi,

Here goes some clean ups to the exynos drivers. The main clean ups is
the presetting and zpos making the property immutable and the removal
of *_win_data structures.

v2 contains a extra patch to fix alpha setting for planes in fimd, so
now fimd works fine even after the removal of struct fimd_win_data.

Gustavo

---
Gustavo Padovan (7):
  drm/exynos: fimd: fix alpha setting for XR24 pixel format
  drm/exynos: remove unused exynos_crtc-win_enable() callback
  drm/exynos: remove struct *_win_data abstraction on planes
  drm/exynos: preset zpos value for overlay planes
  drm/exynos: make zpos property immutable
  drm/exynos: remove exynos_plane_destroy()
  drm/exynos: remove leftover functions declarations

Mandeep Singh Baines (1):
  drm/exynos: track vblank events on a per crtc basis

 drivers/gpu/drm/exynos/exynos7_drm_decon.c | 176 --
 drivers/gpu/drm/exynos/exynos_drm_crtc.c   | 101 ++---
 drivers/gpu/drm/exynos/exynos_drm_crtc.h   |   7 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c|  27 
 drivers/gpu/drm/exynos/exynos_drm_drv.h|  20 +--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   | 226 -
 drivers/gpu/drm/exynos/exynos_drm_plane.c  |  66 ++---
 drivers/gpu/drm/exynos/exynos_drm_plane.h  |   7 +-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c   | 134 -
 drivers/gpu/drm/exynos/exynos_mixer.c  | 217 ++-
 include/video/samsung_fimd.h   |   5 +
 11 files changed, 337 insertions(+), 649 deletions(-)

-- 
2.1.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 -v2 7/8] drm/exynos: remove leftover functions declarations

2015-03-26 Thread Gustavo Padovan
From: Gustavo Padovan gustavo.pado...@collabora.co.uk

These functions were already removed by previous cleanup work, but these
ones were left behind.

Signed-off-by: Gustavo Padovan gustavo.pado...@collabora.co.uk
Acked-by: Joonyoung Shim jy0922.s...@samsung.com
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index e1fd2ef..0ecd8fc 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -28,12 +28,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, 
int pipe);
 void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe);
 void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb);
 
-void exynos_drm_crtc_plane_mode_set(struct drm_crtc *crtc,
-   struct exynos_drm_plane *plane);
-void exynos_drm_crtc_plane_commit(struct drm_crtc *crtc, int zpos);
-void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos);
-void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos);
-
 /* This function gets pipe value to crtc device matched with out_type. */
 int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
unsigned int out_type);
-- 
2.1.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 -v2 6/8] drm/exynos: remove exynos_plane_destroy()

2015-03-26 Thread Gustavo Padovan
From: Gustavo Padovan gustavo.pado...@collabora.co.uk

The .destroy() callback for exynos can be replaced by drm_plane_cleanup().
The only extra operation on exynos_plane_destroy() was a call to
exynos_plane_disable() but the plane is already disabled by a earlier call
to drm_framebuffer_remove().

Signed-off-by: Gustavo Padovan gustavo.pado...@collabora.co.uk
---
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 2fbac9b..2b0479e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -178,16 +178,10 @@ static int exynos_disable_plane(struct drm_plane *plane)
return 0;
 }
 
-static void exynos_plane_destroy(struct drm_plane *plane)
-{
-   exynos_disable_plane(plane);
-   drm_plane_cleanup(plane);
-}
-
 static struct drm_plane_funcs exynos_plane_funcs = {
.update_plane   = exynos_update_plane,
.disable_plane  = exynos_disable_plane,
-   .destroy= exynos_plane_destroy,
+   .destroy= drm_plane_cleanup,
 };
 
 static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
-- 
2.1.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 1/5] tests/exynos: add fimg2d performance analysis

2015-03-26 Thread Emil Velikov
On 25/03/15 18:27, Tobias Jakobi wrote:
 Hello,
 
 the new version should fix most of the mentioned issues.
 
 Tobias Jakobi wrote:
 As a general note I would recommend keeping statements on separate lines
 (none of if (foo) far()) as it makes debugging easier.
 OK, changing this.
 Except for this, I didn't change it since I don't see the point. In fact
 I think that splitting the few occurrences makes the code less readable.
 
Beauty is in the eye of the beholder.

 I haven't worked with getopt before, so I gave it a try and made all
 these hardcoded parameters configurable.
 
Nice :-)

Cheers,
Emil
--
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 v2 1/5] tests/exynos: add fimg2d performance analysis

2015-03-26 Thread Emil Velikov
On 25/03/15 16:48, Tobias Jakobi wrote:
 Currently only fast solid color clear performance is measured.
 A large buffer is allocated and solid color clear operations
 are executed on it with randomly chosen properties (position
 and size of the region, clear color). Execution time is
 measured and output together with the amount of pixels
 processed.
 
 The 'simple' variant only executes one G2D command buffer at
 a time, while the 'multi' variant executes multiple ones. This
 can be used to measure setup/exec overhead.
 
 The test also serves a stability check. If clocks/voltages are
 too high or low respectively, the test quickly reveals this.
 
 v2: Add GPLv2 header, argument handling and documentation.
 Tool is only installed when requested.
 
 Signed-off-by: Tobias Jakobi tjak...@math.uni-bielefeld.de
 ---
  tests/exynos/Makefile.am  |  19 ++-
  tests/exynos/exynos_fimg2d_perf.c | 320 
 ++
  2 files changed, 337 insertions(+), 2 deletions(-)
  create mode 100644 tests/exynos/exynos_fimg2d_perf.c
 
 diff --git a/tests/exynos/Makefile.am b/tests/exynos/Makefile.am
 index b21d016..e82d199 100644
 --- a/tests/exynos/Makefile.am
 +++ b/tests/exynos/Makefile.am
 @@ -5,16 +5,31 @@ AM_CFLAGS = \
   -I $(top_srcdir)/exynos \
   -I $(top_srcdir)
  
 +bin_PROGRAMS =
 +noinst_PROGRAMS =
 +
  if HAVE_LIBKMS
  if HAVE_INSTALL_TESTS
 -bin_PROGRAMS = \
 +bin_PROGRAMS += \
   exynos_fimg2d_test
  else
 -noinst_PROGRAMS = \
 +noinst_PROGRAMS += \
   exynos_fimg2d_test
  endif
  endif
  
 +if HAVE_INSTALL_TESTS
 +bin_PROGRAMS += \
 + exynos_fimg2d_perf
 +else
 +noinst_PROGRAMS += \
 + exynos_fimg2d_perf
 +endif
 +
One can simplify this as below, although I will not worry too much about
it :) That aside would be nice to hear some feedback from the Exynos and
the old school libdrm devs on the core changes.


if HAVE_LIBKMS
FOO = \
exynos_fimg2d_test
endif

if HAVE_INSTALL_TESTS
bin_PROGRAMS = \
$(FOO) \
exynos_fimg2d_perf
else
noinst_PROGRAMS = \
$(FOO) \
exynos_fimg2d_perf
endif


-Emil

--
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 -v2 1/8] drm/exynos: fimd: fix alpha setting for XR24 pixel format

2015-03-26 Thread Gustavo Padovan
From: Gustavo Padovan gustavo.pado...@collabora.co.uk

XR24 planes were not shown properly, so now set the right registers
to correctly enable displaying these planes.

It also moves the alpha register settings to fimd_win_set_pixfmt()
to keep all pixel format stuff together.

Signed-off-by: Gustavo Padovan gustavo.pado...@collabora.co.uk
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 31 +--
 include/video/samsung_fimd.h |  5 +
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 925fc69..c7aa4c7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -54,6 +54,9 @@
 /* size control register for hardware windows 1 ~ 2. */
 #define VIDOSD_D(win)  (VIDOSD_BASE + 0x0C + (win) * 16)
 
+#define VIDWnALPHA0(win)   (VIDW_ALPHA + 0x00 + (win) * 8)
+#define VIDWnALPHA1(win)   (VIDW_ALPHA + 0x04 + (win) * 8)
+
 #define VIDWx_BUF_START(win, buf)  (VIDW_BUF_START(buf) + (win) * 8)
 #define VIDWx_BUF_END(win, buf)(VIDW_BUF_END(buf) + (win) * 8)
 #define VIDWx_BUF_SIZE(win, buf)   (VIDW_BUF_SIZE(buf) + (win) * 4)
@@ -623,6 +626,24 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, 
unsigned int win)
}
 
writel(val, ctx-regs + WINCON(win));
+
+   /* hardware window 0 doesn't support alpha channel. */
+   if (win != 0) {
+   /* OSD alpha */
+   val = VIDISD14C_ALPHA0_R(0xf) |
+   VIDISD14C_ALPHA0_G(0xf) |
+   VIDISD14C_ALPHA0_B(0xf) |
+   VIDISD14C_ALPHA1_R(0xf) |
+   VIDISD14C_ALPHA1_G(0xf) |
+   VIDISD14C_ALPHA1_B(0xf);
+
+   writel(val, ctx-regs + VIDOSD_C(win));
+
+   val = VIDW_ALPHA_R(0xf) | VIDW_ALPHA_G(0xf) |
+   VIDW_ALPHA_G(0xf);
+   writel(val, ctx-regs + VIDWnALPHA0(win));
+   writel(val, ctx-regs + VIDWnALPHA1(win));
+   }
 }
 
 static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win)
@@ -747,16 +768,6 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, 
int zpos)
DRM_DEBUG_KMS(osd pos: tx = %d, ty = %d, bx = %d, by = %d\n,
win_data-offset_x, win_data-offset_y, last_x, last_y);
 
-   /* hardware window 0 doesn't support alpha channel. */
-   if (win != 0) {
-   /* OSD alpha */
-   alpha = VIDISD14C_ALPHA1_R(0xf) |
-   VIDISD14C_ALPHA1_G(0xf) |
-   VIDISD14C_ALPHA1_B(0xf);
-
-   writel(alpha, ctx-regs + VIDOSD_C(win));
-   }
-
/* OSD size */
if (win != 3  win != 4) {
u32 offset = VIDOSD_D(win);
diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
index a20e4a3..5132428 100644
--- a/include/video/samsung_fimd.h
+++ b/include/video/samsung_fimd.h
@@ -289,6 +289,11 @@
 #define VIDISD14C_ALPHA1_B_LIMIT   0xf
 #define VIDISD14C_ALPHA1_B(_x) ((_x)  0)
 
+#define VIDW_ALPHA 0x021c
+#define VIDW_ALPHA_R(_x)   ((_x)  16)
+#define VIDW_ALPHA_G(_x)   ((_x)  8)
+#define VIDW_ALPHA_B(_x)   ((_x)  0)
+
 /* Video buffer addresses */
 #define VIDW_BUF_START(_buff)  (0xA0 + ((_buff) * 8))
 #define VIDW_BUF_START1(_buff) (0xA4 + ((_buff) * 8))
-- 
2.1.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 -v2 4/8] drm/exynos: preset zpos value for overlay planes

2015-03-26 Thread Gustavo Padovan
From: Gustavo Padovan gustavo.pado...@collabora.co.uk

Usually userspace don't want to have two overlay planes on the same zpos
so this change assign a different zpos for each plane. Before this change
a zpos of value zero was created for all planes so the userspace had to
set up the zpos of every plane it wanted to use.

Also all places that were storing zpos positions are now unsigned int.

Signed-off-by: Gustavo Padovan gustavo.pado...@collabora.co.uk
---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c | 20 +++-
 drivers/gpu/drm/exynos/exynos_drm_drv.h|  7 +++
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   | 19 ++-
 drivers/gpu/drm/exynos/exynos_drm_plane.c  | 16 +---
 drivers/gpu/drm/exynos/exynos_drm_plane.h  |  3 ++-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c   | 17 +
 drivers/gpu/drm/exynos/exynos_mixer.c  | 11 +--
 7 files changed, 37 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c 
b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 2cbe328..bee1f72 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -378,7 +378,7 @@ static void decon_win_set_colkey(struct decon_context *ctx, 
unsigned int win)
  * @protect: 1 to protect (disable updates)
  */
 static void decon_shadow_protect_win(struct decon_context *ctx,
-   int win, bool protect)
+unsigned int win, bool protect)
 {
u32 bits, val;
 
@@ -392,12 +392,12 @@ static void decon_shadow_protect_win(struct decon_context 
*ctx,
writel(val, ctx-regs + SHADOWCON);
 }
 
-static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos)
+static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
 {
struct decon_context *ctx = crtc-ctx;
struct drm_display_mode *mode = crtc-base.mode;
struct exynos_drm_plane *plane;
-   int padding, win = zpos;
+   int padding;
unsigned long val, alpha;
unsigned int last_x;
unsigned int last_y;
@@ -405,9 +405,6 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, 
int zpos)
if (ctx-suspended)
return;
 
-   if (win == DEFAULT_ZPOS)
-   win = ctx-default_win;
-
if (win  0 || win = WINDOWS_NR)
return;
 
@@ -513,16 +510,12 @@ static void decon_win_commit(struct exynos_drm_crtc 
*crtc, int zpos)
plane-enabled = true;
 }
 
-static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos)
+static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
 {
struct decon_context *ctx = crtc-ctx;
struct exynos_drm_plane *plane;
-   int win = zpos;
u32 val;
 
-   if (win == DEFAULT_ZPOS)
-   win = ctx-default_win;
-
if (win  0 || win = WINDOWS_NR)
return;
 
@@ -764,7 +757,8 @@ static int decon_bind(struct device *dev, struct device 
*master, void *data)
struct drm_device *drm_dev = data;
struct exynos_drm_plane *exynos_plane;
enum drm_plane_type type;
-   int zpos, ret;
+   unsigned int zpos;
+   int ret;
 
ret = decon_ctx_initialize(ctx, drm_dev);
if (ret) {
@@ -776,7 +770,7 @@ static int decon_bind(struct device *dev, struct device 
*master, void *data)
type = (zpos == ctx-default_win) ? DRM_PLANE_TYPE_PRIMARY :
DRM_PLANE_TYPE_OVERLAY;
exynos_plane_init(drm_dev, ctx-planes[zpos], 1  ctx-pipe,
- type);
+ type, zpos);
}
 
exynos_plane = ctx-planes[ctx-default_win];
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 8a2f943..26d6de1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -21,7 +21,6 @@
 #define MAX_CRTC   3
 #define MAX_PLANE  5
 #define MAX_FB_BUFFER  4
-#define DEFAULT_ZPOS   -1
 
 #define to_exynos_crtc(x)  container_of(x, struct exynos_drm_crtc, base)
 #define to_exynos_plane(x) container_of(x, struct exynos_drm_plane, base)
@@ -104,7 +103,7 @@ struct exynos_drm_plane {
unsigned int pitch;
uint32_t pixel_format;
dma_addr_t dma_addr[MAX_FB_BUFFER];
-   int zpos;
+   unsigned int zpos;
unsigned int index_color;
 
bool default_win:1;
@@ -189,8 +188,8 @@ struct exynos_drm_crtc_ops {
int (*enable_vblank)(struct exynos_drm_crtc *crtc);
void (*disable_vblank)(struct exynos_drm_crtc *crtc);
void (*wait_for_vblank)(struct exynos_drm_crtc *crtc);
-   void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos);
-   void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos);
+   void (*win_commit)(struct exynos_drm_crtc 

[PATCH -v2 3/8] drm/exynos: remove struct *_win_data abstraction on planes

2015-03-26 Thread Gustavo Padovan
From: Gustavo Padovan gustavo.pado...@collabora.co.uk

struct {fimd,mixer,vidi}_win_data was just keeping the same data
as struct exynos_drm_plane thus get ride of it and use exynos_drm_plane
directly.

It changes how planes are created and remove .win_mode_set() callback
that was only filling all *_win_data structs.

Signed-off-by: Gustavo Padovan gustavo.pado...@collabora.co.uk
---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c | 164 --
 drivers/gpu/drm/exynos/exynos_drm_crtc.c   |   9 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.h   |   1 +
 drivers/gpu/drm/exynos/exynos_drm_drv.c|  14 --
 drivers/gpu/drm/exynos/exynos_drm_drv.h|   5 +-
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   | 182 +
 drivers/gpu/drm/exynos/exynos_drm_plane.c  |  23 +---
 drivers/gpu/drm/exynos/exynos_drm_plane.h  |   6 +-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c   | 123 -
 drivers/gpu/drm/exynos/exynos_mixer.c  | 212 ++---
 10 files changed, 242 insertions(+), 497 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c 
b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 63f02e2..2cbe328 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -28,6 +28,7 @@
 #include video/exynos7_decon.h
 
 #include exynos_drm_crtc.h
+#include exynos_drm_plane.h
 #include exynos_drm_drv.h
 #include exynos_drm_fbdev.h
 #include exynos_drm_iommu.h
@@ -41,32 +42,16 @@
 
 #define WINDOWS_NR 2
 
-struct decon_win_data {
-   unsigned intovl_x;
-   unsigned intovl_y;
-   unsigned intoffset_x;
-   unsigned intoffset_y;
-   unsigned intovl_width;
-   unsigned intovl_height;
-   unsigned intfb_width;
-   unsigned intfb_height;
-   unsigned intbpp;
-   unsigned intpixel_format;
-   dma_addr_t  dma_addr;
-   boolenabled;
-   boolresume;
-};
-
 struct decon_context {
struct device   *dev;
struct drm_device   *drm_dev;
struct exynos_drm_crtc  *crtc;
+   struct exynos_drm_plane planes[WINDOWS_NR];
struct clk  *pclk;
struct clk  *aclk;
struct clk  *eclk;
struct clk  *vclk;
void __iomem*regs;
-   struct decon_win_data   win_data[WINDOWS_NR];
unsigned intdefault_win;
unsigned long   irq_flags;
booli80_if;
@@ -296,59 +281,16 @@ static void decon_disable_vblank(struct exynos_drm_crtc 
*crtc)
}
 }
 
-static void decon_win_mode_set(struct exynos_drm_crtc *crtc,
-   struct exynos_drm_plane *plane)
-{
-   struct decon_context *ctx = crtc-ctx;
-   struct decon_win_data *win_data;
-   int win, padding;
-
-   if (!plane) {
-   DRM_ERROR(plane is NULL\n);
-   return;
-   }
-
-   win = plane-zpos;
-   if (win == DEFAULT_ZPOS)
-   win = ctx-default_win;
-
-   if (win  0 || win = WINDOWS_NR)
-   return;
-
-
-   win_data = ctx-win_data[win];
-
-   padding = (plane-pitch / (plane-bpp  3)) - plane-fb_width;
-   win_data-offset_x = plane-fb_x;
-   win_data-offset_y = plane-fb_y;
-   win_data-fb_width = plane-fb_width + padding;
-   win_data-fb_height = plane-fb_height;
-   win_data-ovl_x = plane-crtc_x;
-   win_data-ovl_y = plane-crtc_y;
-   win_data-ovl_width = plane-crtc_width;
-   win_data-ovl_height = plane-crtc_height;
-   win_data-dma_addr = plane-dma_addr[0];
-   win_data-bpp = plane-bpp;
-   win_data-pixel_format = plane-pixel_format;
-
-   DRM_DEBUG_KMS(offset_x = %d, offset_y = %d\n,
-   win_data-offset_x, win_data-offset_y);
-   DRM_DEBUG_KMS(ovl_width = %d, ovl_height = %d\n,
-   win_data-ovl_width, win_data-ovl_height);
-   DRM_DEBUG_KMS(paddr = 0x%lx\n, (unsigned long)win_data-dma_addr);
-   DRM_DEBUG_KMS(fb_width = %d, crtc_width = %d\n,
-   plane-fb_width, plane-crtc_width);
-}
-
 static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
 {
-   struct decon_win_data *win_data = ctx-win_data[win];
+   struct exynos_drm_plane *plane = ctx-planes[win];
unsigned long val;
+   int padding;
 
val = readl(ctx-regs + WINCON(win));
val = ~WINCONx_BPPMODE_MASK;
 
-   switch (win_data-pixel_format) {
+   switch (plane-pixel_format) {
case DRM_FORMAT_RGB565:
val |= WINCONx_BPPMODE_16BPP_565;
val |= WINCONx_BURSTLEN_16WORD;
@@ -397,7 +339,7 @@ static void 

[PATCH -v2 8/8] drm/exynos: track vblank events on a per crtc basis

2015-03-26 Thread Gustavo Padovan
From: Mandeep Singh Baines m...@chromium.org

The goal of the change is to make sure we send the vblank event on the
current vblank. My hope is to fix any races that might be causing flicker.
After this change I only see a flicker in the transition plymouth and
X11.

Simplified the code by tracking vblank events on a per-crtc basis. This
allowed me to remove all error paths from the callback. It also allowed
me to remove the vblank wait from the callback.

Signed-off-by: Mandeep Singh Baines m...@chromium.org
Signed-off-by: Gustavo Padovan gustavo.pado...@collabora.co.uk
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c | 92 +++-
 drivers/gpu/drm/exynos/exynos_drm_drv.c  | 13 -
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |  6 +--
 3 files changed, 44 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 47dd2b0..eb49195 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -34,9 +34,8 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int 
mode)
if (mode  DRM_MODE_DPMS_ON) {
/* wait for the completion of page flip. */
if (!wait_event_timeout(exynos_crtc-pending_flip_queue,
-   !atomic_read(exynos_crtc-pending_flip),
-   HZ/20))
-   atomic_set(exynos_crtc-pending_flip, 0);
+   (exynos_crtc-event == NULL), HZ/20))
+   exynos_crtc-event = NULL;
drm_crtc_vblank_off(crtc);
}
 
@@ -164,11 +163,10 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc 
*crtc,
 uint32_t page_flip_flags)
 {
struct drm_device *dev = crtc-dev;
-   struct exynos_drm_private *dev_priv = dev-dev_private;
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct drm_framebuffer *old_fb = crtc-primary-fb;
unsigned int crtc_w, crtc_h;
-   int ret = -EINVAL;
+   int ret;
 
/* when the page flip is requested, crtc's dpms should be on */
if (exynos_crtc-dpms  DRM_MODE_DPMS_ON) {
@@ -176,48 +174,49 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc 
*crtc,
return -EINVAL;
}
 
-   mutex_lock(dev-struct_mutex);
+   if (!event)
+   return -EINVAL;
 
-   if (event) {
-   /*
-* the pipe from user always is 0 so we can set pipe number
-* of current owner to event.
-*/
-   event-pipe = exynos_crtc-pipe;
+   spin_lock_irq(dev-event_lock);
+   if (exynos_crtc-event) {
+   ret = -EBUSY;
+   goto out;
+   }
 
-   ret = drm_vblank_get(dev, exynos_crtc-pipe);
-   if (ret) {
-   DRM_DEBUG(failed to acquire vblank counter\n);
+   ret = drm_vblank_get(dev, exynos_crtc-pipe);
+   if (ret) {
+   DRM_DEBUG(failed to acquire vblank counter\n);
+   goto out;
+   }
 
-   goto out;
-   }
+   exynos_crtc-event = event;
+   spin_unlock_irq(dev-event_lock);
 
+   /*
+* the pipe from user always is 0 so we can set pipe number
+* of current owner to event.
+*/
+   event-pipe = exynos_crtc-pipe;
+
+   crtc-primary-fb = fb;
+   crtc_w = fb-width - crtc-x;
+   crtc_h = fb-height - crtc-y;
+   ret = exynos_update_plane(crtc-primary, crtc, fb, 0, 0,
+ crtc_w, crtc_h, crtc-x, crtc-y,
+ crtc_w, crtc_h);
+   if (ret) {
+   crtc-primary-fb = old_fb;
spin_lock_irq(dev-event_lock);
-   list_add_tail(event-base.link,
-   dev_priv-pageflip_event_list);
-   atomic_set(exynos_crtc-pending_flip, 1);
+   exynos_crtc-event = NULL;
+   drm_vblank_put(dev, exynos_crtc-pipe);
spin_unlock_irq(dev-event_lock);
-
-   crtc-primary-fb = fb;
-   crtc_w = fb-width - crtc-x;
-   crtc_h = fb-height - crtc-y;
-   ret = exynos_update_plane(crtc-primary, crtc, fb, 0, 0,
- crtc_w, crtc_h, crtc-x, crtc-y,
- crtc_w, crtc_h);
-   if (ret) {
-   crtc-primary-fb = old_fb;
-
-   spin_lock_irq(dev-event_lock);
-   drm_vblank_put(dev, exynos_crtc-pipe);
-   list_del(event-base.link);
-   atomic_set(exynos_crtc-pending_flip, 0);
-   spin_unlock_irq(dev-event_lock);
-
-   goto out;
-   }
+   return ret;
}
+
+   return 0;
+
 out:
-   

Re: [rtc-linux] Re: [PATCH v2 2/2] mfd: sec-core: Modify RTC compatible name of S2MPS13

2015-03-26 Thread Lee Jones
On Tue, 24 Mar 2015, Krzysztof Kozlowski wrote:

 2015-03-23 13:34 GMT+01:00 Lee Jones lee.jo...@linaro.org:
  On Tue, 17 Mar 2015, Krzysztof Kozlowski wrote:
 
  From: Chanwoo Choi cw00.c...@samsung.com
 
  This patch modify the RTC compatible name of S2MPS13 because S2MPS13's RTC 
  is
  equal to S2MPS14's RTC.
 
  Cc: Lee Jones lee.jo...@linaro.org
  Suggested-by: Krzysztof Kozlowski k.kozlow...@samsung.com
  Signed-off-by: Chanwoo Choi cw00.c...@samsung.com
  Signed-off-by: Krzysztof Kozlowski k.kozlow...@samsung.com
 
  ---
 
  Changes since v1:
  1. New patch.
  ---
   drivers/mfd/sec-core.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)
 
  Applied, thanks.
 
 Hi,
 
 Sorry for the mess but we did this wrong.
 The S2MPS13 RTC is slightly different than S2MPS14 and that difference
 is important. It is embarrassing... but the difference was written
 small-print as a note in datasheet. Really. I found it after carefully
 comparing two PDFs. The impact of difference was not detected because
 of error in DTS for Exynos5433-based board.
 
 This patch should be dropped (or reverted) and s2mps13-rtc should be
 used for S2MPS13 RTC mfd_cell. The RTC driver (rtc/rtxc-s5m) should
 have its own support for RTC which I will add in separate patch.
 
 Lee, once again sorry for the mess. How would you like to proceed? Can
 you just drop this commit?

Patch removed -- panic averted.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
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 1/3] drm/exynos: mixer: add 2x scaling to mixer_graph_buffer

2015-03-26 Thread Gustavo Padovan
Hi Tobias,

2015-03-26 Tobias Jakobi tjak...@math.uni-bielefeld.de:

 While the VP (video processor) supports arbitrary scaling
 of its input, the mixer just supports a simple 2x (line
 doubling) scaling. Expose this functionality and exit
 early when an unsupported scaling configuration is
 encountered.
 
 This was tested with modetest's DRM plane test (from
 the libdrm test suite) on an Odroid-X2 (Exynos4412).
 
 Signed-off-by: Tobias Jakobi tjak...@math.uni-bielefeld.de
 ---
  drivers/gpu/drm/exynos/exynos_mixer.c | 38 
 +--
  1 file changed, 32 insertions(+), 6 deletions(-)
 
 diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
 b/drivers/gpu/drm/exynos/exynos_mixer.c
 index df547b6..7c38d3b 100644
 --- a/drivers/gpu/drm/exynos/exynos_mixer.c
 +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
 @@ -521,12 +521,37 @@ static void mixer_layer_update(struct mixer_context 
 *ctx)
   mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
  }
  
 +static int mixer_setup_scale(unsigned int src_w, unsigned int src_h,
 + unsigned int dst_w, unsigned int dst_h,
 + unsigned int *scale_w, unsigned int *scale_h)

I would keep calling these two vars x_ratio and y_ratio. I don't see a reason
to change the name here.

 +{
 + if (dst_w != src_w) {
 + if (dst_w == 2 * src_w)
 + *scale_w = 1;
 + else
 + goto fail;
 + }
 +
 + if (dst_h != src_h) {
 + if (dst_h == 2 * src_h)
 + *scale_h = 1;
 + else
 + goto fail;
 + }
 +
 + return 0;
 +
 +fail:
 + DRM_DEBUG_KMS(only 2x width/height scaling of plane supported\n);
 + return -1;

Use EPERM or ENOTSUPP. Or even true/false.

 +}
 +
  static void mixer_graph_buffer(struct mixer_context *ctx, int win)
  {
   struct mixer_resources *res = ctx-mixer_res;
   unsigned long flags;
   struct hdmi_win_data *win_data;
 - unsigned int x_ratio, y_ratio;
 + unsigned int x_ratio = 0, y_ratio = 0;
   unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
   dma_addr_t dma_addr;
   unsigned int fmt;
 @@ -550,9 +575,10 @@ static void mixer_graph_buffer(struct mixer_context 
 *ctx, int win)
   fmt = ARGB;
   }
  
 - /* 2x scaling feature */
 - x_ratio = 0;
 - y_ratio = 0;
 + /* check if mixer supports scaling setup */
 + if (mixer_setup_scale(win_data-src_width, win_data-src_height,
 + win_data-crtc_width, win_data-crtc_height,
 + x_ratio, y_ratio)) return;

You need to fix style here

if (mixer_setup_scale(win_data-src_width, win_data-src_height,
  win_data-crtc_width, win_data-crtc_height,  
  x_ratio, y_ratio))  
return; 


I think your patch is good after these things get fixes and we can go with it
and drop mine. Then I'll just rebase the alpha channel fix patch on top of
this one.

Gustavo
--
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] drm: Exynos: Respect framebuffer pitch for FIMD/Mixer

2015-03-26 Thread Inki Dae
Hello Javier,

Applied.

Could you use right prefix of the subject like below when you post patch?

'drm/exynos: ...', not 'drm: Exynos: ...'

Your email will be filtered from my mailbox if you don't use the right
prefix so I couldn't check and take care of your patch.

Thanks,
Inki Dae

On 2015년 03월 24일 17:57, Javier Martinez Canillas wrote:
 Hello Inki,
 
 On Tue, Mar 17, 2015 at 2:24 PM, Daniel Stone dani...@collabora.com wrote:
 When performing a modeset, use the framebuffer pitch value to set FIMD
 IMG_SIZE and Mixer SPAN registers. These are both defined as pitch - the
 distance between contiguous lines (bytes for FIMD, pixels for mixer).

 Fixes display on Snow (1366x768).

 Signed-off-by: Daniel Stone dani...@collabora.com
 Tested-by: Javier Martinez Canillas javier.marti...@collabora.co.uk
 
 Any comments on this patch? It would be great to pick this sooner
 rather than later since it fixes (at least) display output on Snow and
 HDMI output on Peach Pit/Pi.
 
 Best regards,
 Javier
 

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