Re: [RFC 04/10] memory: Add Tegra124 memory controller support

2014-07-01 Thread Hiroshi Doyu

Thierry Reding  writes:

> diff --git a/include/dt-bindings/memory/tegra124-mc.h 
> b/include/dt-bindings/memory/tegra124-mc.h
> new file mode 100644
> index ..6b1617ce022f
> --- /dev/null
> +++ b/include/dt-bindings/memory/tegra124-mc.h
> @@ -0,0 +1,30 @@
> +#ifndef DT_BINDINGS_MEMORY_TEGRA124_MC_H
> +#define DT_BINDINGS_MEMORY_TEGRA124_MC_H
> +
> +#define TEGRA_SWGROUP_DC   0
> +#define TEGRA_SWGROUP_DCB  1
> +#define TEGRA_SWGROUP_AFI  2
> +#define TEGRA_SWGROUP_AVPC 3
> +#define TEGRA_SWGROUP_HDA  4
> +#define TEGRA_SWGROUP_HC   5
> +#define TEGRA_SWGROUP_MSENC6
> +#define TEGRA_SWGROUP_PPCS 7
> +#define TEGRA_SWGROUP_SATA 8
> +#define TEGRA_SWGROUP_VDE  9
> +#define TEGRA_SWGROUP_MPCORELP 10
> +#define TEGRA_SWGROUP_MPCORE   11
> +#define TEGRA_SWGROUP_ISP2 12
> +#define TEGRA_SWGROUP_XUSB_HOST13
> +#define TEGRA_SWGROUP_XUSB_DEV 14
> +#define TEGRA_SWGROUP_ISP2B15
> +#define TEGRA_SWGROUP_TSEC 16
> +#define TEGRA_SWGROUP_A9AVP17
> +#define TEGRA_SWGROUP_GPU  18
> +#define TEGRA_SWGROUP_SDMMC1A  19
> +#define TEGRA_SWGROUP_SDMMC2A  20
> +#define TEGRA_SWGROUP_SDMMC3A  21
> +#define TEGRA_SWGROUP_SDMMC4A  22
> +#define TEGRA_SWGROUP_VIC  23
> +#define TEGRA_SWGROUP_VI   24
> +
> +#endif

In the SMMUv8 patch series, I have assigned unique IDs for all those
HWAs among Tegra SoC generations so that DT can provide which HWAs are
attached to that SoC. The SMMUv8 driver would be unified among Tegra
SoCs, then.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 04/10] memory: Add Tegra124 memory controller support

2014-07-01 Thread Hiroshi Doyu

Thierry Reding thierry.red...@gmail.com writes:

 diff --git a/include/dt-bindings/memory/tegra124-mc.h 
 b/include/dt-bindings/memory/tegra124-mc.h
 new file mode 100644
 index ..6b1617ce022f
 --- /dev/null
 +++ b/include/dt-bindings/memory/tegra124-mc.h
 @@ -0,0 +1,30 @@
 +#ifndef DT_BINDINGS_MEMORY_TEGRA124_MC_H
 +#define DT_BINDINGS_MEMORY_TEGRA124_MC_H
 +
 +#define TEGRA_SWGROUP_DC   0
 +#define TEGRA_SWGROUP_DCB  1
 +#define TEGRA_SWGROUP_AFI  2
 +#define TEGRA_SWGROUP_AVPC 3
 +#define TEGRA_SWGROUP_HDA  4
 +#define TEGRA_SWGROUP_HC   5
 +#define TEGRA_SWGROUP_MSENC6
 +#define TEGRA_SWGROUP_PPCS 7
 +#define TEGRA_SWGROUP_SATA 8
 +#define TEGRA_SWGROUP_VDE  9
 +#define TEGRA_SWGROUP_MPCORELP 10
 +#define TEGRA_SWGROUP_MPCORE   11
 +#define TEGRA_SWGROUP_ISP2 12
 +#define TEGRA_SWGROUP_XUSB_HOST13
 +#define TEGRA_SWGROUP_XUSB_DEV 14
 +#define TEGRA_SWGROUP_ISP2B15
 +#define TEGRA_SWGROUP_TSEC 16
 +#define TEGRA_SWGROUP_A9AVP17
 +#define TEGRA_SWGROUP_GPU  18
 +#define TEGRA_SWGROUP_SDMMC1A  19
 +#define TEGRA_SWGROUP_SDMMC2A  20
 +#define TEGRA_SWGROUP_SDMMC3A  21
 +#define TEGRA_SWGROUP_SDMMC4A  22
 +#define TEGRA_SWGROUP_VIC  23
 +#define TEGRA_SWGROUP_VI   24
 +
 +#endif

In the SMMUv8 patch series, I have assigned unique IDs for all those
HWAs among Tegra SoC generations so that DT can provide which HWAs are
attached to that SoC. The SMMUv8 driver would be unified among Tegra
SoCs, then.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 04/10] memory: Add Tegra124 memory controller support

2014-06-27 Thread Hiroshi DOyu

Thierry Reding  writes:

> From: Thierry Reding 
>
> The memory controller on NVIDIA Tegra124 exposes various knobs that can
> be used to tune the behaviour of the clients attached to it.
>
> Currently this driver sets up the latency allowance registers to the HW
> defaults. Eventually an API should be exported by this driver (via a
> custom API or a generic subsystem) to allow clients to register latency
> requirements.
>
> This driver also registers an IOMMU (SMMU) that's implemented by the
> memory controller.
>
> Signed-off-by: Thierry Reding 
> ---
>  drivers/memory/Kconfig   |9 +
>  drivers/memory/Makefile  |1 +
>  drivers/memory/tegra124-mc.c | 1945 
> ++
>  include/dt-bindings/memory/tegra124-mc.h |   30 +
>  4 files changed, 1985 insertions(+)
>  create mode 100644 drivers/memory/tegra124-mc.c
>  create mode 100644 include/dt-bindings/memory/tegra124-mc.h

I prefer reusing the existing SMMU and having MC and SMMU separated
since most of SMMU code are not different from functionality POV, and
new MC features are quite independent of SMMU.

If it's really convenient to combine MC and SMMU into one driver, we
could move "drivers/iomm/tegra-smmu.c" here first, and add MC features
on the top of it.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 09/10] drm/tegra: Add IOMMU support

2014-06-27 Thread Hiroshi DOyu

Thierry Reding  writes:

> From: Thierry Reding 
>
> When an IOMMU device is available on the platform bus, allocate an IOMMU
> domain and attach the display controllers to it. The display controllers
> can then scan out non-contiguous buffers by mapping them through the
> IOMMU.
>
> Signed-off-by: Thierry Reding 
> ---
>  drivers/gpu/drm/tegra/dc.c  |  21 
>  drivers/gpu/drm/tegra/drm.c |  17 
>  drivers/gpu/drm/tegra/drm.h |   3 +
>  drivers/gpu/drm/tegra/fb.c  |  16 ++-
>  drivers/gpu/drm/tegra/gem.c | 236 
> +++-
>  drivers/gpu/drm/tegra/gem.h |   4 +
>  6 files changed, 273 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> index afcca04f5367..0f7452d04811 100644
> --- a/drivers/gpu/drm/tegra/dc.c
> +++ b/drivers/gpu/drm/tegra/dc.c
> @@ -9,6 +9,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>
>  #include "dc.h"
> @@ -1283,8 +1284,18 @@ static int tegra_dc_init(struct host1x_client *client)
>  {
> struct drm_device *drm = dev_get_drvdata(client->parent);
> struct tegra_dc *dc = host1x_client_to_dc(client);
> +   struct tegra_drm *tegra = drm->dev_private;
> int err;
>
> +   if (tegra->domain) {
> +   err = iommu_attach_device(tegra->domain, dc->dev);

I wanted to keep device drivers iommu-free with the following:

http://patchwork.ozlabs.org/patch/354074/


> +   if (err < 0) {
> +   dev_err(dc->dev, "failed to attach to IOMMU: %d\n",
> +   err);
> +   return err;
> +   }
> +   }
> +
> drm_crtc_init(drm, >base, _crtc_funcs);
> drm_mode_crtc_set_gamma_size(>base, 256);
> drm_crtc_helper_add(>base, _crtc_helper_funcs);
> @@ -1318,7 +1329,9 @@ static int tegra_dc_init(struct host1x_client *client)
>
>  static int tegra_dc_exit(struct host1x_client *client)
>  {
> +   struct drm_device *drm = dev_get_drvdata(client->parent);
> struct tegra_dc *dc = host1x_client_to_dc(client);
> +   struct tegra_drm *tegra = drm->dev_private;
> int err;
>
> devm_free_irq(dc->dev, dc->irq, dc);
> @@ -1335,6 +1348,8 @@ static int tegra_dc_exit(struct host1x_client *client)
> return err;
> }
>
> +   iommu_detach_device(tegra->domain, dc->dev);
> +
> return 0;
>  }
>
> @@ -1462,6 +1477,12 @@ static int tegra_dc_probe(struct platform_device *pdev)
> return -ENXIO;
> }
>
> +   err = iommu_attach(>dev);
> +   if (err < 0) {
> +   dev_err(>dev, "failed to attach to IOMMU: %d\n", err);
> +   return err;
> +   }
> +
> INIT_LIST_HEAD(>client.list);
> dc->client.ops = _client_ops;
> dc->client.dev = >dev;
> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> index 59736bb810cd..1d2bbafad982 100644
> --- a/drivers/gpu/drm/tegra/drm.c
> +++ b/drivers/gpu/drm/tegra/drm.c
> @@ -8,6 +8,7 @@
>   */
>
>  #include 
> +#include 
>
>  #include "drm.h"
>  #include "gem.h"
> @@ -33,6 +34,16 @@ static int tegra_drm_load(struct drm_device *drm, unsigned 
> long flags)
> if (!tegra)
> return -ENOMEM;
>
> +   if (iommu_present(_bus_type)) {
> +   tegra->domain = iommu_domain_alloc(_bus_type);

Can we use "dma_iommu_mapping" instead of domain?

I thought that DMA API is on the top of IOMMU API so that it may be
cleaner to use only DMA API.


> +   if (IS_ERR(tegra->domain)) {
> +   kfree(tegra);
> +   return PTR_ERR(tegra->domain);
> +   }
> +
> +   drm_mm_init(>mm, 0, SZ_2G);
> +   }
> +
> mutex_init(>clients_lock);
> INIT_LIST_HEAD(>clients);
> drm->dev_private = tegra;
> @@ -71,6 +82,7 @@ static int tegra_drm_load(struct drm_device *drm, unsigned 
> long flags)
>  static int tegra_drm_unload(struct drm_device *drm)
>  {
> struct host1x_device *device = to_host1x_device(drm->dev);
> +   struct tegra_drm *tegra = drm->dev_private;
> int err;
>
> drm_kms_helper_poll_fini(drm);
> @@ -82,6 +94,11 @@ static int tegra_drm_unload(struct drm_device *drm)
> if (err < 0)
> return err;
>
> +   if (tegra->domain) {
> +   iommu_domain_free(tegra->domain);
> +   drm_mm_takedown(>mm);
> +   }
> +
> return 0;
>  }
>
> diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
> index 96d754e7b3eb..a07c796b7edc 100644
> --- a/drivers/gpu/drm/tegra/drm.h
> +++ b/drivers/gpu/drm/tegra/drm.h
> @@ -39,6 +39,9 @@ struct tegra_fbdev {
>  struct tegra_drm {
> struct drm_device *drm;
>
> +   struct iommu_domain *domain;
> +   struct drm_mm mm;
> +
> struct mutex clients_lock;
> struct list_head clients;
>
> diff --git a/drivers/gpu/drm/tegra/fb.c 

Re: [RFC 10/10] mmc: sdhci-tegra: Add IOMMU support

2014-06-27 Thread Hiroshi DOyu

Thierry Reding  writes:

> From: Thierry Reding 
>
> Attach to the device's master interface of the IOMMU at .probe() time.
> IOMMU support becomes available via the DMA mapping API interoperation
> code, but this explicit attachment is necessary to ensure proper probe
> order.
>
> Signed-off-by: Thierry Reding 
> ---
>  drivers/mmc/host/sdhci-tegra.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 33100d10d176..b884614fa4e6 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -15,6 +15,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -237,6 +238,11 @@ static int sdhci_tegra_probe(struct platform_device 
> *pdev)
>   match = of_match_device(sdhci_tegra_dt_match, >dev);
>   if (!match)
>   return -EINVAL;
> +
> + rc = iommu_attach(>dev);
> + if (rc < 0)
> + return rc;
> +

I thought that, if we consider that ->probe() should include minimal H/W
probing so that DMA API call in ->probe() could be deferred after
->probe() and till it's in use actually, like opening a device node. For
me this decision(minimal h/w probe) seemed logical but it would add a
new restriction. One advantage is that we could still keep all drivers
wihtout any IOMMU code if it doesn't call DMA API in ->probe().

>   soc_data = match->data;
>  
>   host = sdhci_pltfm_init(pdev, soc_data->pdata, 0);
> @@ -310,6 +316,8 @@ static int sdhci_tegra_remove(struct platform_device 
> *pdev)
>   clk_disable_unprepare(pltfm_host->clk);
>   clk_put(pltfm_host->clk);
>  
> + iommu_detach(>dev);
> +
>   sdhci_pltfm_free(pdev);
>  
>   return 0;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 09/10] drm/tegra: Add IOMMU support

2014-06-27 Thread Hiroshi DOyu

Thierry Reding thierry.red...@gmail.com writes:

 From: Thierry Reding tred...@nvidia.com

 When an IOMMU device is available on the platform bus, allocate an IOMMU
 domain and attach the display controllers to it. The display controllers
 can then scan out non-contiguous buffers by mapping them through the
 IOMMU.

 Signed-off-by: Thierry Reding tred...@nvidia.com
 ---
  drivers/gpu/drm/tegra/dc.c  |  21 
  drivers/gpu/drm/tegra/drm.c |  17 
  drivers/gpu/drm/tegra/drm.h |   3 +
  drivers/gpu/drm/tegra/fb.c  |  16 ++-
  drivers/gpu/drm/tegra/gem.c | 236 
 +++-
  drivers/gpu/drm/tegra/gem.h |   4 +
  6 files changed, 273 insertions(+), 24 deletions(-)

 diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
 index afcca04f5367..0f7452d04811 100644
 --- a/drivers/gpu/drm/tegra/dc.c
 +++ b/drivers/gpu/drm/tegra/dc.c
 @@ -9,6 +9,7 @@

  #include linux/clk.h
  #include linux/debugfs.h
 +#include linux/iommu.h
  #include linux/reset.h

  #include dc.h
 @@ -1283,8 +1284,18 @@ static int tegra_dc_init(struct host1x_client *client)
  {
 struct drm_device *drm = dev_get_drvdata(client-parent);
 struct tegra_dc *dc = host1x_client_to_dc(client);
 +   struct tegra_drm *tegra = drm-dev_private;
 int err;

 +   if (tegra-domain) {
 +   err = iommu_attach_device(tegra-domain, dc-dev);

I wanted to keep device drivers iommu-free with the following:

http://patchwork.ozlabs.org/patch/354074/


 +   if (err  0) {
 +   dev_err(dc-dev, failed to attach to IOMMU: %d\n,
 +   err);
 +   return err;
 +   }
 +   }
 +
 drm_crtc_init(drm, dc-base, tegra_crtc_funcs);
 drm_mode_crtc_set_gamma_size(dc-base, 256);
 drm_crtc_helper_add(dc-base, tegra_crtc_helper_funcs);
 @@ -1318,7 +1329,9 @@ static int tegra_dc_init(struct host1x_client *client)

  static int tegra_dc_exit(struct host1x_client *client)
  {
 +   struct drm_device *drm = dev_get_drvdata(client-parent);
 struct tegra_dc *dc = host1x_client_to_dc(client);
 +   struct tegra_drm *tegra = drm-dev_private;
 int err;

 devm_free_irq(dc-dev, dc-irq, dc);
 @@ -1335,6 +1348,8 @@ static int tegra_dc_exit(struct host1x_client *client)
 return err;
 }

 +   iommu_detach_device(tegra-domain, dc-dev);
 +
 return 0;
  }

 @@ -1462,6 +1477,12 @@ static int tegra_dc_probe(struct platform_device *pdev)
 return -ENXIO;
 }

 +   err = iommu_attach(pdev-dev);
 +   if (err  0) {
 +   dev_err(pdev-dev, failed to attach to IOMMU: %d\n, err);
 +   return err;
 +   }
 +
 INIT_LIST_HEAD(dc-client.list);
 dc-client.ops = dc_client_ops;
 dc-client.dev = pdev-dev;
 diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
 index 59736bb810cd..1d2bbafad982 100644
 --- a/drivers/gpu/drm/tegra/drm.c
 +++ b/drivers/gpu/drm/tegra/drm.c
 @@ -8,6 +8,7 @@
   */

  #include linux/host1x.h
 +#include linux/iommu.h

  #include drm.h
  #include gem.h
 @@ -33,6 +34,16 @@ static int tegra_drm_load(struct drm_device *drm, unsigned 
 long flags)
 if (!tegra)
 return -ENOMEM;

 +   if (iommu_present(platform_bus_type)) {
 +   tegra-domain = iommu_domain_alloc(platform_bus_type);

Can we use dma_iommu_mapping instead of domain?

I thought that DMA API is on the top of IOMMU API so that it may be
cleaner to use only DMA API.


 +   if (IS_ERR(tegra-domain)) {
 +   kfree(tegra);
 +   return PTR_ERR(tegra-domain);
 +   }
 +
 +   drm_mm_init(tegra-mm, 0, SZ_2G);
 +   }
 +
 mutex_init(tegra-clients_lock);
 INIT_LIST_HEAD(tegra-clients);
 drm-dev_private = tegra;
 @@ -71,6 +82,7 @@ static int tegra_drm_load(struct drm_device *drm, unsigned 
 long flags)
  static int tegra_drm_unload(struct drm_device *drm)
  {
 struct host1x_device *device = to_host1x_device(drm-dev);
 +   struct tegra_drm *tegra = drm-dev_private;
 int err;

 drm_kms_helper_poll_fini(drm);
 @@ -82,6 +94,11 @@ static int tegra_drm_unload(struct drm_device *drm)
 if (err  0)
 return err;

 +   if (tegra-domain) {
 +   iommu_domain_free(tegra-domain);
 +   drm_mm_takedown(tegra-mm);
 +   }
 +
 return 0;
  }

 diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
 index 96d754e7b3eb..a07c796b7edc 100644
 --- a/drivers/gpu/drm/tegra/drm.h
 +++ b/drivers/gpu/drm/tegra/drm.h
 @@ -39,6 +39,9 @@ struct tegra_fbdev {
  struct tegra_drm {
 struct drm_device *drm;

 +   struct iommu_domain *domain;
 +   struct drm_mm mm;
 +
 struct mutex clients_lock;
 struct list_head clients;

 diff --git 

Re: [RFC 10/10] mmc: sdhci-tegra: Add IOMMU support

2014-06-27 Thread Hiroshi DOyu

Thierry Reding thierry.red...@gmail.com writes:

 From: Thierry Reding tred...@nvidia.com

 Attach to the device's master interface of the IOMMU at .probe() time.
 IOMMU support becomes available via the DMA mapping API interoperation
 code, but this explicit attachment is necessary to ensure proper probe
 order.

 Signed-off-by: Thierry Reding tred...@nvidia.com
 ---
  drivers/mmc/host/sdhci-tegra.c | 8 
  1 file changed, 8 insertions(+)

 diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
 index 33100d10d176..b884614fa4e6 100644
 --- a/drivers/mmc/host/sdhci-tegra.c
 +++ b/drivers/mmc/host/sdhci-tegra.c
 @@ -15,6 +15,7 @@
  #include linux/err.h
  #include linux/module.h
  #include linux/init.h
 +#include linux/iommu.h
  #include linux/platform_device.h
  #include linux/clk.h
  #include linux/io.h
 @@ -237,6 +238,11 @@ static int sdhci_tegra_probe(struct platform_device 
 *pdev)
   match = of_match_device(sdhci_tegra_dt_match, pdev-dev);
   if (!match)
   return -EINVAL;
 +
 + rc = iommu_attach(pdev-dev);
 + if (rc  0)
 + return rc;
 +

I thought that, if we consider that -probe() should include minimal H/W
probing so that DMA API call in -probe() could be deferred after
-probe() and till it's in use actually, like opening a device node. For
me this decision(minimal h/w probe) seemed logical but it would add a
new restriction. One advantage is that we could still keep all drivers
wihtout any IOMMU code if it doesn't call DMA API in -probe().

   soc_data = match-data;
  
   host = sdhci_pltfm_init(pdev, soc_data-pdata, 0);
 @@ -310,6 +316,8 @@ static int sdhci_tegra_remove(struct platform_device 
 *pdev)
   clk_disable_unprepare(pltfm_host-clk);
   clk_put(pltfm_host-clk);
  
 + iommu_detach(pdev-dev);
 +
   sdhci_pltfm_free(pdev);
  
   return 0;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 04/10] memory: Add Tegra124 memory controller support

2014-06-27 Thread Hiroshi DOyu

Thierry Reding thierry.red...@gmail.com writes:

 From: Thierry Reding tred...@nvidia.com

 The memory controller on NVIDIA Tegra124 exposes various knobs that can
 be used to tune the behaviour of the clients attached to it.

 Currently this driver sets up the latency allowance registers to the HW
 defaults. Eventually an API should be exported by this driver (via a
 custom API or a generic subsystem) to allow clients to register latency
 requirements.

 This driver also registers an IOMMU (SMMU) that's implemented by the
 memory controller.

 Signed-off-by: Thierry Reding tred...@nvidia.com
 ---
  drivers/memory/Kconfig   |9 +
  drivers/memory/Makefile  |1 +
  drivers/memory/tegra124-mc.c | 1945 
 ++
  include/dt-bindings/memory/tegra124-mc.h |   30 +
  4 files changed, 1985 insertions(+)
  create mode 100644 drivers/memory/tegra124-mc.c
  create mode 100644 include/dt-bindings/memory/tegra124-mc.h

I prefer reusing the existing SMMU and having MC and SMMU separated
since most of SMMU code are not different from functionality POV, and
new MC features are quite independent of SMMU.

If it's really convenient to combine MC and SMMU into one driver, we
could move drivers/iomm/tegra-smmu.c here first, and add MC features
on the top of it.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] devicetree: Add generic IOMMU device tree bindings

2014-05-30 Thread Hiroshi Doyu

Arnd Bergmann  writes:

>> > +Multiple-master IOMMU:
>> > +--
>> > +
>> > +   iommu {
>> > +   /* the specifier represents the ID of the master */
>> > +   #address-cells = <1>;
>> > +   #size-cells = <0>;
>> > +   };
>> > +
>> > +   master {
>> > +   /* device has master ID 42 in the IOMMU */
>> > +   iommus = <&/iommu 42>;
>> > +   };
>> 
>> Presumably the ID would be the streamID on ARM's SMMU. How would a
>> master with 8 streamIDs be described? This is what Calxeda midway has
>> for SATA and I would expect that to be somewhat common. Either you
>> need some ID masking or you'll have lots of duplication when you have
>> windows.
>
> I don't understand the problem. If you have stream IDs 0 through 7,
> you would have
>
>   master@a {
>   ...
>   iommus = < 0>;
>   };
>
>   master@b {
>   ...
>   iommus = < 1;
>   };
>
>   ...
>
>   master@12 {
>   ...
>   iommus = < 7;
>   };
>
> and you don't need a window at all. Why would you need a mask of
> some sort?

IIUC the original problem, "a master with 8 streamIDs" means something
like below, where some devices have multiple IDs but some have a
single. A sinle #address-cells cannot afford those 2 masters at once.

   iommu {
   /* the specifier represents the ID of the master */
   #address-cells = <1>;
   #size-cells = <0>;
   };

master@a {
...
iommus = < 1 2 3>; # 3 IDs
};

master@b {
...
iommus = < 4>; # 1 ID
};

Tegra,SMMU has a similar problem and we have used a fixed size bitmap(64
bit) to afford 64 stream IDs so that a single device can hold multiple
IDs. If we apply the same bitmap to the above exmaple:

   iommu {
   /* the specifier represents the ID of the master */
   #address-cells = <1>;
   #size-cells = <0>;
   };

master@a {
...
iommus = < (BIT(1) | BIT(2) | BIT(3))>; # IDs 1 2 3
};

master@b {
...
iommus = < BIT(4)>; # ID 4
};

The disadvantage of this is that this limits the max number of streamIDs
to support. If # of streamID is increased later more than 64, this
format cannot cover any more. You have to predict the max # of streamIDs
in advance if steamID is statically assigned.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] devicetree: Add generic IOMMU device tree bindings

2014-05-30 Thread Hiroshi Doyu

Arnd Bergmann a...@arndb.de writes:

  +Multiple-master IOMMU:
  +--
  +
  +   iommu {
  +   /* the specifier represents the ID of the master */
  +   #address-cells = 1;
  +   #size-cells = 0;
  +   };
  +
  +   master {
  +   /* device has master ID 42 in the IOMMU */
  +   iommus = /iommu 42;
  +   };
 
 Presumably the ID would be the streamID on ARM's SMMU. How would a
 master with 8 streamIDs be described? This is what Calxeda midway has
 for SATA and I would expect that to be somewhat common. Either you
 need some ID masking or you'll have lots of duplication when you have
 windows.

 I don't understand the problem. If you have stream IDs 0 through 7,
 you would have

   master@a {
   ...
   iommus = smmu 0;
   };

   master@b {
   ...
   iommus = smmu 1;
   };

   ...

   master@12 {
   ...
   iommus = smmu 7;
   };

 and you don't need a window at all. Why would you need a mask of
 some sort?

IIUC the original problem, a master with 8 streamIDs means something
like below, where some devices have multiple IDs but some have a
single. A sinle #address-cells cannot afford those 2 masters at once.

   iommu {
   /* the specifier represents the ID of the master */
   #address-cells = 1;
   #size-cells = 0;
   };

master@a {
...
iommus = smmu 1 2 3; # 3 IDs
};

master@b {
...
iommus = smmu 4; # 1 ID
};

Tegra,SMMU has a similar problem and we have used a fixed size bitmap(64
bit) to afford 64 stream IDs so that a single device can hold multiple
IDs. If we apply the same bitmap to the above exmaple:

   iommu {
   /* the specifier represents the ID of the master */
   #address-cells = 1;
   #size-cells = 0;
   };

master@a {
...
iommus = smmu (BIT(1) | BIT(2) | BIT(3)); # IDs 1 2 3
};

master@b {
...
iommus = smmu BIT(4); # ID 4
};

The disadvantage of this is that this limits the max number of streamIDs
to support. If # of streamID is increased later more than 64, this
format cannot cover any more. You have to predict the max # of streamIDs
in advance if steamID is statically assigned.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv6+ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-14 Thread Hiroshi Doyu
Hiroshi Doyu  wrote @ Thu, 12 Dec 2013 14:14:04 +0200 (EET):

> > > From 8f7c0404aa68f0e8dbe0babc240590f6528ecc1f Mon Sep 17 00:00:00 2001
> > > From: Hiroshi Doyu 
> > > Date: Fri, 15 Nov 2013 10:52:53 +0200
> > > Subject: [PATCH] of: introduce of_property_for_each_phandle_with_args()
> > >
> > > Iterating over a property containing a list of phandles with arguments
> > > is a common operation for device drivers. This patch adds a new
> > > of_property_for_each_phandle_with_args() macro to make the iteration
> > > simpler.
> > >
> > > Signed-off-by: Hiroshi Doyu 
> > > Cc: Rob Herring 

> > > ---
> > >  drivers/of/base.c  | 46 ++
> > >  include/linux/of.h | 32 
> > >  2 files changed, 78 insertions(+)
> > >
> > > diff --git a/drivers/of/base.c b/drivers/of/base.c
> > > index f807d0e..cd4ab05 100644
> > > --- a/drivers/of/base.c
> > > +++ b/drivers/of/base.c
> > > @@ -1201,6 +1201,52 @@ void of_print_phandle_args(const char *msg, const 
> > > struct of_phandle_args *args)
> > >   printk("\n");
> > >  }
> > >
> > > +const __be32 *of_phandle_iter_next(const char *cells_name, int 
> > > cell_count,
> > > +const __be32 *cur, const __be32 *end,
> > > +struct of_phandle_args *out_args)
> > 
> > Having to pass in cells_name, cell_count, cur and end each time seems a
> > little odd. Can a state structure be used instead?
> > 
> > struct of_phandle_iter_state {
> > const char *cells_name;
> > int cells_count;
> > const __be32 *cur;
> > const __be32 *end;
> > struct of_phandle_args out_args;
> > }
> > 
> > Make the caller provide one of those and fill it in with the init
> > function.
> 
> I rewrote this a few times and so now I have a few version of this
> implementations :-) The above proposal is similar to the version v6+++
> mentioned in the above patch note:
> 
> > > v6+++:
> > > Introduced a new struct "of_phandle_iter" to keep the state when
> > > iterating over the list.
> 
> which is:
> 
>   [RFC][PATCHv6+++ 01/13] of: introduce 
> of_property_for_earch_phandle_with_args()
> http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007087.html
> 
> Stephen seemed to prefer the version without state struct. I like the
> idea to not pass the same arguments repeatly. Instead, wrapping them
> in a struct with state may look better.
> 
> So if Stephen agrees, I'll rewrite the version with state struct
> again.

Stephen, let me know what you think.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv7 04/12] driver/core: populate devices in order for IOMMUs

2013-12-14 Thread Hiroshi Doyu
Thierry Reding  wrote @ Sat, 14 Dec 2013 13:24:22 
+0100:

> * PGP Signed by an unknown key
> 
> On Thu, Dec 12, 2013 at 06:14:02PM -0800, Greg KH wrote:
> > On Thu, Dec 12, 2013 at 11:39:20AM +, Grant Likely wrote:
> > > On Thu, 12 Dec 2013 09:57:05 +0200, Hiroshi Doyu  wrote:
> > > > IOMMU devices on the bus need to be poplulated first, then iommu
> > > > master devices are done later.
> > > > 
> > > > With CONFIG_OF_IOMMU, "iommus=" DT binding would be used to identify
> > > > whether a device can be an iommu msater or not. If a device can, we'll
> > > > defer to populate that device till an iommu device is populated. Then,
> > > > those deferred iommu master devices are populated and configured with
> > > > help of the already populated iommu device.
> > > > 
> > > > Signed-off-by: Hiroshi Doyu 
> > > > Cc: Greg Kroah-Hartman 
> > > > ---
> > > > This is related to the following discussion:
> > > >   [RFC PATCH] Documentation: devicetree: add description for generic 
> > > > bus properties
> > > >   
> > > > http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/215042.html
> > > > 
> > > > v6:
> > > > Spinned off only driver core part from:
> > > >   [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs
> > > > 
> > > > v5:
> > > > Use "iommus=" binding instread of arm,smmu's "#stream-id-cells".
> > > > 
> > > > v4:
> > > > This is newly added, and the successor of the following RFC:
> > > >   [RFC][PATCHv3+ 1/2] driver/core: Add of_iommu_attach()
> > > >   
> > > > http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006914.html
> > > > 
> > > > Signed-off-by: Hiroshi Doyu 
> > > > ---
> > > >  drivers/base/dd.c | 5 +
> > > >  1 file changed, 5 insertions(+)
> > > > 
> > > > diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> > > > index 0605176..0605f52 100644
> > > > --- a/drivers/base/dd.c
> > > > +++ b/drivers/base/dd.c
> > > > @@ -25,6 +25,7 @@
> > > >  #include 
> > > >  #include 
> > > >  #include 
> > > > +#include 
> > > >  
> > > >  #include "base.h"
> > > >  #include "power/power.h"
> > > > @@ -273,6 +274,10 @@ static int really_probe(struct device *dev, struct 
> > > > device_driver *drv)
> > > >  
> > > > dev->driver = drv;
> > > >  
> > > > +   ret = of_iommu_attach(dev);
> > > > +   if (ret)
> > > > +   goto probe_failed;
> > > > +
> > > 
> > > As discussed before, I really don't think hooking in to dd.c is the
> > > right thing to do here, and certainly not as a device tree specific
> > > function. ACPI or PCI described devices may have the same constraints
> > > and those won't have DT descriptions.
> > 
> > I agree, this shouldn't be in the driver core.
> 
> Okay, so what would be an alternative? Grant's objection makes sense and
> we could easily just wrap the call to of_iommu_attach() within a generic
> iommu_attach() that could decide at runtime which exact implementation
> to call, depending on whether the device is DT, ACPI, PCI or whatnot.
> 
> If we don't want something like that in the core either, then the only
> other alternative would be to call this from each driver. However given
> the desire to handle IOMMUs completely transparently for device drivers
> that would be missing the point.

What about using "bus_notifier" to send -EPROBE_DEFER?

The current bus_notifier framework doesn't have the ability to defer
the probe, but I may think that this change is acceptable relatively.

The fundamental problem is that IOMMU doesn't follow the exact bus
model like "chained IOMMU" cases, but this discussion may take long to
be solved. I think that "bus_notifier" with send -EPROBE_DEFER would
cover most of the normal cases, like normal IOMMU device probe
population order.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv7 04/12] driver/core: populate devices in order for IOMMUs

2013-12-14 Thread Hiroshi Doyu
Thierry Reding thierry.red...@gmail.com wrote @ Sat, 14 Dec 2013 13:24:22 
+0100:

 * PGP Signed by an unknown key
 
 On Thu, Dec 12, 2013 at 06:14:02PM -0800, Greg KH wrote:
  On Thu, Dec 12, 2013 at 11:39:20AM +, Grant Likely wrote:
   On Thu, 12 Dec 2013 09:57:05 +0200, Hiroshi Doyu hd...@nvidia.com wrote:
IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, iommus= DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an iommu device is populated. Then,
those deferred iommu master devices are populated and configured with
help of the already populated iommu device.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
---
This is related to the following discussion:
  [RFC PATCH] Documentation: devicetree: add description for generic 
bus properties
  
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/215042.html

v6:
Spinned off only driver core part from:
  [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

v5:
Use iommus= binding instread of arm,smmu's #stream-id-cells.

v4:
This is newly added, and the successor of the following RFC:
  [RFC][PATCHv3+ 1/2] driver/core: Add of_iommu_attach()
  
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006914.html

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/base/dd.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0605176..0605f52 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -25,6 +25,7 @@
 #include linux/async.h
 #include linux/pm_runtime.h
 #include linux/pinctrl/devinfo.h
+#include linux/of_iommu.h
 
 #include base.h
 #include power/power.h
@@ -273,6 +274,10 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
 
dev-driver = drv;
 
+   ret = of_iommu_attach(dev);
+   if (ret)
+   goto probe_failed;
+
   
   As discussed before, I really don't think hooking in to dd.c is the
   right thing to do here, and certainly not as a device tree specific
   function. ACPI or PCI described devices may have the same constraints
   and those won't have DT descriptions.
  
  I agree, this shouldn't be in the driver core.
 
 Okay, so what would be an alternative? Grant's objection makes sense and
 we could easily just wrap the call to of_iommu_attach() within a generic
 iommu_attach() that could decide at runtime which exact implementation
 to call, depending on whether the device is DT, ACPI, PCI or whatnot.
 
 If we don't want something like that in the core either, then the only
 other alternative would be to call this from each driver. However given
 the desire to handle IOMMUs completely transparently for device drivers
 that would be missing the point.

What about using bus_notifier to send -EPROBE_DEFER?

The current bus_notifier framework doesn't have the ability to defer
the probe, but I may think that this change is acceptable relatively.

The fundamental problem is that IOMMU doesn't follow the exact bus
model like chained IOMMU cases, but this discussion may take long to
be solved. I think that bus_notifier with send -EPROBE_DEFER would
cover most of the normal cases, like normal IOMMU device probe
population order.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv6+ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-14 Thread Hiroshi Doyu
Hiroshi Doyu hd...@nvidia.com wrote @ Thu, 12 Dec 2013 14:14:04 +0200 (EET):

   From 8f7c0404aa68f0e8dbe0babc240590f6528ecc1f Mon Sep 17 00:00:00 2001
   From: Hiroshi Doyu hd...@nvidia.com
   Date: Fri, 15 Nov 2013 10:52:53 +0200
   Subject: [PATCH] of: introduce of_property_for_each_phandle_with_args()
  
   Iterating over a property containing a list of phandles with arguments
   is a common operation for device drivers. This patch adds a new
   of_property_for_each_phandle_with_args() macro to make the iteration
   simpler.
  
   Signed-off-by: Hiroshi Doyu hd...@nvidia.com
   Cc: Rob Herring robherri...@gmail.com

   ---
drivers/of/base.c  | 46 ++
include/linux/of.h | 32 
2 files changed, 78 insertions(+)
  
   diff --git a/drivers/of/base.c b/drivers/of/base.c
   index f807d0e..cd4ab05 100644
   --- a/drivers/of/base.c
   +++ b/drivers/of/base.c
   @@ -1201,6 +1201,52 @@ void of_print_phandle_args(const char *msg, const 
   struct of_phandle_args *args)
 printk(\n);
}
  
   +const __be32 *of_phandle_iter_next(const char *cells_name, int 
   cell_count,
   +const __be32 *cur, const __be32 *end,
   +struct of_phandle_args *out_args)
  
  Having to pass in cells_name, cell_count, cur and end each time seems a
  little odd. Can a state structure be used instead?
  
  struct of_phandle_iter_state {
  const char *cells_name;
  int cells_count;
  const __be32 *cur;
  const __be32 *end;
  struct of_phandle_args out_args;
  }
  
  Make the caller provide one of those and fill it in with the init
  function.
 
 I rewrote this a few times and so now I have a few version of this
 implementations :-) The above proposal is similar to the version v6+++
 mentioned in the above patch note:
 
   v6+++:
   Introduced a new struct of_phandle_iter to keep the state when
   iterating over the list.
 
 which is:
 
   [RFC][PATCHv6+++ 01/13] of: introduce 
 of_property_for_earch_phandle_with_args()
 http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007087.html
 
 Stephen seemed to prefer the version without state struct. I like the
 idea to not pass the same arguments repeatly. Instead, wrapping them
 in a struct with state may look better.
 
 So if Stephen agrees, I'll rewrite the version with state struct
 again.

Stephen, let me know what you think.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv6+ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-12 Thread Hiroshi Doyu
Grant Likely  wrote @ Thu, 12 Dec 2013 12:34:17 +0100:

> On Wed, 11 Dec 2013 14:33:38 +0100, Hiroshi Doyu  wrote:
> > Hi Grant,
> >
> > Grant Likely  wrote @ Wed, 11 Dec 2013 14:28:45 
> > +0100:
> >
> > > On Thu, 21 Nov 2013 11:57:00 -0700, Stephen Warren 
> > >  wrote:
> > > > On 11/21/2013 10:17 AM, Hiroshi Doyu wrote:
> > > > > Iterating over a property containing a list of phandles with arguments
> > > > > is a common operation for device drivers. This patch adds a new
> > > > > of_property_for_each_phandle_with_args() macro to make the iteration
> > > > > simpler.
> > > > >
> > > > > Signed-off-by: Hiroshi Doyu 
> > > > > ---
> > > > > v6+:
> > > > > Use the description, which Grant Likely proposed, to be full enough
> > > > > that a future reader can figure out why a patch was written.
> > > > >   
> > > > > http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007062.html
> > ...
> >
> > > That's right, I forgot I said that. Yes please fix the implementation.
> >
> > Here's the latest. I'll include this with the next v7 series.
> >
> > Can I get your Acked-by with this?
> >
> > --8<
> >
> > From 8f7c0404aa68f0e8dbe0babc240590f6528ecc1f Mon Sep 17 00:00:00 2001
> > From: Hiroshi Doyu 
> > Date: Fri, 15 Nov 2013 10:52:53 +0200
> > Subject: [PATCH] of: introduce of_property_for_each_phandle_with_args()
> >
> > Iterating over a property containing a list of phandles with arguments
> > is a common operation for device drivers. This patch adds a new
> > of_property_for_each_phandle_with_args() macro to make the iteration
> > simpler.
> >
> > Signed-off-by: Hiroshi Doyu 
> > Cc: Rob Herring 
> > ---
> > v7:
> > Fixed some minors pointed by Rob and Stephen.
> >
> > v6:
> > Iterate without intrducing a new struct.
> >
> > v6+++:
> > Introduced a new struct "of_phandle_iter" to keep the state when
> > iterating over the list.
> >
> > v6++:
> > Optimized to avoid O(n^2), suggested by Stephen Warren.
> > http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html
> >
> > I didn't introduce any struct to hold params and state here.
> >
> > v6+:
> > Use the description, which Grant Likely proposed, to be full enough
> > that a future reader can figure out why a patch was written.
> >
> > v5:
> > New patch for v5.
> >
> > Signed-off-by: Hiroshi Doyu 
> > ---
> >  drivers/of/base.c  | 46 ++
> >  include/linux/of.h | 32 
> >  2 files changed, 78 insertions(+)
> >
> > diff --git a/drivers/of/base.c b/drivers/of/base.c
> > index f807d0e..cd4ab05 100644
> > --- a/drivers/of/base.c
> > +++ b/drivers/of/base.c
> > @@ -1201,6 +1201,52 @@ void of_print_phandle_args(const char *msg, const 
> > struct of_phandle_args *args)
> >   printk("\n");
> >  }
> >
> > +const __be32 *of_phandle_iter_next(const char *cells_name, int cell_count,
> > +const __be32 *cur, const __be32 *end,
> > +struct of_phandle_args *out_args)
> 
> Having to pass in cells_name, cell_count, cur and end each time seems a
> little odd. Can a state structure be used instead?
> 
> struct of_phandle_iter_state {
> const char *cells_name;
> int cells_count;
> const __be32 *cur;
> const __be32 *end;
> struct of_phandle_args out_args;
> }
> 
> Make the caller provide one of those and fill it in with the init
> function.

I rewrote this a few times and so now I have a few version of this
implementations :-) The above proposal is similar to the version v6+++
mentioned in the above patch note:

> > v6+++:
> > Introduced a new struct "of_phandle_iter" to keep the state when
> > iterating over the list.

which is:

  [RFC][PATCHv6+++ 01/13] of: introduce 
of_property_for_earch_phandle_with_args()
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007087.html

Stephen seemed to prefer the version without state struct. I like the
idea to not pass the same arguments repeatly. Instead, wrapping them
in a struct with state may look better.

So if Stephen agrees, I'll rewrite the version with state struct
again.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 05/12] iommu/core: add ops->{bound,unbind}_driver()

2013-12-12 Thread Hiroshi Doyu
ops->{bound,unbind}_driver() functions are called at
BUS_NOTIFY_{BOUND,UNBIND}_DRIVER respectively.

This is necessary to control the device population order. IOMMU master
devices depend on an IOMMU device instanciation. IOMMU master devices
can be registered to an IOMMU only after it's successfully
populated. This IOMMU registration is done via
ops->bound_driver(). Currently this population can be deferred if
depending IOMMU device hasn't yet been populated in driver core. This
cannot be done via ops->add_device() since after add_device() device's
population/instanciation can be still deferred via probe().

Signed-off-by: Hiroshi Doyu 
---
v6:
New for v6.

Signed-off-by: Hiroshi Doyu 
---
 drivers/iommu/iommu.c | 13 +++--
 include/linux/iommu.h |  4 
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index efc..5469d36 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -540,14 +540,23 @@ static int iommu_bus_notifier(struct notifier_block *nb,
 * ADD/DEL call into iommu driver ops if provided, which may
 * result in ADD/DEL notifiers to group->notifier
 */
-   if (action == BUS_NOTIFY_ADD_DEVICE) {
+   switch (action) {
+   case BUS_NOTIFY_ADD_DEVICE:
if (ops->add_device)
return ops->add_device(dev);
-   } else if (action == BUS_NOTIFY_DEL_DEVICE) {
+   case BUS_NOTIFY_DEL_DEVICE:
if (ops->remove_device && dev->iommu_group) {
ops->remove_device(dev);
return 0;
}
+   case BUS_NOTIFY_BOUND_DRIVER:
+   if (ops->bound_driver)
+   ops->bound_driver(dev);
+   break;
+   case BUS_NOTIFY_UNBIND_DRIVER:
+   if (ops->unbind_driver)
+   ops->unbind_driver(dev);
+   break;
}
 
/*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index a444c79..a0e92be 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -96,6 +96,8 @@ enum iommu_attr {
  * @domain_has_cap: domain capabilities query
  * @add_device: add device to iommu grouping
  * @remove_device: remove device from iommu grouping
+ * @bound_driver: called at BUS_NOTIFY_BOUND_DRIVER
+ * @unbind_driver: called at BUS_NOTIFY_UNBIND_DRIVER
  * @domain_get_attr: Query domain attributes
  * @domain_set_attr: Change domain attributes
  * @pgsize_bitmap: bitmap of supported page sizes
@@ -114,6 +116,8 @@ struct iommu_ops {
  unsigned long cap);
int (*add_device)(struct device *dev);
void (*remove_device)(struct device *dev);
+   int (*bound_driver)(struct device *dev);
+   void (*unbind_driver)(struct device *dev);
int (*device_group)(struct device *dev, unsigned int *groupid);
int (*domain_get_attr)(struct iommu_domain *domain,
   enum iommu_attr attr, void *data);
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 03/12] iommu/of: check if dependee iommu is ready or not

2013-12-12 Thread Hiroshi Doyu
IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, "iommus=" DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an depending iommu device is
populated.

Signed-off-by: Hiroshi Doyu 
---
v6:
Spinned off only of_iommu part from:
  [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

v5:
Use "iommus=" binding instread of arm,smmu's "#stream-id-cells".

v4:
This is newly added, and the successor of the following RFC:
  [RFC][PATCHv3+ 1/2] driver/core: Add of_iommu_attach()
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006914.html

Signed-off-by: Hiroshi Doyu 
---
 drivers/iommu/of_iommu.c | 14 ++
 include/linux/of_iommu.h |  6 ++
 2 files changed, 20 insertions(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 5d1aeb9..557c0c8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -125,3 +125,17 @@ int of_get_dma_window(struct device_node *dn, const char 
*prefix, int index,
return 0;
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
+
+int of_iommu_attach(struct device *dev)
+{
+   const __be32 *cur, *end;
+   struct of_phandle_args args;
+
+   of_property_for_each_phandle_with_args(dev->of_node, "iommus",
+  "#iommu-cells", 0, args, cur, end) {
+   if (!of_find_iommu_by_node(args.np))
+   return -EPROBE_DEFER;
+   }
+
+   return 0;
+}
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index a0aa9d4..14c9a5c 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -14,6 +14,7 @@ extern int of_get_dma_window(struct device_node *dn, const 
char *prefix,
 
 extern void iommu_add(struct iommu *iommu);
 extern void iommu_del(struct iommu *iommu);
+extern int of_iommu_attach(struct device *dev);
 
 #else
 
@@ -32,6 +33,11 @@ static inline void iommu_del(struct iommu *iommu)
 {
 }
 
+static inline int of_iommu_attach(struct device *dev)
+{
+   return 0;
+}
+
 #endif /* CONFIG_OF_IOMMU */
 
 #endif /* __OF_IOMMU_H */
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 02/12] iommu/of: introduce a global iommu device list

2013-12-12 Thread Hiroshi Doyu
This enables to find an populated IOMMU device via a device node. This
can be used to see if an dependee IOMMU is populated or not to keep
correct device population order. Client devices need to wait an IOMMU
to be populated.

Suggested by Thierry Reding and copied his example code.

Signed-off-by: Hiroshi Doyu 
Cc: Joerg Roedel 
Cc: Thierry Reding 
---
v6:
New for v6.

Signed-off-by: Hiroshi Doyu 
---
 drivers/iommu/of_iommu.c | 37 +
 include/linux/of_iommu.h | 16 
 2 files changed, 53 insertions(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index ee249bc..5d1aeb9 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -20,6 +20,43 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+
+static DEFINE_MUTEX(iommus_lock);
+static LIST_HEAD(iommus_list);
+
+void iommu_add(struct iommu *iommu)
+{
+   INIT_LIST_HEAD(>list);
+   mutex_lock(_lock);
+   list_add_tail(>list, _list);
+   mutex_unlock(_lock);
+}
+
+void iommu_del(struct iommu *iommu)
+{
+   INIT_LIST_HEAD(>list);
+   mutex_lock(_lock);
+   list_del(>list);
+   mutex_unlock(_lock);
+}
+
+static struct iommu *of_find_iommu_by_node(struct device_node *np)
+{
+   struct iommu *iommu;
+
+   mutex_lock(_lock);
+   list_for_each_entry(iommu, _list, list) {
+   if (iommu->dev->of_node == np) {
+   mutex_unlock(_lock);
+   return iommu;
+   }
+   }
+   mutex_unlock(_lock);
+
+   return NULL;
+}
 
 /**
  * of_get_dma_window - Parse *dma-window property and returns 0 if found.
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 51a560f..a0aa9d4 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -3,10 +3,18 @@
 
 #ifdef CONFIG_OF_IOMMU
 
+struct iommu {
+   struct list_head list;
+   struct device *dev;
+};
+
 extern int of_get_dma_window(struct device_node *dn, const char *prefix,
 int index, unsigned long *busno, dma_addr_t *addr,
 size_t *size);
 
+extern void iommu_add(struct iommu *iommu);
+extern void iommu_del(struct iommu *iommu);
+
 #else
 
 static inline int of_get_dma_window(struct device_node *dn, const char *prefix,
@@ -16,6 +24,14 @@ static inline int of_get_dma_window(struct device_node *dn, 
const char *prefix,
return -EINVAL;
 }
 
+static inline void iommu_add(struct iommu *iommu)
+{
+}
+
+static inline void iommu_del(struct iommu *iommu)
+{
+}
+
 #endif /* CONFIG_OF_IOMMU */
 
 #endif /* __OF_IOMMU_H */
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 09/12] iommu/tegra: smmu: get swgroups from DT "iommus="

2013-12-12 Thread Hiroshi Doyu
This provides the info about which swgroups a device belongs to. This
info is passed from DT. This is necessary for the unified SMMU driver
among Tegra SoCs since each has different H/W accelerators.

Signed-off-by: Hiroshi Doyu 
---
v6:
- Explained "#iommu-cells" in the binding document.
- Fixed old "nvidia,memory-clients" with 'iommus" in the binding
  document.
- Move smmu_of_get_swgroups() here from the previous patch not to break
  git bisecting.

v5:
"iommu=" in a device DT is used instead of "mmu-masters" in an iommu
DT. This is "iommu=" version of:

  [PATCHv4 5/7] iommu/tegra: smmu: Support "mmu-masters" binding

Signed-off-by: Hiroshi Doyu 
---
 .../bindings/iommu/nvidia,tegra30-smmu.txt |  30 -
 drivers/iommu/tegra-smmu.c | 135 ++---
 2 files changed, 145 insertions(+), 20 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt 
b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
index 89fb543..fd53f54 100644
--- a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
@@ -1,6 +1,6 @@
 NVIDIA Tegra 30 IOMMU H/W, SMMU (System Memory Management Unit)
 
-Required properties:
+Required properties in the IOMMU node:
 - compatible : "nvidia,tegra30-smmu"
 - reg : Should contain 3 register banks(address and length) for each
   of the SMMU register blocks.
@@ -8,9 +8,23 @@ Required properties:
 - nvidia,#asids : # of ASIDs
 - dma-window : IOVA start address and length.
 - nvidia,ahb : phandle to the ahb bus connected to SMMU.
+- iommus: phandle to an iommu device which a device is
+  attached to and indicates which swgroups a device belongs to(SWGROUP ID).
+  SWGROUP ID is from 0 to 63, and a device can belong to multiple SWGROUPS.
+- #iommu-cells. Should be 2. In client IOMMU specifiers, the two cells
+  represent a 64-bit bitmask of SWGROUP IDs under which the device
+  initiates transactions. The least significant word is first. See
+   for a list of valid values.
+
+Required properties in device nodes affected by the IOMMU:
+- iommus: A list of phandle plus specifier pairs for each IOMMU that
+  affects master transactions initiated by the device. The number of
+  cells in each specifier is defined by the #iommu-cells property in
+  the IOMMU node referred to by the phandle. The meaning of the
+  specifier cells is defined by the referenced IOMMU's binding.
 
 Example:
-   smmu {
+   smmu: iommu {
compatible = "nvidia,tegra30-smmu";
reg = <0x7000f010 0x02c
   0x7000f1f0 0x010
@@ -18,4 +32,16 @@ Example:
nvidia,#asids = <4>;/* # of ASIDs */
dma-window = <0 0x4000>;/* IOVA start & length */
nvidia,ahb = <>;
+   #iommu-cells = <2>;
};
+
+   host1x {
+   compatible = "nvidia,tegra30-host1x", "simple-bus";
+   iommus = < TEGRA_SWGROUP_CELLS(HC)>;
+   
+   gr3d {
+   compatible = "nvidia,tegra30-gr3d";
+   iommus = < TEGRA_SWGROUP_CELLS(NV)
+   TEGRA_SWGROUP_CELLS(NV2)>;
+   
+   };
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 6ab977a..fd4479a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -190,6 +190,8 @@ enum {
  * Per client for address space
  */
 struct smmu_client {
+   struct device_node  *of_node;
+   struct rb_node  node;
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
@@ -233,6 +235,7 @@ struct smmu_device {
spinlock_t  lock;
char*name;
struct device   *dev;
+   struct rb_root  clients;
struct page *avp_vector_page;   /* dummy page shared by all AS's */
 
/*
@@ -310,6 +313,96 @@ static inline void smmu_write(struct smmu_device *smmu, 
u32 val, size_t offs)
  */
 #define FLUSH_SMMU_REGS(smmu)  smmu_read(smmu, SMMU_CONFIG)
 
+static struct smmu_client *find_smmu_client(struct smmu_device *smmu,
+   struct device_node *dev_node)
+{
+   struct rb_node *node = smmu->clients.rb_node;
+
+   while (node) {
+   struct smmu_client *client;
+
+   client = container_of(node, struct smmu_client, node);
+   if (dev_node < client->of_node)
+   node = node->rb_left;
+   else if (dev_node > client->of_node)
+   node = node->rb_right;
+   else
+   return client;
+   }
+
+ 

[PATCHv7 07/12] iommu/tegra: smmu: register device to iommu dynamically

2013-12-12 Thread Hiroshi Doyu
platform_devices are registered as IOMMU'able dynamically via
add_device() and remove_device().

Tegra SMMU can have multiple address spaces(AS). IOMMU'able devices
can belong to one of them. Multiple IOVA maps are created at boot-up,
which can be attached to devices later. We reserve 2 of them for
static assignment, AS[0] for system default, AS[1] for AHB clusters as
protected domain from others, where there are many traditional
pheripheral devices like USB, SD/MMC. They should be isolated from
some smart devices like host1x for system robustness. Even if smart
devices behaves wrongly, the traditional devices(SD/MMC, USB) wouldn't
be affected, and the system could continue most likely. DMA API(ARM)
needs ARM_DMA_USE_IOMMU to be enabled.

Signed-off-by: Hiroshi Doyu 
---
v6:
Use smmu_iommu_{bound,unbind}_driver() instead of
smmu_iommu_{add,del}_device() to register devices to SMMU.

v5:
Add check NUM_OF_STATIC_MAPS < #asids.

v4:
Combined the following from v3. This makes more sense what they do.
  [PATCHv3 06/19] iommu/tegra: smmu: Select ARM_DMA_USE_IOMMU in Kconfig
  [PATCHv3 07/19] iommu/tegra: smmu: Create default IOVA maps
  [PATCHv3 08/19] iommu/tegra: smmu: Register platform_device to IOMMU 
dynamically
  [PATCHv3 19/19] iommu/tegra: smmu: Support Multiple ASID

Signed-off-by: Hiroshi Doyu 
---
 drivers/iommu/Kconfig  |  1 +
 drivers/iommu/tegra-smmu.c | 70 +-
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 3e7fdbb..0a86d63 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -170,6 +170,7 @@ config TEGRA_IOMMU_SMMU
bool "Tegra SMMU IOMMU Support"
depends on ARCH_TEGRA && TEGRA_AHB
select IOMMU_API
+   select ARM_DMA_USE_IOMMU
help
  Enables support for remapping discontiguous physical memory
  shared with the operating system into contiguous I/O virtual
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 3c772c9..99b4bd4 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -39,6 +39,9 @@
 
 #include 
 #include 
+#include 
+
+#include 
 
 enum smmu_hwgrp {
HWGRP_AFI,
@@ -319,6 +322,8 @@ struct smmu_device {
 
struct device_node *ahb;
 
+   struct dma_iommu_mapping **map;
+
int num_as;
struct smmu_as  as[0];  /* Run-time allocated array */
 };
@@ -947,6 +952,44 @@ static void smmu_iommu_domain_destroy(struct iommu_domain 
*domain)
dev_dbg(smmu->dev, "smmu_as@%p\n", as);
 }
 
+/*
+ * ASID[0] for the system default
+ * ASID[1] for PPCS("AHB bus children"), which has SDMMC
+ * ASID[2][3].. open for drivers, first come, first served.
+ */
+enum {
+   SYSTEM_DEFAULT,
+   SYSTEM_PROTECTED,
+   NUM_OF_STATIC_MAPS,
+};
+
+static int smmu_iommu_bound_driver(struct device *dev)
+{
+   int err = -EPROBE_DEFER;
+   u32 swgroups = dev->platform_data;
+   struct dma_iommu_mapping *map = NULL;
+
+   if (test_bit(TEGRA_SWGROUP_PPCS, swgroups))
+   map = smmu_handle->map[SYSTEM_PROTECTED];
+   else
+   map = smmu_handle->map[SYSTEM_DEFAULT];
+
+   if (map)
+   err = arm_iommu_attach_device(dev, map);
+   else
+   return -EPROBE_DEFER;
+
+   pr_debug("swgroups=%08lx map=%p err=%d %s\n",
+swgroups, map, err, dev_name(dev));
+   return err;
+}
+
+static void smmu_iommu_unbind_driver(struct device *dev)
+{
+   dev_dbg(dev, "Detaching from map %p\n", to_dma_iommu_mapping(dev));
+   arm_iommu_detach_device(dev);
+}
+
 static struct iommu_ops smmu_iommu_ops = {
.domain_init= smmu_iommu_domain_init,
.domain_destroy = smmu_iommu_domain_destroy,
@@ -956,6 +999,8 @@ static struct iommu_ops smmu_iommu_ops = {
.unmap  = smmu_iommu_unmap,
.iova_to_phys   = smmu_iommu_iova_to_phys,
.domain_has_cap = smmu_iommu_domain_has_cap,
+   .bound_driver   = smmu_iommu_bound_driver,
+   .unbind_driver  = smmu_iommu_unbind_driver,
.pgsize_bitmap  = SMMU_IOMMU_PGSIZES,
 };
 
@@ -1144,6 +1189,23 @@ static int tegra_smmu_resume(struct device *dev)
return err;
 }
 
+static void tegra_smmu_create_default_map(struct smmu_device *smmu)
+{
+   int i;
+
+   for (i = 0; i < smmu->num_as; i++) {
+   dma_addr_t base = smmu->iovmm_base;
+   size_t size = smmu->page_count << PAGE_SHIFT;
+
+   smmu->map[i] = arm_iommu_create_mapping(_bus_type,
+   base, size, 0);
+   if (IS_ERR(smmu->map[i]))
+   dev_err(smmu->dev,
+   "Couldn't create: asid=%d map=%p %pa-%pa\n",
+   i, smmu->ma

[PATCHv7 06/12] ARM: tegra: create a DT header defining SWGROUP ID

2013-12-12 Thread Hiroshi Doyu
Create a header file to define the swgroup IDs used by the IOMMU(SMMU)
binding. "swgroup" is a group of H/W clients which a Tegra SoC
supports. This unique ID can be used to calculate MC_SMMU__ASID_0 register offset and MC__HOTRESET_*_0
register bit. This will allow the same header to be used by both
device tree files, and drivers implementing this binding, which
guarantees that the two stay in sync. This also makes device trees
more readable by using names instead of magic numbers. For HOTRESET
bit shifting we need another conversion table, which will come later.

Signed-off-by: Hiroshi Doyu 
---
v6:
Use 0x instead of ~0UL since dtc expand this to ~0ULL.

v5:
Added new macro TEGRA_SWGROUP_CELLS() and WO_U32_OF_U64().

v4:
This is almost same as the previous v3. Just TEGRA_SWGROUP_MAX is
added.
  [PATCHv3 15/19] ARM: tegra: Create a DT header defining SWGROUP ID

Signed-off-by: Hiroshi Doyu 
---
 include/dt-bindings/memory/tegra-swgroup.h | 50 ++
 1 file changed, 50 insertions(+)
 create mode 100644 include/dt-bindings/memory/tegra-swgroup.h

diff --git a/include/dt-bindings/memory/tegra-swgroup.h 
b/include/dt-bindings/memory/tegra-swgroup.h
new file mode 100644
index 000..9c279f1
--- /dev/null
+++ b/include/dt-bindings/memory/tegra-swgroup.h
@@ -0,0 +1,50 @@
+/*
+ * This header provides constants for binding nvidia,swgroup ID
+ */
+
+#ifndef _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H
+#define _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H
+
+#define TEGRA_SWGROUP_AFI  0   /* 0x238 */
+#define TEGRA_SWGROUP_AVPC 1   /* 0x23c */
+#define TEGRA_SWGROUP_DC   2   /* 0x240 */
+#define TEGRA_SWGROUP_DCB  3   /* 0x244 */
+#define TEGRA_SWGROUP_EPP  4   /* 0x248 */
+#define TEGRA_SWGROUP_G2   5   /* 0x24c */
+#define TEGRA_SWGROUP_HC   6   /* 0x250 */
+#define TEGRA_SWGROUP_HDA  7   /* 0x254 */
+#define TEGRA_SWGROUP_ISP  8   /* 0x258 */
+#define TEGRA_SWGROUP_ISP2 SWGROUP_ISP
+#define TEGRA_SWGROUP_DC14 9   /* 0x490 *//* Exceptional non-linear */
+#define TEGRA_SWGROUP_DC12 10  /* 0xa88 *//* Exceptional non-linear */
+#define TEGRA_SWGROUP_MPE  11  /* 0x264 */
+#define TEGRA_SWGROUP_MSENCSWGROUP_MPE
+#define TEGRA_SWGROUP_NV   12  /* 0x268 */
+#define TEGRA_SWGROUP_NV2  13  /* 0x26c */
+#define TEGRA_SWGROUP_PPCS 14  /* 0x270 */
+#define TEGRA_SWGROUP_SATA215  /* 0x274 */
+#define TEGRA_SWGROUP_SATA 16  /* 0x278 */
+#define TEGRA_SWGROUP_VDE  17  /* 0x27c */
+#define TEGRA_SWGROUP_VI   18  /* 0x280 */
+#define TEGRA_SWGROUP_VIC  19  /* 0x284 */
+#define TEGRA_SWGROUP_XUSB_HOST20  /* 0x288 */
+#define TEGRA_SWGROUP_XUSB_DEV 21  /* 0x28c */
+#define TEGRA_SWGROUP_A9AVP22  /* 0x290 */
+#define TEGRA_SWGROUP_TSEC 23  /* 0x294 */
+#define TEGRA_SWGROUP_PPCS124  /* 0x298 */
+#define TEGRA_SWGROUP_SDMMC1A  25  /* 0xa94 *//* Linear shift again */
+#define TEGRA_SWGROUP_SDMMC2A  26  /* 0xa98 */
+#define TEGRA_SWGROUP_SDMMC3A  27  /* 0xa9c */
+#define TEGRA_SWGROUP_SDMMC4A  28  /* 0xaa0 */
+#define TEGRA_SWGROUP_ISP2B29  /* 0xaa4 */
+#define TEGRA_SWGROUP_GPU  30  /* 0xaa8 */
+#define TEGRA_SWGROUP_GPUB 31  /* 0xaac */
+#define TEGRA_SWGROUP_PPCS232  /* 0xab0 */
+
+#define TWO_U32_OF_U64(x)  ((x) & 0x) ((x) >> 32)
+#define TEGRA_SWGROUP_BIT(x)   (1ULL << TEGRA_SWGROUP_##x)
+#define TEGRA_SWGROUP_CELLS(x) TWO_U32_OF_U64(TEGRA_SWGROUP_BIT(x))
+
+#define TEGRA_SWGROUP_MAX  64
+
+#endif /* _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H */
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 04/12] driver/core: populate devices in order for IOMMUs

2013-12-12 Thread Hiroshi Doyu
IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, "iommus=" DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an iommu device is populated. Then,
those deferred iommu master devices are populated and configured with
help of the already populated iommu device.

Signed-off-by: Hiroshi Doyu 
Cc: Greg Kroah-Hartman 
---
This is related to the following discussion:
  [RFC PATCH] Documentation: devicetree: add description for generic bus 
properties
  
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/215042.html

v6:
Spinned off only driver core part from:
  [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

v5:
Use "iommus=" binding instread of arm,smmu's "#stream-id-cells".

v4:
This is newly added, and the successor of the following RFC:
  [RFC][PATCHv3+ 1/2] driver/core: Add of_iommu_attach()
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006914.html

Signed-off-by: Hiroshi Doyu 
---
 drivers/base/dd.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0605176..0605f52 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "base.h"
 #include "power/power.h"
@@ -273,6 +274,10 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
 
dev->driver = drv;
 
+   ret = of_iommu_attach(dev);
+   if (ret)
+   goto probe_failed;
+
/* If using pinctrl, bind pins now before probing */
ret = pinctrl_bind_pins(dev);
if (ret)
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 12/12] iommu/tegra: smmu: add SMMU to an global iommu list

2013-12-12 Thread Hiroshi Doyu
This allows to inquire if SMMU is populated or not.

Suggested by Thierry Reding and copied his example code.

Signed-off-by: Hiroshi Doyu 
Cc: Thierry Reding 
---
v6:
New for v6.

Signed-off-by: Hiroshi Doyu 
---
 drivers/iommu/tegra-smmu.c | 55 +-
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2d4b8b6..d0f0ba7 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -225,6 +225,8 @@ struct smmu_debugfs_info {
  * Per SMMU device - IOMMU device
  */
 struct smmu_device {
+   struct iommuiommu;
+
void __iomem*regbase;   /* register offset base */
void __iomem**regs; /* register block start address array */
void __iomem**rege; /* register block end address array */
@@ -234,7 +236,6 @@ struct smmu_device {
unsigned long   page_count; /* total remappable size */
spinlock_t  lock;
char*name;
-   struct device   *dev;
struct rb_root  clients;
struct page *avp_vector_page;   /* dummy page shared by all AS's */
 
@@ -371,7 +372,7 @@ static int register_smmu_client(struct smmu_device *smmu,
return -EBUSY;
}
 
-   client = devm_kzalloc(smmu->dev, sizeof(*client), GFP_KERNEL);
+   client = devm_kzalloc(smmu->iommu.dev, sizeof(*client), GFP_KERNEL);
if (!client)
return -ENOMEM;
 
@@ -388,7 +389,7 @@ static int smmu_of_get_swgroups(struct device *dev, 
unsigned long *swgroups)
 
of_property_for_each_phandle_with_args(dev->of_node, "iommus",
   "#iommu-cells", 0, args, cur, 
end) {
-   if (args.np != smmu_handle->dev->of_node)
+   if (args.np != smmu_handle->iommu.dev->of_node)
continue;
 
BUG_ON(args.args_count != 2);
@@ -527,7 +528,7 @@ static void free_ptbl(struct smmu_as *as, dma_addr_t iova)
unsigned long *pdir = (unsigned long *)page_address(as->pdir_page);
 
if (pdir[pdn] != _PDE_VACANT(pdn)) {
-   dev_dbg(as->smmu->dev, "pdn: %lx\n", pdn);
+   dev_dbg(as->smmu->iommu.dev, "pdn: %lx\n", pdn);
 
ClearPageReserved(SMMU_EX_PTBL_PAGE(pdir[pdn]));
__free_page(SMMU_EX_PTBL_PAGE(pdir[pdn]));
@@ -542,7 +543,7 @@ static void free_pdir(struct smmu_as *as)
 {
unsigned addr;
int count;
-   struct device *dev = as->smmu->dev;
+   struct device *dev = as->smmu->iommu.dev;
 
if (!as->pdir_page)
return;
@@ -585,11 +586,11 @@ static unsigned long *locate_pte(struct smmu_as *as,
unsigned long addr = SMMU_PDN_TO_ADDR(pdn);
 
/* Vacant - allocate a new page table */
-   dev_dbg(as->smmu->dev, "New PTBL pdn: %lx\n", pdn);
+   dev_dbg(as->smmu->iommu.dev, "New PTBL pdn: %lx\n", pdn);
 
*ptbl_page_p = alloc_page(GFP_ATOMIC);
if (!*ptbl_page_p) {
-   dev_err(as->smmu->dev,
+   dev_err(as->smmu->iommu.dev,
"failed to allocate smmu_device page table\n");
return NULL;
}
@@ -649,7 +650,7 @@ static int alloc_pdir(struct smmu_as *as)
/*
 * do the allocation, then grab as->lock
 */
-   cnt = devm_kzalloc(smmu->dev,
+   cnt = devm_kzalloc(smmu->iommu.dev,
   sizeof(cnt[0]) * SMMU_PDIR_COUNT,
   GFP_KERNEL);
page = alloc_page(GFP_KERNEL | __GFP_DMA);
@@ -663,7 +664,8 @@ static int alloc_pdir(struct smmu_as *as)
}
 
if (!page || !cnt) {
-   dev_err(smmu->dev, "failed to allocate at %s\n", __func__);
+   dev_err(smmu->iommu.dev,
+   "failed to allocate at %s\n", __func__);
err = -ENOMEM;
goto err_out;
}
@@ -693,7 +695,7 @@ static int alloc_pdir(struct smmu_as *as)
 err_out:
spin_unlock_irqrestore(>lock, flags);
 
-   devm_kfree(smmu->dev, cnt);
+   devm_kfree(smmu->iommu.dev, cnt);
if (page)
__free_page(page);
return err;
@@ -748,7 +750,7 @@ static int smmu_iommu_map(struct iommu_domain *domain, 
unsigned long iova,
unsigned long pfn = __phys_to_pfn(pa);
unsigned long flags;
 
-   dev_info(as->smmu->dev, "[%d] %08lx:%pa\n", as->asid, iova, );
+   dev_info(as->smmu->iommu.dev, "[%d] %08lx:%pa\n", as->asid, iova, );
 
if (!pfn_valid(pfn))
return -ENOMEM;
@@ -765,7 +767,7 @@ static size_t sm

[PATCHv7 11/12] iommu/tegra: smmu: Rename hwgrp -> swgroups

2013-12-12 Thread Hiroshi Doyu
Use the correct term for SWGROUP related variables and macros.

The term "swgroup" is the collection of "memory client". A "memory
client" usually represents a HardWare Accelerator(HWA) like
GPU. Sometimes a strut device can belong to multiple "swgroup" so that
"swgroup's'" is used here. This "swgroups" is the term used in Tegra
TRM. Rename along with TRM.

Signed-off-by: Hiroshi Doyu 
---
v4:
New for v4

Signed-off-by: Hiroshi Doyu 
---
 drivers/iommu/tegra-smmu.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2b8a302..2d4b8b6 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -179,12 +179,12 @@ enum {
 
 #define NUM_SMMU_REG_BANKS 3
 
-#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1)
-#define smmu_client_disable_hwgrp(c)   smmu_client_set_hwgrp(c, 0, 0)
-#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
-#define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0)
+#define smmu_client_enable_swgroups(c, m) smmu_client_set_swgroups(c, m, 1)
+#define smmu_client_disable_swgroups(c) smmu_client_set_swgroups(c, 0, 0)
+#define __smmu_client_enable_swgroups(c, m) __smmu_client_set_swgroups(c, m, 1)
+#define __smmu_client_disable_swgroups(c) __smmu_client_set_swgroups(c, 0, 0)
 
-#define HWGRP_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
+#define SWGROUPS_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
 
 /*
  * Per client for address space
@@ -195,7 +195,7 @@ struct smmu_client {
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
-   unsigned long   hwgrp[2];
+   unsigned long   swgroups[2];
 };
 
 /*
@@ -377,7 +377,7 @@ static int register_smmu_client(struct smmu_device *smmu,
 
client->dev = dev;
client->of_node = dev->of_node;
-   memcpy(client->hwgrp, swgroups, sizeof(u64));
+   memcpy(client->swgroups, swgroups, sizeof(u64));
return insert_smmu_client(smmu, client);
 }
 
@@ -403,7 +403,7 @@ static int smmu_of_get_swgroups(struct device *dev, 
unsigned long *swgroups)
return -ENODEV;
 }
 
-static int __smmu_client_set_hwgrp(struct smmu_client *c,
+static int __smmu_client_set_swgroups(struct smmu_client *c,
   unsigned long *map, int on)
 {
int i;
@@ -412,10 +412,10 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
struct smmu_device *smmu = as->smmu;
 
if (!on)
-   map = c->hwgrp;
+   map = c->swgroups;
 
for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
-   offs = HWGRP_ASID_REG(i);
+   offs = SWGROUPS_ASID_REG(i);
val = smmu_read(smmu, offs);
if (on) {
if (val) {
@@ -425,7 +425,7 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
}
 
val = mask;
-   memcpy(c->hwgrp, map, sizeof(u64));
+   memcpy(c->swgroups, map, sizeof(u64));
} else {
WARN_ON((val & mask) == mask);
val &= ~mask;
@@ -438,7 +438,7 @@ skip:
return 0;
 }
 
-static int smmu_client_set_hwgrp(struct smmu_client *c,
+static int smmu_client_set_swgroups(struct smmu_client *c,
 unsigned long *map, int on)
 {
int err;
@@ -447,7 +447,7 @@ static int smmu_client_set_hwgrp(struct smmu_client *c,
struct smmu_device *smmu = as->smmu;
 
spin_lock_irqsave(>lock, flags);
-   err = __smmu_client_set_hwgrp(c, map, on);
+   err = __smmu_client_set_swgroups(c, map, on);
spin_unlock_irqrestore(>lock, flags);
return err;
 }
@@ -487,7 +487,7 @@ static int smmu_setup_regs(struct smmu_device *smmu)
smmu_write(smmu, val, SMMU_PTB_DATA);
 
list_for_each_entry(c, >client, list)
-   __smmu_client_set_hwgrp(c, c->hwgrp, 1);
+   __smmu_client_set_swgroups(c, c->swgroups, 1);
}
 
smmu_write(smmu, smmu->translation_enable_0, SMMU_TRANSLATION_ENABLE_0);
@@ -815,7 +815,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain 
*domain,
return -ENOMEM;
 
client->as = as;
-   err = smmu_client_enable_hwgrp(client, client->hwgrp);
+   err = smmu_client_enable_swgroups(client, client->swgroups);
if (err)
return -EINVAL;
 
@@ -835,7 +835,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain 
*domain,
 * Reserve "page zero" for AVP vectors using a common dummy
 * page.
 */
-   if (test_bit(TEGRA_SWGROUP_AVPC, client->

[PATCHv7 08/12] iommu/tegra: smmu: calculate ASID register offset by ID

2013-12-12 Thread Hiroshi Doyu
ASID register offset is caclulated by SWGROUP ID so that we can get
rid of old SoC specific MACROs. This ID conversion is needed for the
unified SMMU driver over Tegra SoCs. We use dt-bindings MACRO instead
of SoC dependent MACROs. The formula is:

  MC_SMMU__ASID_0 = MC_SMMU_AFI_ASID_0 + ID * 4;

Now SWGROUP ID is the global HardWare Accelerator(HWA) identifier
among all Tegra SoC except Tegra2.

Signed-off-by: Hiroshi Doyu 
---
v5:
Added SMMU_ASID_BASE(== SMMU_AFI_ASID).
Removed unused ASID offset definitions.
Use 'unsigned long *' instead of u64 for swgroups bitmap.

v4:
Combined the following patches from v3:
[PATCHv3 09/19] iommu/tegra: smmu: Calculate ASID register offset by ID
[PATCHv3 16/19] iommu/tegra: smmu: Use dt-bindings MACRO

Signed-off-by: Hiroshi Doyu 
---
 drivers/iommu/tegra-smmu.c | 111 +++--
 1 file changed, 17 insertions(+), 94 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 99b4bd4..6ab977a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -43,46 +43,6 @@
 
 #include 
 
-enum smmu_hwgrp {
-   HWGRP_AFI,
-   HWGRP_AVPC,
-   HWGRP_DC,
-   HWGRP_DCB,
-   HWGRP_EPP,
-   HWGRP_G2,
-   HWGRP_HC,
-   HWGRP_HDA,
-   HWGRP_ISP,
-   HWGRP_MPE,
-   HWGRP_NV,
-   HWGRP_NV2,
-   HWGRP_PPCS,
-   HWGRP_SATA,
-   HWGRP_VDE,
-   HWGRP_VI,
-
-   HWGRP_COUNT,
-
-   HWGRP_END = ~0,
-};
-
-#define HWG_AFI(1 << HWGRP_AFI)
-#define HWG_AVPC   (1 << HWGRP_AVPC)
-#define HWG_DC (1 << HWGRP_DC)
-#define HWG_DCB(1 << HWGRP_DCB)
-#define HWG_EPP(1 << HWGRP_EPP)
-#define HWG_G2 (1 << HWGRP_G2)
-#define HWG_HC (1 << HWGRP_HC)
-#define HWG_HDA(1 << HWGRP_HDA)
-#define HWG_ISP(1 << HWGRP_ISP)
-#define HWG_MPE(1 << HWGRP_MPE)
-#define HWG_NV (1 << HWGRP_NV)
-#define HWG_NV2(1 << HWGRP_NV2)
-#define HWG_PPCS   (1 << HWGRP_PPCS)
-#define HWG_SATA   (1 << HWGRP_SATA)
-#define HWG_VDE(1 << HWGRP_VDE)
-#define HWG_VI (1 << HWGRP_VI)
-
 /* bitmap of the page sizes currently supported */
 #define SMMU_IOMMU_PGSIZES (SZ_4K)
 
@@ -152,21 +112,7 @@ enum {
 #define SMMU_TRANSLATION_ENABLE_2  0x230
 
 #define SMMU_AFI_ASID  0x238   /* PCIE */
-#define SMMU_AVPC_ASID 0x23c   /* AVP */
-#define SMMU_DC_ASID   0x240   /* Display controller */
-#define SMMU_DCB_ASID  0x244   /* Display controller B */
-#define SMMU_EPP_ASID  0x248   /* Encoder pre-processor */
-#define SMMU_G2_ASID   0x24c   /* 2D engine */
-#define SMMU_HC_ASID   0x250   /* Host1x */
-#define SMMU_HDA_ASID  0x254   /* High-def audio */
-#define SMMU_ISP_ASID  0x258   /* Image signal processor */
-#define SMMU_MPE_ASID  0x264   /* MPEG encoder */
-#define SMMU_NV_ASID   0x268   /* (3D) */
-#define SMMU_NV2_ASID  0x26c   /* (3D) */
-#define SMMU_PPCS_ASID 0x270   /* AHB */
-#define SMMU_SATA_ASID 0x278   /* SATA */
-#define SMMU_VDE_ASID  0x27c   /* Video decoder */
-#define SMMU_VI_ASID   0x280   /* Video input */
+#define SMMU_ASID_BASE SMMU_AFI_ASID
 
 #define SMMU_PDE_NEXT_SHIFT28
 
@@ -238,27 +184,7 @@ enum {
 #define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
 #define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0)
 
-#define HWGRP_INIT(client) [HWGRP_##client] = SMMU_##client##_ASID
-
-static const u32 smmu_hwgrp_asid_reg[] = {
-   HWGRP_INIT(AFI),
-   HWGRP_INIT(AVPC),
-   HWGRP_INIT(DC),
-   HWGRP_INIT(DCB),
-   HWGRP_INIT(EPP),
-   HWGRP_INIT(G2),
-   HWGRP_INIT(HC),
-   HWGRP_INIT(HDA),
-   HWGRP_INIT(ISP),
-   HWGRP_INIT(MPE),
-   HWGRP_INIT(NV),
-   HWGRP_INIT(NV2),
-   HWGRP_INIT(PPCS),
-   HWGRP_INIT(SATA),
-   HWGRP_INIT(VDE),
-   HWGRP_INIT(VI),
-};
-#define HWGRP_ASID_REG(x) (smmu_hwgrp_asid_reg[x])
+#define HWGRP_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
 
 /*
  * Per client for address space
@@ -267,7 +193,7 @@ struct smmu_client {
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
-   u32 hwgrp;
+   unsigned long   hwgrp[2];
 };
 
 /*
@@ -384,41 +310,37 @@ static inline void smmu_write(struct smmu_device *smmu, 
u32 val, size_t offs)
  */
 #define FLUSH_SMMU_REGS(smmu)  smmu_read(smmu, SMMU_CONFIG)
 
-#define smmu_client_hwgrp(c) (u32)((c)->dev->platform_data)
-
 static int __smmu_client_set_hwgrp(struct smmu_client *c,
-  unsigned long map, int on)
+  unsigned long *map, int on)
 {
int i;
struct smmu_as *as = c->as;
u32 val, offs, mask = SMMU_ASID_ENABLE(as-&

[PATCHv7 10/12] iommu/tegra: smmu: allow duplicate ASID wirte

2013-12-12 Thread Hiroshi Doyu
The device, which belongs to the same ASID, can try to enable the same
ASID as the other swgroup devices. This should be allowed but just
skip the actual register write. If the write value is different, it
will return -EINVAL.

Signed-off-by: Hiroshi Doyu 
---
v4:
This was the part of v3, which isn't used any more.
  [PATCHv3 10/19] iommu/tegra: smmu: Get "nvidia,swgroups" from DT

Signed-off-by: Hiroshi Doyu 
---
 drivers/iommu/tegra-smmu.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index fd4479a..2b8a302 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -418,9 +418,13 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
offs = HWGRP_ASID_REG(i);
val = smmu_read(smmu, offs);
if (on) {
-   if (WARN_ON(val & mask))
-   goto err_hw_busy;
-   val |= mask;
+   if (val) {
+   if (WARN_ON(val != mask))
+   return -EINVAL;
+   goto skip;
+   }
+
+   val = mask;
memcpy(c->hwgrp, map, sizeof(u64));
} else {
WARN_ON((val & mask) == mask);
@@ -430,16 +434,8 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
}
 
FLUSH_SMMU_REGS(smmu);
+skip:
return 0;
-
-err_hw_busy:
-   for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
-   offs = HWGRP_ASID_REG(i);
-   val = smmu_read(smmu, offs);
-   val &= ~mask;
-   smmu_write(smmu, val, offs);
-   }
-   return -EBUSY;
 }
 
 static int smmu_client_set_hwgrp(struct smmu_client *c,
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 08/12] iommu/tegra: smmu: calculate ASID register offset by ID

2013-12-12 Thread Hiroshi Doyu
ASID register offset is caclulated by SWGROUP ID so that we can get
rid of old SoC specific MACROs. This ID conversion is needed for the
unified SMMU driver over Tegra SoCs. We use dt-bindings MACRO instead
of SoC dependent MACROs. The formula is:

  MC_SMMU_swgroup name_ASID_0 = MC_SMMU_AFI_ASID_0 + ID * 4;

Now SWGROUP ID is the global HardWare Accelerator(HWA) identifier
among all Tegra SoC except Tegra2.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v5:
Added SMMU_ASID_BASE(== SMMU_AFI_ASID).
Removed unused ASID offset definitions.
Use 'unsigned long *' instead of u64 for swgroups bitmap.

v4:
Combined the following patches from v3:
[PATCHv3 09/19] iommu/tegra: smmu: Calculate ASID register offset by ID
[PATCHv3 16/19] iommu/tegra: smmu: Use dt-bindings MACRO

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/iommu/tegra-smmu.c | 111 +++--
 1 file changed, 17 insertions(+), 94 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 99b4bd4..6ab977a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -43,46 +43,6 @@
 
 #include dt-bindings/memory/tegra-swgroup.h
 
-enum smmu_hwgrp {
-   HWGRP_AFI,
-   HWGRP_AVPC,
-   HWGRP_DC,
-   HWGRP_DCB,
-   HWGRP_EPP,
-   HWGRP_G2,
-   HWGRP_HC,
-   HWGRP_HDA,
-   HWGRP_ISP,
-   HWGRP_MPE,
-   HWGRP_NV,
-   HWGRP_NV2,
-   HWGRP_PPCS,
-   HWGRP_SATA,
-   HWGRP_VDE,
-   HWGRP_VI,
-
-   HWGRP_COUNT,
-
-   HWGRP_END = ~0,
-};
-
-#define HWG_AFI(1  HWGRP_AFI)
-#define HWG_AVPC   (1  HWGRP_AVPC)
-#define HWG_DC (1  HWGRP_DC)
-#define HWG_DCB(1  HWGRP_DCB)
-#define HWG_EPP(1  HWGRP_EPP)
-#define HWG_G2 (1  HWGRP_G2)
-#define HWG_HC (1  HWGRP_HC)
-#define HWG_HDA(1  HWGRP_HDA)
-#define HWG_ISP(1  HWGRP_ISP)
-#define HWG_MPE(1  HWGRP_MPE)
-#define HWG_NV (1  HWGRP_NV)
-#define HWG_NV2(1  HWGRP_NV2)
-#define HWG_PPCS   (1  HWGRP_PPCS)
-#define HWG_SATA   (1  HWGRP_SATA)
-#define HWG_VDE(1  HWGRP_VDE)
-#define HWG_VI (1  HWGRP_VI)
-
 /* bitmap of the page sizes currently supported */
 #define SMMU_IOMMU_PGSIZES (SZ_4K)
 
@@ -152,21 +112,7 @@ enum {
 #define SMMU_TRANSLATION_ENABLE_2  0x230
 
 #define SMMU_AFI_ASID  0x238   /* PCIE */
-#define SMMU_AVPC_ASID 0x23c   /* AVP */
-#define SMMU_DC_ASID   0x240   /* Display controller */
-#define SMMU_DCB_ASID  0x244   /* Display controller B */
-#define SMMU_EPP_ASID  0x248   /* Encoder pre-processor */
-#define SMMU_G2_ASID   0x24c   /* 2D engine */
-#define SMMU_HC_ASID   0x250   /* Host1x */
-#define SMMU_HDA_ASID  0x254   /* High-def audio */
-#define SMMU_ISP_ASID  0x258   /* Image signal processor */
-#define SMMU_MPE_ASID  0x264   /* MPEG encoder */
-#define SMMU_NV_ASID   0x268   /* (3D) */
-#define SMMU_NV2_ASID  0x26c   /* (3D) */
-#define SMMU_PPCS_ASID 0x270   /* AHB */
-#define SMMU_SATA_ASID 0x278   /* SATA */
-#define SMMU_VDE_ASID  0x27c   /* Video decoder */
-#define SMMU_VI_ASID   0x280   /* Video input */
+#define SMMU_ASID_BASE SMMU_AFI_ASID
 
 #define SMMU_PDE_NEXT_SHIFT28
 
@@ -238,27 +184,7 @@ enum {
 #define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
 #define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0)
 
-#define HWGRP_INIT(client) [HWGRP_##client] = SMMU_##client##_ASID
-
-static const u32 smmu_hwgrp_asid_reg[] = {
-   HWGRP_INIT(AFI),
-   HWGRP_INIT(AVPC),
-   HWGRP_INIT(DC),
-   HWGRP_INIT(DCB),
-   HWGRP_INIT(EPP),
-   HWGRP_INIT(G2),
-   HWGRP_INIT(HC),
-   HWGRP_INIT(HDA),
-   HWGRP_INIT(ISP),
-   HWGRP_INIT(MPE),
-   HWGRP_INIT(NV),
-   HWGRP_INIT(NV2),
-   HWGRP_INIT(PPCS),
-   HWGRP_INIT(SATA),
-   HWGRP_INIT(VDE),
-   HWGRP_INIT(VI),
-};
-#define HWGRP_ASID_REG(x) (smmu_hwgrp_asid_reg[x])
+#define HWGRP_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
 
 /*
  * Per client for address space
@@ -267,7 +193,7 @@ struct smmu_client {
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
-   u32 hwgrp;
+   unsigned long   hwgrp[2];
 };
 
 /*
@@ -384,41 +310,37 @@ static inline void smmu_write(struct smmu_device *smmu, 
u32 val, size_t offs)
  */
 #define FLUSH_SMMU_REGS(smmu)  smmu_read(smmu, SMMU_CONFIG)
 
-#define smmu_client_hwgrp(c) (u32)((c)-dev-platform_data)
-
 static int __smmu_client_set_hwgrp(struct smmu_client *c,
-  unsigned long map, int on)
+  unsigned long *map, int on)
 {
int i;
struct smmu_as *as = c-as;
u32 val, offs, mask = SMMU_ASID_ENABLE(as-asid);
struct smmu_device *smmu = as-smmu;
 
-   WARN_ON

[PATCHv7 06/12] ARM: tegra: create a DT header defining SWGROUP ID

2013-12-12 Thread Hiroshi Doyu
Create a header file to define the swgroup IDs used by the IOMMU(SMMU)
binding. swgroup is a group of H/W clients which a Tegra SoC
supports. This unique ID can be used to calculate MC_SMMU_swgroup
name_ASID_0 register offset and MC_swgroup name_HOTRESET_*_0
register bit. This will allow the same header to be used by both
device tree files, and drivers implementing this binding, which
guarantees that the two stay in sync. This also makes device trees
more readable by using names instead of magic numbers. For HOTRESET
bit shifting we need another conversion table, which will come later.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v6:
Use 0x instead of ~0UL since dtc expand this to ~0ULL.

v5:
Added new macro TEGRA_SWGROUP_CELLS() and WO_U32_OF_U64().

v4:
This is almost same as the previous v3. Just TEGRA_SWGROUP_MAX is
added.
  [PATCHv3 15/19] ARM: tegra: Create a DT header defining SWGROUP ID

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 include/dt-bindings/memory/tegra-swgroup.h | 50 ++
 1 file changed, 50 insertions(+)
 create mode 100644 include/dt-bindings/memory/tegra-swgroup.h

diff --git a/include/dt-bindings/memory/tegra-swgroup.h 
b/include/dt-bindings/memory/tegra-swgroup.h
new file mode 100644
index 000..9c279f1
--- /dev/null
+++ b/include/dt-bindings/memory/tegra-swgroup.h
@@ -0,0 +1,50 @@
+/*
+ * This header provides constants for binding nvidia,swgroup ID
+ */
+
+#ifndef _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H
+#define _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H
+
+#define TEGRA_SWGROUP_AFI  0   /* 0x238 */
+#define TEGRA_SWGROUP_AVPC 1   /* 0x23c */
+#define TEGRA_SWGROUP_DC   2   /* 0x240 */
+#define TEGRA_SWGROUP_DCB  3   /* 0x244 */
+#define TEGRA_SWGROUP_EPP  4   /* 0x248 */
+#define TEGRA_SWGROUP_G2   5   /* 0x24c */
+#define TEGRA_SWGROUP_HC   6   /* 0x250 */
+#define TEGRA_SWGROUP_HDA  7   /* 0x254 */
+#define TEGRA_SWGROUP_ISP  8   /* 0x258 */
+#define TEGRA_SWGROUP_ISP2 SWGROUP_ISP
+#define TEGRA_SWGROUP_DC14 9   /* 0x490 *//* Exceptional non-linear */
+#define TEGRA_SWGROUP_DC12 10  /* 0xa88 *//* Exceptional non-linear */
+#define TEGRA_SWGROUP_MPE  11  /* 0x264 */
+#define TEGRA_SWGROUP_MSENCSWGROUP_MPE
+#define TEGRA_SWGROUP_NV   12  /* 0x268 */
+#define TEGRA_SWGROUP_NV2  13  /* 0x26c */
+#define TEGRA_SWGROUP_PPCS 14  /* 0x270 */
+#define TEGRA_SWGROUP_SATA215  /* 0x274 */
+#define TEGRA_SWGROUP_SATA 16  /* 0x278 */
+#define TEGRA_SWGROUP_VDE  17  /* 0x27c */
+#define TEGRA_SWGROUP_VI   18  /* 0x280 */
+#define TEGRA_SWGROUP_VIC  19  /* 0x284 */
+#define TEGRA_SWGROUP_XUSB_HOST20  /* 0x288 */
+#define TEGRA_SWGROUP_XUSB_DEV 21  /* 0x28c */
+#define TEGRA_SWGROUP_A9AVP22  /* 0x290 */
+#define TEGRA_SWGROUP_TSEC 23  /* 0x294 */
+#define TEGRA_SWGROUP_PPCS124  /* 0x298 */
+#define TEGRA_SWGROUP_SDMMC1A  25  /* 0xa94 *//* Linear shift again */
+#define TEGRA_SWGROUP_SDMMC2A  26  /* 0xa98 */
+#define TEGRA_SWGROUP_SDMMC3A  27  /* 0xa9c */
+#define TEGRA_SWGROUP_SDMMC4A  28  /* 0xaa0 */
+#define TEGRA_SWGROUP_ISP2B29  /* 0xaa4 */
+#define TEGRA_SWGROUP_GPU  30  /* 0xaa8 */
+#define TEGRA_SWGROUP_GPUB 31  /* 0xaac */
+#define TEGRA_SWGROUP_PPCS232  /* 0xab0 */
+
+#define TWO_U32_OF_U64(x)  ((x)  0x) ((x)  32)
+#define TEGRA_SWGROUP_BIT(x)   (1ULL  TEGRA_SWGROUP_##x)
+#define TEGRA_SWGROUP_CELLS(x) TWO_U32_OF_U64(TEGRA_SWGROUP_BIT(x))
+
+#define TEGRA_SWGROUP_MAX  64
+
+#endif /* _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H */
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 04/12] driver/core: populate devices in order for IOMMUs

2013-12-12 Thread Hiroshi Doyu
IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, iommus= DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an iommu device is populated. Then,
those deferred iommu master devices are populated and configured with
help of the already populated iommu device.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
---
This is related to the following discussion:
  [RFC PATCH] Documentation: devicetree: add description for generic bus 
properties
  
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/215042.html

v6:
Spinned off only driver core part from:
  [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

v5:
Use iommus= binding instread of arm,smmu's #stream-id-cells.

v4:
This is newly added, and the successor of the following RFC:
  [RFC][PATCHv3+ 1/2] driver/core: Add of_iommu_attach()
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006914.html

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/base/dd.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0605176..0605f52 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -25,6 +25,7 @@
 #include linux/async.h
 #include linux/pm_runtime.h
 #include linux/pinctrl/devinfo.h
+#include linux/of_iommu.h
 
 #include base.h
 #include power/power.h
@@ -273,6 +274,10 @@ static int really_probe(struct device *dev, struct 
device_driver *drv)
 
dev-driver = drv;
 
+   ret = of_iommu_attach(dev);
+   if (ret)
+   goto probe_failed;
+
/* If using pinctrl, bind pins now before probing */
ret = pinctrl_bind_pins(dev);
if (ret)
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 10/12] iommu/tegra: smmu: allow duplicate ASID wirte

2013-12-12 Thread Hiroshi Doyu
The device, which belongs to the same ASID, can try to enable the same
ASID as the other swgroup devices. This should be allowed but just
skip the actual register write. If the write value is different, it
will return -EINVAL.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v4:
This was the part of v3, which isn't used any more.
  [PATCHv3 10/19] iommu/tegra: smmu: Get nvidia,swgroups from DT

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/iommu/tegra-smmu.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index fd4479a..2b8a302 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -418,9 +418,13 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
offs = HWGRP_ASID_REG(i);
val = smmu_read(smmu, offs);
if (on) {
-   if (WARN_ON(val  mask))
-   goto err_hw_busy;
-   val |= mask;
+   if (val) {
+   if (WARN_ON(val != mask))
+   return -EINVAL;
+   goto skip;
+   }
+
+   val = mask;
memcpy(c-hwgrp, map, sizeof(u64));
} else {
WARN_ON((val  mask) == mask);
@@ -430,16 +434,8 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
}
 
FLUSH_SMMU_REGS(smmu);
+skip:
return 0;
-
-err_hw_busy:
-   for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
-   offs = HWGRP_ASID_REG(i);
-   val = smmu_read(smmu, offs);
-   val = ~mask;
-   smmu_write(smmu, val, offs);
-   }
-   return -EBUSY;
 }
 
 static int smmu_client_set_hwgrp(struct smmu_client *c,
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 12/12] iommu/tegra: smmu: add SMMU to an global iommu list

2013-12-12 Thread Hiroshi Doyu
This allows to inquire if SMMU is populated or not.

Suggested by Thierry Reding and copied his example code.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
Cc: Thierry Reding thierry.red...@gmail.com
---
v6:
New for v6.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/iommu/tegra-smmu.c | 55 +-
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2d4b8b6..d0f0ba7 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -225,6 +225,8 @@ struct smmu_debugfs_info {
  * Per SMMU device - IOMMU device
  */
 struct smmu_device {
+   struct iommuiommu;
+
void __iomem*regbase;   /* register offset base */
void __iomem**regs; /* register block start address array */
void __iomem**rege; /* register block end address array */
@@ -234,7 +236,6 @@ struct smmu_device {
unsigned long   page_count; /* total remappable size */
spinlock_t  lock;
char*name;
-   struct device   *dev;
struct rb_root  clients;
struct page *avp_vector_page;   /* dummy page shared by all AS's */
 
@@ -371,7 +372,7 @@ static int register_smmu_client(struct smmu_device *smmu,
return -EBUSY;
}
 
-   client = devm_kzalloc(smmu-dev, sizeof(*client), GFP_KERNEL);
+   client = devm_kzalloc(smmu-iommu.dev, sizeof(*client), GFP_KERNEL);
if (!client)
return -ENOMEM;
 
@@ -388,7 +389,7 @@ static int smmu_of_get_swgroups(struct device *dev, 
unsigned long *swgroups)
 
of_property_for_each_phandle_with_args(dev-of_node, iommus,
   #iommu-cells, 0, args, cur, 
end) {
-   if (args.np != smmu_handle-dev-of_node)
+   if (args.np != smmu_handle-iommu.dev-of_node)
continue;
 
BUG_ON(args.args_count != 2);
@@ -527,7 +528,7 @@ static void free_ptbl(struct smmu_as *as, dma_addr_t iova)
unsigned long *pdir = (unsigned long *)page_address(as-pdir_page);
 
if (pdir[pdn] != _PDE_VACANT(pdn)) {
-   dev_dbg(as-smmu-dev, pdn: %lx\n, pdn);
+   dev_dbg(as-smmu-iommu.dev, pdn: %lx\n, pdn);
 
ClearPageReserved(SMMU_EX_PTBL_PAGE(pdir[pdn]));
__free_page(SMMU_EX_PTBL_PAGE(pdir[pdn]));
@@ -542,7 +543,7 @@ static void free_pdir(struct smmu_as *as)
 {
unsigned addr;
int count;
-   struct device *dev = as-smmu-dev;
+   struct device *dev = as-smmu-iommu.dev;
 
if (!as-pdir_page)
return;
@@ -585,11 +586,11 @@ static unsigned long *locate_pte(struct smmu_as *as,
unsigned long addr = SMMU_PDN_TO_ADDR(pdn);
 
/* Vacant - allocate a new page table */
-   dev_dbg(as-smmu-dev, New PTBL pdn: %lx\n, pdn);
+   dev_dbg(as-smmu-iommu.dev, New PTBL pdn: %lx\n, pdn);
 
*ptbl_page_p = alloc_page(GFP_ATOMIC);
if (!*ptbl_page_p) {
-   dev_err(as-smmu-dev,
+   dev_err(as-smmu-iommu.dev,
failed to allocate smmu_device page table\n);
return NULL;
}
@@ -649,7 +650,7 @@ static int alloc_pdir(struct smmu_as *as)
/*
 * do the allocation, then grab as-lock
 */
-   cnt = devm_kzalloc(smmu-dev,
+   cnt = devm_kzalloc(smmu-iommu.dev,
   sizeof(cnt[0]) * SMMU_PDIR_COUNT,
   GFP_KERNEL);
page = alloc_page(GFP_KERNEL | __GFP_DMA);
@@ -663,7 +664,8 @@ static int alloc_pdir(struct smmu_as *as)
}
 
if (!page || !cnt) {
-   dev_err(smmu-dev, failed to allocate at %s\n, __func__);
+   dev_err(smmu-iommu.dev,
+   failed to allocate at %s\n, __func__);
err = -ENOMEM;
goto err_out;
}
@@ -693,7 +695,7 @@ static int alloc_pdir(struct smmu_as *as)
 err_out:
spin_unlock_irqrestore(as-lock, flags);
 
-   devm_kfree(smmu-dev, cnt);
+   devm_kfree(smmu-iommu.dev, cnt);
if (page)
__free_page(page);
return err;
@@ -748,7 +750,7 @@ static int smmu_iommu_map(struct iommu_domain *domain, 
unsigned long iova,
unsigned long pfn = __phys_to_pfn(pa);
unsigned long flags;
 
-   dev_info(as-smmu-dev, [%d] %08lx:%pa\n, as-asid, iova, pa);
+   dev_info(as-smmu-iommu.dev, [%d] %08lx:%pa\n, as-asid, iova, pa);
 
if (!pfn_valid(pfn))
return -ENOMEM;
@@ -765,7 +767,7 @@ static size_t smmu_iommu_unmap(struct iommu_domain *domain, 
unsigned long iova,
struct smmu_as *as = domain-priv;
unsigned long flags;
 
-   dev_dbg(as-smmu-dev, [%d] %08lx\n, as-asid, iova);
+   dev_dbg(as-smmu-iommu.dev

[PATCHv7 11/12] iommu/tegra: smmu: Rename hwgrp - swgroups

2013-12-12 Thread Hiroshi Doyu
Use the correct term for SWGROUP related variables and macros.

The term swgroup is the collection of memory client. A memory
client usually represents a HardWare Accelerator(HWA) like
GPU. Sometimes a strut device can belong to multiple swgroup so that
swgroup's' is used here. This swgroups is the term used in Tegra
TRM. Rename along with TRM.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v4:
New for v4

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/iommu/tegra-smmu.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2b8a302..2d4b8b6 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -179,12 +179,12 @@ enum {
 
 #define NUM_SMMU_REG_BANKS 3
 
-#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1)
-#define smmu_client_disable_hwgrp(c)   smmu_client_set_hwgrp(c, 0, 0)
-#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
-#define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0)
+#define smmu_client_enable_swgroups(c, m) smmu_client_set_swgroups(c, m, 1)
+#define smmu_client_disable_swgroups(c) smmu_client_set_swgroups(c, 0, 0)
+#define __smmu_client_enable_swgroups(c, m) __smmu_client_set_swgroups(c, m, 1)
+#define __smmu_client_disable_swgroups(c) __smmu_client_set_swgroups(c, 0, 0)
 
-#define HWGRP_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
+#define SWGROUPS_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
 
 /*
  * Per client for address space
@@ -195,7 +195,7 @@ struct smmu_client {
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
-   unsigned long   hwgrp[2];
+   unsigned long   swgroups[2];
 };
 
 /*
@@ -377,7 +377,7 @@ static int register_smmu_client(struct smmu_device *smmu,
 
client-dev = dev;
client-of_node = dev-of_node;
-   memcpy(client-hwgrp, swgroups, sizeof(u64));
+   memcpy(client-swgroups, swgroups, sizeof(u64));
return insert_smmu_client(smmu, client);
 }
 
@@ -403,7 +403,7 @@ static int smmu_of_get_swgroups(struct device *dev, 
unsigned long *swgroups)
return -ENODEV;
 }
 
-static int __smmu_client_set_hwgrp(struct smmu_client *c,
+static int __smmu_client_set_swgroups(struct smmu_client *c,
   unsigned long *map, int on)
 {
int i;
@@ -412,10 +412,10 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
struct smmu_device *smmu = as-smmu;
 
if (!on)
-   map = c-hwgrp;
+   map = c-swgroups;
 
for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
-   offs = HWGRP_ASID_REG(i);
+   offs = SWGROUPS_ASID_REG(i);
val = smmu_read(smmu, offs);
if (on) {
if (val) {
@@ -425,7 +425,7 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
}
 
val = mask;
-   memcpy(c-hwgrp, map, sizeof(u64));
+   memcpy(c-swgroups, map, sizeof(u64));
} else {
WARN_ON((val  mask) == mask);
val = ~mask;
@@ -438,7 +438,7 @@ skip:
return 0;
 }
 
-static int smmu_client_set_hwgrp(struct smmu_client *c,
+static int smmu_client_set_swgroups(struct smmu_client *c,
 unsigned long *map, int on)
 {
int err;
@@ -447,7 +447,7 @@ static int smmu_client_set_hwgrp(struct smmu_client *c,
struct smmu_device *smmu = as-smmu;
 
spin_lock_irqsave(smmu-lock, flags);
-   err = __smmu_client_set_hwgrp(c, map, on);
+   err = __smmu_client_set_swgroups(c, map, on);
spin_unlock_irqrestore(smmu-lock, flags);
return err;
 }
@@ -487,7 +487,7 @@ static int smmu_setup_regs(struct smmu_device *smmu)
smmu_write(smmu, val, SMMU_PTB_DATA);
 
list_for_each_entry(c, as-client, list)
-   __smmu_client_set_hwgrp(c, c-hwgrp, 1);
+   __smmu_client_set_swgroups(c, c-swgroups, 1);
}
 
smmu_write(smmu, smmu-translation_enable_0, SMMU_TRANSLATION_ENABLE_0);
@@ -815,7 +815,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain 
*domain,
return -ENOMEM;
 
client-as = as;
-   err = smmu_client_enable_hwgrp(client, client-hwgrp);
+   err = smmu_client_enable_swgroups(client, client-swgroups);
if (err)
return -EINVAL;
 
@@ -835,7 +835,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain 
*domain,
 * Reserve page zero for AVP vectors using a common dummy
 * page.
 */
-   if (test_bit(TEGRA_SWGROUP_AVPC, client-hwgrp)) {
+   if (test_bit(TEGRA_SWGROUP_AVPC, client-swgroups)) {
struct page *page;
 
page

[PATCHv7 09/12] iommu/tegra: smmu: get swgroups from DT iommus=

2013-12-12 Thread Hiroshi Doyu
This provides the info about which swgroups a device belongs to. This
info is passed from DT. This is necessary for the unified SMMU driver
among Tegra SoCs since each has different H/W accelerators.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v6:
- Explained #iommu-cells in the binding document.
- Fixed old nvidia,memory-clients with 'iommus in the binding
  document.
- Move smmu_of_get_swgroups() here from the previous patch not to break
  git bisecting.

v5:
iommu= in a device DT is used instead of mmu-masters in an iommu
DT. This is iommu= version of:

  [PATCHv4 5/7] iommu/tegra: smmu: Support mmu-masters binding

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 .../bindings/iommu/nvidia,tegra30-smmu.txt |  30 -
 drivers/iommu/tegra-smmu.c | 135 ++---
 2 files changed, 145 insertions(+), 20 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt 
b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
index 89fb543..fd53f54 100644
--- a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
@@ -1,6 +1,6 @@
 NVIDIA Tegra 30 IOMMU H/W, SMMU (System Memory Management Unit)
 
-Required properties:
+Required properties in the IOMMU node:
 - compatible : nvidia,tegra30-smmu
 - reg : Should contain 3 register banks(address and length) for each
   of the SMMU register blocks.
@@ -8,9 +8,23 @@ Required properties:
 - nvidia,#asids : # of ASIDs
 - dma-window : IOVA start address and length.
 - nvidia,ahb : phandle to the ahb bus connected to SMMU.
+- iommus: phandle to an iommu device which a device is
+  attached to and indicates which swgroups a device belongs to(SWGROUP ID).
+  SWGROUP ID is from 0 to 63, and a device can belong to multiple SWGROUPS.
+- #iommu-cells. Should be 2. In client IOMMU specifiers, the two cells
+  represent a 64-bit bitmask of SWGROUP IDs under which the device
+  initiates transactions. The least significant word is first. See
+  dt-bindings/memory/tegra-swgroup.h for a list of valid values.
+
+Required properties in device nodes affected by the IOMMU:
+- iommus: A list of phandle plus specifier pairs for each IOMMU that
+  affects master transactions initiated by the device. The number of
+  cells in each specifier is defined by the #iommu-cells property in
+  the IOMMU node referred to by the phandle. The meaning of the
+  specifier cells is defined by the referenced IOMMU's binding.
 
 Example:
-   smmu {
+   smmu: iommu {
compatible = nvidia,tegra30-smmu;
reg = 0x7000f010 0x02c
   0x7000f1f0 0x010
@@ -18,4 +32,16 @@ Example:
nvidia,#asids = 4;/* # of ASIDs */
dma-window = 0 0x4000;/* IOVA start  length */
nvidia,ahb = ahb;
+   #iommu-cells = 2;
};
+
+   host1x {
+   compatible = nvidia,tegra30-host1x, simple-bus;
+   iommus = smmu TEGRA_SWGROUP_CELLS(HC);
+   
+   gr3d {
+   compatible = nvidia,tegra30-gr3d;
+   iommus = smmu TEGRA_SWGROUP_CELLS(NV)
+   TEGRA_SWGROUP_CELLS(NV2);
+   
+   };
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 6ab977a..fd4479a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -190,6 +190,8 @@ enum {
  * Per client for address space
  */
 struct smmu_client {
+   struct device_node  *of_node;
+   struct rb_node  node;
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
@@ -233,6 +235,7 @@ struct smmu_device {
spinlock_t  lock;
char*name;
struct device   *dev;
+   struct rb_root  clients;
struct page *avp_vector_page;   /* dummy page shared by all AS's */
 
/*
@@ -310,6 +313,96 @@ static inline void smmu_write(struct smmu_device *smmu, 
u32 val, size_t offs)
  */
 #define FLUSH_SMMU_REGS(smmu)  smmu_read(smmu, SMMU_CONFIG)
 
+static struct smmu_client *find_smmu_client(struct smmu_device *smmu,
+   struct device_node *dev_node)
+{
+   struct rb_node *node = smmu-clients.rb_node;
+
+   while (node) {
+   struct smmu_client *client;
+
+   client = container_of(node, struct smmu_client, node);
+   if (dev_node  client-of_node)
+   node = node-rb_left;
+   else if (dev_node  client-of_node)
+   node = node-rb_right;
+   else
+   return client;
+   }
+
+   return NULL;
+}
+
+static int insert_smmu_client(struct smmu_device *smmu,
+ struct smmu_client *client

[PATCHv7 07/12] iommu/tegra: smmu: register device to iommu dynamically

2013-12-12 Thread Hiroshi Doyu
platform_devices are registered as IOMMU'able dynamically via
add_device() and remove_device().

Tegra SMMU can have multiple address spaces(AS). IOMMU'able devices
can belong to one of them. Multiple IOVA maps are created at boot-up,
which can be attached to devices later. We reserve 2 of them for
static assignment, AS[0] for system default, AS[1] for AHB clusters as
protected domain from others, where there are many traditional
pheripheral devices like USB, SD/MMC. They should be isolated from
some smart devices like host1x for system robustness. Even if smart
devices behaves wrongly, the traditional devices(SD/MMC, USB) wouldn't
be affected, and the system could continue most likely. DMA API(ARM)
needs ARM_DMA_USE_IOMMU to be enabled.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v6:
Use smmu_iommu_{bound,unbind}_driver() instead of
smmu_iommu_{add,del}_device() to register devices to SMMU.

v5:
Add check NUM_OF_STATIC_MAPS  #asids.

v4:
Combined the following from v3. This makes more sense what they do.
  [PATCHv3 06/19] iommu/tegra: smmu: Select ARM_DMA_USE_IOMMU in Kconfig
  [PATCHv3 07/19] iommu/tegra: smmu: Create default IOVA maps
  [PATCHv3 08/19] iommu/tegra: smmu: Register platform_device to IOMMU 
dynamically
  [PATCHv3 19/19] iommu/tegra: smmu: Support Multiple ASID

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/iommu/Kconfig  |  1 +
 drivers/iommu/tegra-smmu.c | 70 +-
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 3e7fdbb..0a86d63 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -170,6 +170,7 @@ config TEGRA_IOMMU_SMMU
bool Tegra SMMU IOMMU Support
depends on ARCH_TEGRA  TEGRA_AHB
select IOMMU_API
+   select ARM_DMA_USE_IOMMU
help
  Enables support for remapping discontiguous physical memory
  shared with the operating system into contiguous I/O virtual
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 3c772c9..99b4bd4 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -39,6 +39,9 @@
 
 #include asm/page.h
 #include asm/cacheflush.h
+#include asm/dma-iommu.h
+
+#include dt-bindings/memory/tegra-swgroup.h
 
 enum smmu_hwgrp {
HWGRP_AFI,
@@ -319,6 +322,8 @@ struct smmu_device {
 
struct device_node *ahb;
 
+   struct dma_iommu_mapping **map;
+
int num_as;
struct smmu_as  as[0];  /* Run-time allocated array */
 };
@@ -947,6 +952,44 @@ static void smmu_iommu_domain_destroy(struct iommu_domain 
*domain)
dev_dbg(smmu-dev, smmu_as@%p\n, as);
 }
 
+/*
+ * ASID[0] for the system default
+ * ASID[1] for PPCS(AHB bus children), which has SDMMC
+ * ASID[2][3].. open for drivers, first come, first served.
+ */
+enum {
+   SYSTEM_DEFAULT,
+   SYSTEM_PROTECTED,
+   NUM_OF_STATIC_MAPS,
+};
+
+static int smmu_iommu_bound_driver(struct device *dev)
+{
+   int err = -EPROBE_DEFER;
+   u32 swgroups = dev-platform_data;
+   struct dma_iommu_mapping *map = NULL;
+
+   if (test_bit(TEGRA_SWGROUP_PPCS, swgroups))
+   map = smmu_handle-map[SYSTEM_PROTECTED];
+   else
+   map = smmu_handle-map[SYSTEM_DEFAULT];
+
+   if (map)
+   err = arm_iommu_attach_device(dev, map);
+   else
+   return -EPROBE_DEFER;
+
+   pr_debug(swgroups=%08lx map=%p err=%d %s\n,
+swgroups, map, err, dev_name(dev));
+   return err;
+}
+
+static void smmu_iommu_unbind_driver(struct device *dev)
+{
+   dev_dbg(dev, Detaching from map %p\n, to_dma_iommu_mapping(dev));
+   arm_iommu_detach_device(dev);
+}
+
 static struct iommu_ops smmu_iommu_ops = {
.domain_init= smmu_iommu_domain_init,
.domain_destroy = smmu_iommu_domain_destroy,
@@ -956,6 +999,8 @@ static struct iommu_ops smmu_iommu_ops = {
.unmap  = smmu_iommu_unmap,
.iova_to_phys   = smmu_iommu_iova_to_phys,
.domain_has_cap = smmu_iommu_domain_has_cap,
+   .bound_driver   = smmu_iommu_bound_driver,
+   .unbind_driver  = smmu_iommu_unbind_driver,
.pgsize_bitmap  = SMMU_IOMMU_PGSIZES,
 };
 
@@ -1144,6 +1189,23 @@ static int tegra_smmu_resume(struct device *dev)
return err;
 }
 
+static void tegra_smmu_create_default_map(struct smmu_device *smmu)
+{
+   int i;
+
+   for (i = 0; i  smmu-num_as; i++) {
+   dma_addr_t base = smmu-iovmm_base;
+   size_t size = smmu-page_count  PAGE_SHIFT;
+
+   smmu-map[i] = arm_iommu_create_mapping(platform_bus_type,
+   base, size, 0);
+   if (IS_ERR(smmu-map[i]))
+   dev_err(smmu-dev,
+   Couldn't create: asid=%d map=%p %pa-%pa\n,
+   i, smmu-map[i], base, base + size - 1

[PATCHv7 03/12] iommu/of: check if dependee iommu is ready or not

2013-12-12 Thread Hiroshi Doyu
IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, iommus= DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an depending iommu device is
populated.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v6:
Spinned off only of_iommu part from:
  [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

v5:
Use iommus= binding instread of arm,smmu's #stream-id-cells.

v4:
This is newly added, and the successor of the following RFC:
  [RFC][PATCHv3+ 1/2] driver/core: Add of_iommu_attach()
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006914.html

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/iommu/of_iommu.c | 14 ++
 include/linux/of_iommu.h |  6 ++
 2 files changed, 20 insertions(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 5d1aeb9..557c0c8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -125,3 +125,17 @@ int of_get_dma_window(struct device_node *dn, const char 
*prefix, int index,
return 0;
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
+
+int of_iommu_attach(struct device *dev)
+{
+   const __be32 *cur, *end;
+   struct of_phandle_args args;
+
+   of_property_for_each_phandle_with_args(dev-of_node, iommus,
+  #iommu-cells, 0, args, cur, end) {
+   if (!of_find_iommu_by_node(args.np))
+   return -EPROBE_DEFER;
+   }
+
+   return 0;
+}
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index a0aa9d4..14c9a5c 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -14,6 +14,7 @@ extern int of_get_dma_window(struct device_node *dn, const 
char *prefix,
 
 extern void iommu_add(struct iommu *iommu);
 extern void iommu_del(struct iommu *iommu);
+extern int of_iommu_attach(struct device *dev);
 
 #else
 
@@ -32,6 +33,11 @@ static inline void iommu_del(struct iommu *iommu)
 {
 }
 
+static inline int of_iommu_attach(struct device *dev)
+{
+   return 0;
+}
+
 #endif /* CONFIG_OF_IOMMU */
 
 #endif /* __OF_IOMMU_H */
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 02/12] iommu/of: introduce a global iommu device list

2013-12-12 Thread Hiroshi Doyu
This enables to find an populated IOMMU device via a device node. This
can be used to see if an dependee IOMMU is populated or not to keep
correct device population order. Client devices need to wait an IOMMU
to be populated.

Suggested by Thierry Reding and copied his example code.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
Cc: Joerg Roedel j...@8bytes.org
Cc: Thierry Reding thierry.red...@gmail.com
---
v6:
New for v6.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/iommu/of_iommu.c | 37 +
 include/linux/of_iommu.h | 16 
 2 files changed, 53 insertions(+)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index ee249bc..5d1aeb9 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -20,6 +20,43 @@
 #include linux/export.h
 #include linux/limits.h
 #include linux/of.h
+#include linux/of_iommu.h
+#include linux/device.h
+
+static DEFINE_MUTEX(iommus_lock);
+static LIST_HEAD(iommus_list);
+
+void iommu_add(struct iommu *iommu)
+{
+   INIT_LIST_HEAD(iommu-list);
+   mutex_lock(iommus_lock);
+   list_add_tail(iommu-list, iommus_list);
+   mutex_unlock(iommus_lock);
+}
+
+void iommu_del(struct iommu *iommu)
+{
+   INIT_LIST_HEAD(iommu-list);
+   mutex_lock(iommus_lock);
+   list_del(iommu-list);
+   mutex_unlock(iommus_lock);
+}
+
+static struct iommu *of_find_iommu_by_node(struct device_node *np)
+{
+   struct iommu *iommu;
+
+   mutex_lock(iommus_lock);
+   list_for_each_entry(iommu, iommus_list, list) {
+   if (iommu-dev-of_node == np) {
+   mutex_unlock(iommus_lock);
+   return iommu;
+   }
+   }
+   mutex_unlock(iommus_lock);
+
+   return NULL;
+}
 
 /**
  * of_get_dma_window - Parse *dma-window property and returns 0 if found.
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 51a560f..a0aa9d4 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -3,10 +3,18 @@
 
 #ifdef CONFIG_OF_IOMMU
 
+struct iommu {
+   struct list_head list;
+   struct device *dev;
+};
+
 extern int of_get_dma_window(struct device_node *dn, const char *prefix,
 int index, unsigned long *busno, dma_addr_t *addr,
 size_t *size);
 
+extern void iommu_add(struct iommu *iommu);
+extern void iommu_del(struct iommu *iommu);
+
 #else
 
 static inline int of_get_dma_window(struct device_node *dn, const char *prefix,
@@ -16,6 +24,14 @@ static inline int of_get_dma_window(struct device_node *dn, 
const char *prefix,
return -EINVAL;
 }
 
+static inline void iommu_add(struct iommu *iommu)
+{
+}
+
+static inline void iommu_del(struct iommu *iommu)
+{
+}
+
 #endif /* CONFIG_OF_IOMMU */
 
 #endif /* __OF_IOMMU_H */
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 05/12] iommu/core: add ops-{bound,unbind}_driver()

2013-12-12 Thread Hiroshi Doyu
ops-{bound,unbind}_driver() functions are called at
BUS_NOTIFY_{BOUND,UNBIND}_DRIVER respectively.

This is necessary to control the device population order. IOMMU master
devices depend on an IOMMU device instanciation. IOMMU master devices
can be registered to an IOMMU only after it's successfully
populated. This IOMMU registration is done via
ops-bound_driver(). Currently this population can be deferred if
depending IOMMU device hasn't yet been populated in driver core. This
cannot be done via ops-add_device() since after add_device() device's
population/instanciation can be still deferred via probe().

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v6:
New for v6.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/iommu/iommu.c | 13 +++--
 include/linux/iommu.h |  4 
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index efc..5469d36 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -540,14 +540,23 @@ static int iommu_bus_notifier(struct notifier_block *nb,
 * ADD/DEL call into iommu driver ops if provided, which may
 * result in ADD/DEL notifiers to group-notifier
 */
-   if (action == BUS_NOTIFY_ADD_DEVICE) {
+   switch (action) {
+   case BUS_NOTIFY_ADD_DEVICE:
if (ops-add_device)
return ops-add_device(dev);
-   } else if (action == BUS_NOTIFY_DEL_DEVICE) {
+   case BUS_NOTIFY_DEL_DEVICE:
if (ops-remove_device  dev-iommu_group) {
ops-remove_device(dev);
return 0;
}
+   case BUS_NOTIFY_BOUND_DRIVER:
+   if (ops-bound_driver)
+   ops-bound_driver(dev);
+   break;
+   case BUS_NOTIFY_UNBIND_DRIVER:
+   if (ops-unbind_driver)
+   ops-unbind_driver(dev);
+   break;
}
 
/*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index a444c79..a0e92be 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -96,6 +96,8 @@ enum iommu_attr {
  * @domain_has_cap: domain capabilities query
  * @add_device: add device to iommu grouping
  * @remove_device: remove device from iommu grouping
+ * @bound_driver: called at BUS_NOTIFY_BOUND_DRIVER
+ * @unbind_driver: called at BUS_NOTIFY_UNBIND_DRIVER
  * @domain_get_attr: Query domain attributes
  * @domain_set_attr: Change domain attributes
  * @pgsize_bitmap: bitmap of supported page sizes
@@ -114,6 +116,8 @@ struct iommu_ops {
  unsigned long cap);
int (*add_device)(struct device *dev);
void (*remove_device)(struct device *dev);
+   int (*bound_driver)(struct device *dev);
+   void (*unbind_driver)(struct device *dev);
int (*device_group)(struct device *dev, unsigned int *groupid);
int (*domain_get_attr)(struct iommu_domain *domain,
   enum iommu_attr attr, void *data);
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv6+ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-12 Thread Hiroshi Doyu
Grant Likely grant.lik...@linaro.org wrote @ Thu, 12 Dec 2013 12:34:17 +0100:

 On Wed, 11 Dec 2013 14:33:38 +0100, Hiroshi Doyu hd...@nvidia.com wrote:
  Hi Grant,
 
  Grant Likely grant.lik...@linaro.org wrote @ Wed, 11 Dec 2013 14:28:45 
  +0100:
 
   On Thu, 21 Nov 2013 11:57:00 -0700, Stephen Warren 
   swar...@wwwdotorg.org wrote:
On 11/21/2013 10:17 AM, Hiroshi Doyu wrote:
 Iterating over a property containing a list of phandles with arguments
 is a common operation for device drivers. This patch adds a new
 of_property_for_each_phandle_with_args() macro to make the iteration
 simpler.

 Signed-off-by: Hiroshi Doyu hd...@nvidia.com
 ---
 v6+:
 Use the description, which Grant Likely proposed, to be full enough
 that a future reader can figure out why a patch was written.
   
 http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007062.html
  ...
 
   That's right, I forgot I said that. Yes please fix the implementation.
 
  Here's the latest. I'll include this with the next v7 series.
 
  Can I get your Acked-by with this?
 
  --8
 
  From 8f7c0404aa68f0e8dbe0babc240590f6528ecc1f Mon Sep 17 00:00:00 2001
  From: Hiroshi Doyu hd...@nvidia.com
  Date: Fri, 15 Nov 2013 10:52:53 +0200
  Subject: [PATCH] of: introduce of_property_for_each_phandle_with_args()
 
  Iterating over a property containing a list of phandles with arguments
  is a common operation for device drivers. This patch adds a new
  of_property_for_each_phandle_with_args() macro to make the iteration
  simpler.
 
  Signed-off-by: Hiroshi Doyu hd...@nvidia.com
  Cc: Rob Herring robherri...@gmail.com
  ---
  v7:
  Fixed some minors pointed by Rob and Stephen.
 
  v6:
  Iterate without intrducing a new struct.
 
  v6+++:
  Introduced a new struct of_phandle_iter to keep the state when
  iterating over the list.
 
  v6++:
  Optimized to avoid O(n^2), suggested by Stephen Warren.
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html
 
  I didn't introduce any struct to hold params and state here.
 
  v6+:
  Use the description, which Grant Likely proposed, to be full enough
  that a future reader can figure out why a patch was written.
 
  v5:
  New patch for v5.
 
  Signed-off-by: Hiroshi Doyu hd...@nvidia.com
  ---
   drivers/of/base.c  | 46 ++
   include/linux/of.h | 32 
   2 files changed, 78 insertions(+)
 
  diff --git a/drivers/of/base.c b/drivers/of/base.c
  index f807d0e..cd4ab05 100644
  --- a/drivers/of/base.c
  +++ b/drivers/of/base.c
  @@ -1201,6 +1201,52 @@ void of_print_phandle_args(const char *msg, const 
  struct of_phandle_args *args)
printk(\n);
   }
 
  +const __be32 *of_phandle_iter_next(const char *cells_name, int cell_count,
  +const __be32 *cur, const __be32 *end,
  +struct of_phandle_args *out_args)
 
 Having to pass in cells_name, cell_count, cur and end each time seems a
 little odd. Can a state structure be used instead?
 
 struct of_phandle_iter_state {
 const char *cells_name;
 int cells_count;
 const __be32 *cur;
 const __be32 *end;
 struct of_phandle_args out_args;
 }
 
 Make the caller provide one of those and fill it in with the init
 function.

I rewrote this a few times and so now I have a few version of this
implementations :-) The above proposal is similar to the version v6+++
mentioned in the above patch note:

  v6+++:
  Introduced a new struct of_phandle_iter to keep the state when
  iterating over the list.

which is:

  [RFC][PATCHv6+++ 01/13] of: introduce 
of_property_for_earch_phandle_with_args()
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007087.html

Stephen seemed to prefer the version without state struct. I like the
idea to not pass the same arguments repeatly. Instead, wrapping them
in a struct with state may look better.

So if Stephen agrees, I'll rewrite the version with state struct
again.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 01/12] of: introduce of_property_for_each_phandle_with_args()

2013-12-11 Thread Hiroshi Doyu
Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Signed-off-by: Hiroshi Doyu 
Cc: Rob Herring 
Cc: Grant Likely 
---
v7:
Fixed some minors pointed by Rob and Stephen.

v6:
Iterate without intrducing a new struct.

v6+++:
Introduced a new struct "of_phandle_iter" to keep the state when
iterating over the list.

v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

I didn't introduce any struct to hold params and state here.

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu 
---
 drivers/of/base.c  | 46 ++
 include/linux/of.h | 32 
 2 files changed, 78 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..cd4ab05 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,52 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk("\n");
 }
 
+const __be32 *of_phandle_iter_next(const char *cells_name, int cell_count,
+  const __be32 *cur, const __be32 *end,
+  struct of_phandle_args *out_args)
+{
+   struct device_node *dn;
+   int i;
+
+   if (!cells_name && !cell_count)
+   return NULL;
+
+   if (!cur || (cur >= end))
+   return NULL;
+
+   dn = of_find_node_by_phandle(be32_to_cpup(cur++));
+   if (!dn)
+   return NULL;
+
+   if (cells_name)
+   if (of_property_read_u32(dn, cells_name, _count))
+   return NULL;
+
+   out_args->np = dn;
+   out_args->args_count = cell_count;
+   for (i = 0; i < cell_count; i++)
+   out_args->args[i] = be32_to_cpup(cur++);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_next);
+
+const __be32 *of_phandle_iter_init(const struct device_node *np,
+  const char *list_name,
+  const __be32 **end)
+{
+   size_t bytes;
+   const __be32 *cur;
+
+   cur = of_get_property(np, list_name, );
+   *end = cur;
+   if (bytes)
+   *end += bytes / sizeof(*cur);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_init);
+
 static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..4345582 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -303,6 +303,14 @@ extern int of_parse_phandle_with_fixed_args(const struct 
device_node *np,
 extern int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name);
 
+extern const __be32 *of_phandle_iter_init(const struct device_node *np,
+ const char *list_name,
+ const __be32 **end);
+extern const __be32 *of_phandle_iter_next(const char *cells_name,
+ int cell_count,
+ const __be32 *cur, const __be32 *end,
+ struct of_phandle_args *out_args);
+
 extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
 extern int of_alias_get_id(struct device_node *np, const char *stem);
 
@@ -527,6 +535,22 @@ static inline int of_count_phandle_with_args(struct 
device_node *np,
return -ENOSYS;
 }
 
+static inline const __be32 *of_phandle_iter_init(const struct device_node *np,
+const char *list_name,
+const __be32 **end)
+{
+   return NULL;
+}
+
+static inline const __be32 *of_phandle_iter_next(const char *cells_name,
+int cell_count,
+const __be32 *cur,
+const __be32 *end,
+struct of_phandle_args 
*out_args);
+{
+   return NULL;
+}
+
 static inline int of_alias_get_id(struct device_node *np, const char *stem)
 {
return -ENOSYS;
@@ -613,6 +637,14 @@ static inline int of_property_read_u32(const struct 
device_node *np,
s;  \
s = of_prop_next_string(prop, s))
 
+#define of_property_for_each_ph

[PATCHv7 00/12] Unifying SMMU driver among Tegra SoCs

2013-12-11 Thread Hiroshi Doyu
Hi,

This series provide:

(0) IOMMU standard DT binding("iommus")
(1) Unified IOMMU(SMMU) driver among Tegra SoCs
(2) Multiple Address Space support(MASID) in IOMMU(SMMMU)
(3) Tegra IOMMU'able devices, most of platform devices are IOMMU'able.

There's been some discussion[1] about device population order. Some
devices needs to be populated earlier than other devices regardless of
their bus topology. For the solution I implemented an IOMMU hook in
driver core:

  [PATCHv7 04/13] driver/core: populate devices in order for IOMMUs

which is based on:
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006933.html

The main problem here is,

IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, "iommus=" DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an iommu device is populated. Then,
those defered iommu master devices are populated and configured with
help of the already populated iommu device via a new IOMMU API
iommu_ops->driver_bound().

This "iommus=" binding is expected used as the global/standard binding.

Tested IOMMU functionality with T30 SD/MMC. Any further testing with
T114 and/or other devices would be really appreciated.

v6:
Minior fixes.
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/213082.html

v5:
Use "iommus=" DT bindings as a standard IOMMU binding.
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/212331.html

v4:
Add a hook in driver core to control device populatin order.
Introduced arm,smmu "mmu-master" binding instead of tegra own.
Removed DT patches from this series.
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006931.html

v3:
Updated based on Stephen Warren's feedback
  http://lists.linuxfoundation.org/pipermail/iommu/2013-October/006724.html

v2:
Updated based on Thierry Reding's and Stephen Warren's feedback
  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/181888.html

v1:
  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/180267.html

Available in the git repository at:

  git://g...@nv-tegra.nvidia.com/user/hdoyu/linux.git smmu-upstreaming@20131212

Hiroshi Doyu (12):
  of: introduce of_property_for_each_phandle_with_args()
  iommu/of: introduce a global iommu device list
  iommu/of: check if dependee iommu is ready or not
  driver/core: populate devices in order for IOMMUs
  iommu/core: add ops->{bound,unbind}_driver()
  ARM: tegra: create a DT header defining SWGROUP ID
  iommu/tegra: smmu: register device to iommu dynamically
  iommu/tegra: smmu: calculate ASID register offset by ID
  iommu/tegra: smmu: get swgroups from DT "iommus="
  iommu/tegra: smmu: allow duplicate ASID wirte
  iommu/tegra: smmu: Rename hwgrp -> swgroups
  iommu/tegra: smmu: add SMMU to an global iommu list

 .../bindings/iommu/nvidia,tegra30-smmu.txt |  30 +-
 drivers/base/dd.c  |   5 +
 drivers/iommu/Kconfig  |   1 +
 drivers/iommu/iommu.c  |  13 +-
 drivers/iommu/of_iommu.c   |  51 +++
 drivers/iommu/tegra-smmu.c | 383 +
 drivers/of/base.c  |  46 +++
 include/dt-bindings/memory/tegra-swgroup.h |  50 +++
 include/linux/iommu.h  |   4 +
 include/linux/of.h |  32 ++
 include/linux/of_iommu.h   |  22 ++
 11 files changed, 487 insertions(+), 150 deletions(-)
 create mode 100644 include/dt-bindings/memory/tegra-swgroup.h

-- 
1.8.1.5

[1]
  "[RFC] early init and DT platform devices allocation/registration"

https://lists.ozlabs.org/pipermail/devicetree-discuss/2013-June/thread.html#36542
  "Report from 2013 ARM kernel summit"

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/210426.html
  "[RFC PATCH] Documentation: devicetree: add description for generic bus 
properties"

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/215042.html

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv6+ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-11 Thread Hiroshi Doyu
Hi Grant,

Grant Likely  wrote @ Wed, 11 Dec 2013 14:28:45 +0100:

> On Thu, 21 Nov 2013 11:57:00 -0700, Stephen Warren  
> wrote:
> > On 11/21/2013 10:17 AM, Hiroshi Doyu wrote:
> > > Iterating over a property containing a list of phandles with arguments
> > > is a common operation for device drivers. This patch adds a new
> > > of_property_for_each_phandle_with_args() macro to make the iteration
> > > simpler.
> > > 
> > > Signed-off-by: Hiroshi Doyu 
> > > ---
> > > v6+:
> > > Use the description, which Grant Likely proposed, to be full enough
> > > that a future reader can figure out why a patch was written.
> > >   
> > > http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007062.html
...

> That's right, I forgot I said that. Yes please fix the implementation.

Here's the latest. I'll include this with the next v7 series.

Can I get your Acked-by with this?

--8<

>From 8f7c0404aa68f0e8dbe0babc240590f6528ecc1f Mon Sep 17 00:00:00 2001
From: Hiroshi Doyu 
Date: Fri, 15 Nov 2013 10:52:53 +0200
Subject: [PATCH] of: introduce of_property_for_each_phandle_with_args()

Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Signed-off-by: Hiroshi Doyu 
Cc: Rob Herring 
---
v7:
Fixed some minors pointed by Rob and Stephen.

v6:
Iterate without intrducing a new struct.

v6+++:
Introduced a new struct "of_phandle_iter" to keep the state when
iterating over the list.

v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

I didn't introduce any struct to hold params and state here.

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu 
---
 drivers/of/base.c  | 46 ++
 include/linux/of.h | 32 
 2 files changed, 78 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..cd4ab05 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,52 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk("\n");
 }
 
+const __be32 *of_phandle_iter_next(const char *cells_name, int cell_count,
+  const __be32 *cur, const __be32 *end,
+  struct of_phandle_args *out_args)
+{
+   struct device_node *dn;
+   int i;
+
+   if (!cells_name && !cell_count)
+   return NULL;
+
+   if (!cur || (cur >= end))
+   return NULL;
+
+   dn = of_find_node_by_phandle(be32_to_cpup(cur++));
+   if (!dn)
+   return NULL;
+
+   if (cells_name)
+   if (of_property_read_u32(dn, cells_name, _count))
+   return NULL;
+
+   out_args->np = dn;
+   out_args->args_count = cell_count;
+   for (i = 0; i < cell_count; i++)
+   out_args->args[i] = be32_to_cpup(cur++);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_next);
+
+const __be32 *of_phandle_iter_init(const struct device_node *np,
+  const char *list_name,
+  const __be32 **end)
+{
+   size_t bytes;
+   const __be32 *cur;
+
+   cur = of_get_property(np, list_name, );
+   *end = cur;
+   if (bytes)
+   *end += bytes / sizeof(*cur);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_init);
+
 static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..4345582 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -303,6 +303,14 @@ extern int of_parse_phandle_with_fixed_args(const struct 
device_node *np,
 extern int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name);
 
+extern const __be32 *of_phandle_iter_init(const struct device_node *np,
+ const char *list_name,
+ const __be32 **end);
+extern const __be32 *of_phandle_iter_next(const char *cells_name,
+ int cell_count,
+ const __be32 *cur, const __be32 *end,
+ struct of_phandle_args *out_args);
+
 extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
 extern int of

Re: [PATCHv6+ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-11 Thread Hiroshi Doyu
Hi Grant,

Grant Likely grant.lik...@linaro.org wrote @ Wed, 11 Dec 2013 14:28:45 +0100:

 On Thu, 21 Nov 2013 11:57:00 -0700, Stephen Warren swar...@wwwdotorg.org 
 wrote:
  On 11/21/2013 10:17 AM, Hiroshi Doyu wrote:
   Iterating over a property containing a list of phandles with arguments
   is a common operation for device drivers. This patch adds a new
   of_property_for_each_phandle_with_args() macro to make the iteration
   simpler.
   
   Signed-off-by: Hiroshi Doyu hd...@nvidia.com
   ---
   v6+:
   Use the description, which Grant Likely proposed, to be full enough
   that a future reader can figure out why a patch was written.
 
   http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007062.html
...

 That's right, I forgot I said that. Yes please fix the implementation.

Here's the latest. I'll include this with the next v7 series.

Can I get your Acked-by with this?

--8

From 8f7c0404aa68f0e8dbe0babc240590f6528ecc1f Mon Sep 17 00:00:00 2001
From: Hiroshi Doyu hd...@nvidia.com
Date: Fri, 15 Nov 2013 10:52:53 +0200
Subject: [PATCH] of: introduce of_property_for_each_phandle_with_args()

Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
Cc: Rob Herring robherri...@gmail.com
---
v7:
Fixed some minors pointed by Rob and Stephen.

v6:
Iterate without intrducing a new struct.

v6+++:
Introduced a new struct of_phandle_iter to keep the state when
iterating over the list.

v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

I didn't introduce any struct to hold params and state here.

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/of/base.c  | 46 ++
 include/linux/of.h | 32 
 2 files changed, 78 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..cd4ab05 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,52 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk(\n);
 }
 
+const __be32 *of_phandle_iter_next(const char *cells_name, int cell_count,
+  const __be32 *cur, const __be32 *end,
+  struct of_phandle_args *out_args)
+{
+   struct device_node *dn;
+   int i;
+
+   if (!cells_name  !cell_count)
+   return NULL;
+
+   if (!cur || (cur = end))
+   return NULL;
+
+   dn = of_find_node_by_phandle(be32_to_cpup(cur++));
+   if (!dn)
+   return NULL;
+
+   if (cells_name)
+   if (of_property_read_u32(dn, cells_name, cell_count))
+   return NULL;
+
+   out_args-np = dn;
+   out_args-args_count = cell_count;
+   for (i = 0; i  cell_count; i++)
+   out_args-args[i] = be32_to_cpup(cur++);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_next);
+
+const __be32 *of_phandle_iter_init(const struct device_node *np,
+  const char *list_name,
+  const __be32 **end)
+{
+   size_t bytes;
+   const __be32 *cur;
+
+   cur = of_get_property(np, list_name, bytes);
+   *end = cur;
+   if (bytes)
+   *end += bytes / sizeof(*cur);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_init);
+
 static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..4345582 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -303,6 +303,14 @@ extern int of_parse_phandle_with_fixed_args(const struct 
device_node *np,
 extern int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name);
 
+extern const __be32 *of_phandle_iter_init(const struct device_node *np,
+ const char *list_name,
+ const __be32 **end);
+extern const __be32 *of_phandle_iter_next(const char *cells_name,
+ int cell_count,
+ const __be32 *cur, const __be32 *end,
+ struct of_phandle_args *out_args);
+
 extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
 extern int of_alias_get_id(struct device_node *np, const char *stem);
 
@@ -527,6 +535,22 @@ static inline int

[PATCHv7 00/12] Unifying SMMU driver among Tegra SoCs

2013-12-11 Thread Hiroshi Doyu
Hi,

This series provide:

(0) IOMMU standard DT binding(iommus)
(1) Unified IOMMU(SMMU) driver among Tegra SoCs
(2) Multiple Address Space support(MASID) in IOMMU(SMMMU)
(3) Tegra IOMMU'able devices, most of platform devices are IOMMU'able.

There's been some discussion[1] about device population order. Some
devices needs to be populated earlier than other devices regardless of
their bus topology. For the solution I implemented an IOMMU hook in
driver core:

  [PATCHv7 04/13] driver/core: populate devices in order for IOMMUs

which is based on:
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006933.html

The main problem here is,

IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, iommus= DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an iommu device is populated. Then,
those defered iommu master devices are populated and configured with
help of the already populated iommu device via a new IOMMU API
iommu_ops-driver_bound().

This iommus= binding is expected used as the global/standard binding.

Tested IOMMU functionality with T30 SD/MMC. Any further testing with
T114 and/or other devices would be really appreciated.

v6:
Minior fixes.
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/213082.html

v5:
Use iommus= DT bindings as a standard IOMMU binding.
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/212331.html

v4:
Add a hook in driver core to control device populatin order.
Introduced arm,smmu mmu-master binding instead of tegra own.
Removed DT patches from this series.
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006931.html

v3:
Updated based on Stephen Warren's feedback
  http://lists.linuxfoundation.org/pipermail/iommu/2013-October/006724.html

v2:
Updated based on Thierry Reding's and Stephen Warren's feedback
  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/181888.html

v1:
  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/180267.html

Available in the git repository at:

  git://g...@nv-tegra.nvidia.com/user/hdoyu/linux.git smmu-upstreaming@20131212

Hiroshi Doyu (12):
  of: introduce of_property_for_each_phandle_with_args()
  iommu/of: introduce a global iommu device list
  iommu/of: check if dependee iommu is ready or not
  driver/core: populate devices in order for IOMMUs
  iommu/core: add ops-{bound,unbind}_driver()
  ARM: tegra: create a DT header defining SWGROUP ID
  iommu/tegra: smmu: register device to iommu dynamically
  iommu/tegra: smmu: calculate ASID register offset by ID
  iommu/tegra: smmu: get swgroups from DT iommus=
  iommu/tegra: smmu: allow duplicate ASID wirte
  iommu/tegra: smmu: Rename hwgrp - swgroups
  iommu/tegra: smmu: add SMMU to an global iommu list

 .../bindings/iommu/nvidia,tegra30-smmu.txt |  30 +-
 drivers/base/dd.c  |   5 +
 drivers/iommu/Kconfig  |   1 +
 drivers/iommu/iommu.c  |  13 +-
 drivers/iommu/of_iommu.c   |  51 +++
 drivers/iommu/tegra-smmu.c | 383 +
 drivers/of/base.c  |  46 +++
 include/dt-bindings/memory/tegra-swgroup.h |  50 +++
 include/linux/iommu.h  |   4 +
 include/linux/of.h |  32 ++
 include/linux/of_iommu.h   |  22 ++
 11 files changed, 487 insertions(+), 150 deletions(-)
 create mode 100644 include/dt-bindings/memory/tegra-swgroup.h

-- 
1.8.1.5

[1]
  [RFC] early init and DT platform devices allocation/registration

https://lists.ozlabs.org/pipermail/devicetree-discuss/2013-June/thread.html#36542
  Report from 2013 ARM kernel summit

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/210426.html
  [RFC PATCH] Documentation: devicetree: add description for generic bus 
properties

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-November/215042.html

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv7 01/12] of: introduce of_property_for_each_phandle_with_args()

2013-12-11 Thread Hiroshi Doyu
Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
Cc: Rob Herring robherri...@gmail.com
Cc: Grant Likely grant.lik...@linaro.org
---
v7:
Fixed some minors pointed by Rob and Stephen.

v6:
Iterate without intrducing a new struct.

v6+++:
Introduced a new struct of_phandle_iter to keep the state when
iterating over the list.

v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

I didn't introduce any struct to hold params and state here.

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/of/base.c  | 46 ++
 include/linux/of.h | 32 
 2 files changed, 78 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..cd4ab05 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,52 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk(\n);
 }
 
+const __be32 *of_phandle_iter_next(const char *cells_name, int cell_count,
+  const __be32 *cur, const __be32 *end,
+  struct of_phandle_args *out_args)
+{
+   struct device_node *dn;
+   int i;
+
+   if (!cells_name  !cell_count)
+   return NULL;
+
+   if (!cur || (cur = end))
+   return NULL;
+
+   dn = of_find_node_by_phandle(be32_to_cpup(cur++));
+   if (!dn)
+   return NULL;
+
+   if (cells_name)
+   if (of_property_read_u32(dn, cells_name, cell_count))
+   return NULL;
+
+   out_args-np = dn;
+   out_args-args_count = cell_count;
+   for (i = 0; i  cell_count; i++)
+   out_args-args[i] = be32_to_cpup(cur++);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_next);
+
+const __be32 *of_phandle_iter_init(const struct device_node *np,
+  const char *list_name,
+  const __be32 **end)
+{
+   size_t bytes;
+   const __be32 *cur;
+
+   cur = of_get_property(np, list_name, bytes);
+   *end = cur;
+   if (bytes)
+   *end += bytes / sizeof(*cur);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_init);
+
 static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..4345582 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -303,6 +303,14 @@ extern int of_parse_phandle_with_fixed_args(const struct 
device_node *np,
 extern int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name);
 
+extern const __be32 *of_phandle_iter_init(const struct device_node *np,
+ const char *list_name,
+ const __be32 **end);
+extern const __be32 *of_phandle_iter_next(const char *cells_name,
+ int cell_count,
+ const __be32 *cur, const __be32 *end,
+ struct of_phandle_args *out_args);
+
 extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
 extern int of_alias_get_id(struct device_node *np, const char *stem);
 
@@ -527,6 +535,22 @@ static inline int of_count_phandle_with_args(struct 
device_node *np,
return -ENOSYS;
 }
 
+static inline const __be32 *of_phandle_iter_init(const struct device_node *np,
+const char *list_name,
+const __be32 **end)
+{
+   return NULL;
+}
+
+static inline const __be32 *of_phandle_iter_next(const char *cells_name,
+int cell_count,
+const __be32 *cur,
+const __be32 *end,
+struct of_phandle_args 
*out_args);
+{
+   return NULL;
+}
+
 static inline int of_alias_get_id(struct device_node *np, const char *stem)
 {
return -ENOSYS;
@@ -613,6 +637,14 @@ static inline int of_property_read_u32(const struct 
device_node *np,
s;  \
s = of_prop_next_string(prop, s))
 
+#define of_property_for_each_phandle_with_args(node

Re: [PATCHv6 05/13] iommu/core: add ops->{bound,unbind}_driver()

2013-12-03 Thread Hiroshi Doyu
On Mon, 25 Nov 2013 14:49:37 +0100
Hiroshi Doyu  wrote:

> Hi Joerg,
> 
> Do you have some time to review this patch along with the following ones?
> 
>   [PATCHv6 02/13] iommu/of: introduce a global iommu device list
>   http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007050.html
> 
>   [PATCHv6 03/13] iommu/of: check if dependee iommu is ready or not
>   http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007051.html

Any chance to get some feedback on them?

> With those patches, now I'm trying to populate iommu master devices
> after an IOMMU device is populated. Originally [PATCHv6 02/13] was
> proposed by Thierry. I'm a bit afraid of adding new IOMMU API as
> this, but I think that this new {bound,unbind}_driver() is the right
> timiing that depeding devices are populated instead of add_device()
> since, even after add_device, a device won't be populated. I'm not so
> sure how this affects on the existing IOMMUs.
> 
> It would be nice if you give some feedback on this.
> 
> On Thu, 21 Nov 2013 14:40:41 +0100
> Hiroshi Doyu  wrote:
> 
> > ops->{bound,unbind}_driver() functions are called at
> > BUS_NOTIFY_{BOUND,UNBIND}_DRIVER respectively.
> > 
> > This is necessary to control the device population order. IOMMU master
> > devices depend on an IOMMU device instanciation. IOMMU master devices
> > can be registered to an IOMMU only after it's successfully
> > populated. This IOMMU registration is done via
> > ops->bound_driver(). Currently this population can be deferred if
> > depending IOMMU device hasn't yet been populated in driver core. This
> > cannot be done via ops->add_device() since after add_device() device's
> > population/instanciation can be still deferred via probe().
> > 
> > Signed-off-by: Hiroshi Doyu 
> > ---
> > v6:
> > New for v6.
> > ---
> >  drivers/iommu/iommu.c | 13 +++--
> >  include/linux/iommu.h |  4 
> >  2 files changed, 15 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index efc..5469d36 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -540,14 +540,23 @@ static int iommu_bus_notifier(struct notifier_block 
> > *nb,
> >  * ADD/DEL call into iommu driver ops if provided, which may
> >  * result in ADD/DEL notifiers to group->notifier
> >  */
> > -   if (action == BUS_NOTIFY_ADD_DEVICE) {
> > +   switch (action) {
> > +   case BUS_NOTIFY_ADD_DEVICE:
> > if (ops->add_device)
> > return ops->add_device(dev);
> > -   } else if (action == BUS_NOTIFY_DEL_DEVICE) {
> > +   case BUS_NOTIFY_DEL_DEVICE:
> > if (ops->remove_device && dev->iommu_group) {
> > ops->remove_device(dev);
> > return 0;
> > }
> > +   case BUS_NOTIFY_BOUND_DRIVER:
> > +   if (ops->bound_driver)
> > +   ops->bound_driver(dev);
> > +   break;
> > +   case BUS_NOTIFY_UNBIND_DRIVER:
> > +   if (ops->unbind_driver)
> > +   ops->unbind_driver(dev);
> > +   break;
> > }
> >  
> > /*
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index a444c79..a0e92be 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -96,6 +96,8 @@ enum iommu_attr {
> >   * @domain_has_cap: domain capabilities query
> >   * @add_device: add device to iommu grouping
> >   * @remove_device: remove device from iommu grouping
> > + * @bound_driver: called at BUS_NOTIFY_BOUND_DRIVER
> > + * @unbind_driver: called at BUS_NOTIFY_UNBIND_DRIVER
> >   * @domain_get_attr: Query domain attributes
> >   * @domain_set_attr: Change domain attributes
> >   * @pgsize_bitmap: bitmap of supported page sizes
> > @@ -114,6 +116,8 @@ struct iommu_ops {
> >   unsigned long cap);
> > int (*add_device)(struct device *dev);
> > void (*remove_device)(struct device *dev);
> > +   int (*bound_driver)(struct device *dev);
> > +   void (*unbind_driver)(struct device *dev);
> > int (*device_group)(struct device *dev, unsigned int *groupid);
> > int (*domain_get_attr)(struct iommu_domain *domain,
> >enum iommu_attr attr, void *data);
> > -- 
> > 1.8.1.5
> > 
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv6 05/13] iommu/core: add ops-{bound,unbind}_driver()

2013-12-03 Thread Hiroshi Doyu
On Mon, 25 Nov 2013 14:49:37 +0100
Hiroshi Doyu hd...@nvidia.com wrote:

 Hi Joerg,
 
 Do you have some time to review this patch along with the following ones?
 
   [PATCHv6 02/13] iommu/of: introduce a global iommu device list
   http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007050.html
 
   [PATCHv6 03/13] iommu/of: check if dependee iommu is ready or not
   http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007051.html

Any chance to get some feedback on them?

 With those patches, now I'm trying to populate iommu master devices
 after an IOMMU device is populated. Originally [PATCHv6 02/13] was
 proposed by Thierry. I'm a bit afraid of adding new IOMMU API as
 this, but I think that this new {bound,unbind}_driver() is the right
 timiing that depeding devices are populated instead of add_device()
 since, even after add_device, a device won't be populated. I'm not so
 sure how this affects on the existing IOMMUs.
 
 It would be nice if you give some feedback on this.
 
 On Thu, 21 Nov 2013 14:40:41 +0100
 Hiroshi Doyu hd...@nvidia.com wrote:
 
  ops-{bound,unbind}_driver() functions are called at
  BUS_NOTIFY_{BOUND,UNBIND}_DRIVER respectively.
  
  This is necessary to control the device population order. IOMMU master
  devices depend on an IOMMU device instanciation. IOMMU master devices
  can be registered to an IOMMU only after it's successfully
  populated. This IOMMU registration is done via
  ops-bound_driver(). Currently this population can be deferred if
  depending IOMMU device hasn't yet been populated in driver core. This
  cannot be done via ops-add_device() since after add_device() device's
  population/instanciation can be still deferred via probe().
  
  Signed-off-by: Hiroshi Doyu hd...@nvidia.com
  ---
  v6:
  New for v6.
  ---
   drivers/iommu/iommu.c | 13 +++--
   include/linux/iommu.h |  4 
   2 files changed, 15 insertions(+), 2 deletions(-)
  
  diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
  index efc..5469d36 100644
  --- a/drivers/iommu/iommu.c
  +++ b/drivers/iommu/iommu.c
  @@ -540,14 +540,23 @@ static int iommu_bus_notifier(struct notifier_block 
  *nb,
   * ADD/DEL call into iommu driver ops if provided, which may
   * result in ADD/DEL notifiers to group-notifier
   */
  -   if (action == BUS_NOTIFY_ADD_DEVICE) {
  +   switch (action) {
  +   case BUS_NOTIFY_ADD_DEVICE:
  if (ops-add_device)
  return ops-add_device(dev);
  -   } else if (action == BUS_NOTIFY_DEL_DEVICE) {
  +   case BUS_NOTIFY_DEL_DEVICE:
  if (ops-remove_device  dev-iommu_group) {
  ops-remove_device(dev);
  return 0;
  }
  +   case BUS_NOTIFY_BOUND_DRIVER:
  +   if (ops-bound_driver)
  +   ops-bound_driver(dev);
  +   break;
  +   case BUS_NOTIFY_UNBIND_DRIVER:
  +   if (ops-unbind_driver)
  +   ops-unbind_driver(dev);
  +   break;
  }
   
  /*
  diff --git a/include/linux/iommu.h b/include/linux/iommu.h
  index a444c79..a0e92be 100644
  --- a/include/linux/iommu.h
  +++ b/include/linux/iommu.h
  @@ -96,6 +96,8 @@ enum iommu_attr {
* @domain_has_cap: domain capabilities query
* @add_device: add device to iommu grouping
* @remove_device: remove device from iommu grouping
  + * @bound_driver: called at BUS_NOTIFY_BOUND_DRIVER
  + * @unbind_driver: called at BUS_NOTIFY_UNBIND_DRIVER
* @domain_get_attr: Query domain attributes
* @domain_set_attr: Change domain attributes
* @pgsize_bitmap: bitmap of supported page sizes
  @@ -114,6 +116,8 @@ struct iommu_ops {
unsigned long cap);
  int (*add_device)(struct device *dev);
  void (*remove_device)(struct device *dev);
  +   int (*bound_driver)(struct device *dev);
  +   void (*unbind_driver)(struct device *dev);
  int (*device_group)(struct device *dev, unsigned int *groupid);
  int (*domain_get_attr)(struct iommu_domain *domain,
 enum iommu_attr attr, void *data);
  -- 
  1.8.1.5
  
 ___
 iommu mailing list
 io...@lists.linux-foundation.org
 https://lists.linuxfoundation.org/mailman/listinfo/iommu
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC][PATCHv6+++ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-02 Thread Hiroshi Doyu
On Mon, 2 Dec 2013 15:39:25 +0100
Rob Herring  wrote:

> On Mon, Dec 2, 2013 at 5:02 AM, Hiroshi Doyu  wrote:
> > Stephen Warren  wrote @ Sun, 1 Dec 2013 20:00:09 
> > +0100:
> >
> >> On 11/29/2013 04:46 AM, Hiroshi Doyu wrote:
> >> ...
> >> > Iterating over a property containing a list of phandles with arguments
> >> > is a common operation for device drivers. This patch adds a new
> >> > of_property_for_each_phandle_with_args() macro to make the iteration
> >> > simpler.
> >> >
> >> > Introduced a new struct "of_phandle_iter" to keep the state when
> >> > iterating over the list.
> >> >
> >> > Signed-off-by: Hiroshi Doyu 


Rob, thank you for review.
I'll fix them and put this one into the next v7 series.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC][PATCHv6+++ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-02 Thread Hiroshi Doyu
Stephen Warren  wrote @ Sun, 1 Dec 2013 20:00:09 +0100:

> On 11/29/2013 04:46 AM, Hiroshi Doyu wrote:
> ...
> > Iterating over a property containing a list of phandles with arguments
> > is a common operation for device drivers. This patch adds a new
> > of_property_for_each_phandle_with_args() macro to make the iteration
> > simpler.
> > 
> > Introduced a new struct "of_phandle_iter" to keep the state when
> > iterating over the list.
> > 
> > Signed-off-by: Hiroshi Doyu 
> > ---
> > v6+++:
> 
> Surely that's v9; "+++" is rather unusual.

My intention was to put this into the next v7 series after I get this
reviewed as RFC.
...
> Together with removing:
> 
> > +   const char  *cells_name;
> > +   int cell_count;
> 
> ... then you'd only be left with cur/end, so I think you could get away
> without a struct at all, but simply "cur" as the iterator variable, plus
> "end" as the one temp variable.

Although the above proposal would be alsmot same as "[RFC][PATCHv6++
01/13]"(*1) where I use *list(cur) and rem as remaining count, here's
the update. I'll put this into v7 series.

---8<--8<--8<--8<--8<--8<--8<--8<--8<---
From: Hiroshi Doyu 

Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Signed-off-by: Hiroshi Doyu 
---
v6:
Iterate without intrducing a new struct.

v6+++:
Introduced a new struct "of_phandle_iter" to keep the state when
iterating over the list.

v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

I didn't introduce any struct to hold params and state here.

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu 
---
 drivers/of/base.c  | 53 +
 include/linux/of.h | 34 ++
 2 files changed, 87 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..7501f24 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,59 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk("\n");
 }
 
+const __be32 *of_phandle_iter_next(const char *cells_name, int cell_count,
+  const __be32 *cur, const __be32 *end,
+  struct of_phandle_args *out_args)
+{
+   phandle phandle;
+   struct device_node *dn;
+   int i;
+
+   if (!cells_name && !cell_count)
+   return NULL;
+
+   if (!cur)
+   return NULL;
+
+   if (end - cur <= 0)
+   return NULL;
+
+   phandle = be32_to_cpup(cur++);
+   if (!phandle)
+   return NULL;
+
+   dn = of_find_node_by_phandle(phandle);
+   if (!dn)
+   return NULL;
+
+   if (cells_name)
+   if (of_property_read_u32(dn, cells_name, _count))
+   return NULL;
+
+   out_args->np = dn;
+   out_args->args_count = cell_count;
+   for (i = 0; i < cell_count; i++)
+   out_args->args[i] = be32_to_cpup(cur++);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_next);
+
+const __be32 *of_phandle_iter_init(const struct device_node *np,
+  const char *list_name,
+  const __be32 **end)
+{
+   size_t bytes;
+   const __be32 *cur;
+
+   cur = of_get_property(np, list_name, );
+   if (bytes)
+   *end = cur + bytes / sizeof(*cur);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_init);
+
 static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..c23710b 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -303,6 +303,14 @@ extern int of_parse_phandle_with_fixed_args(const struct 
device_node *np,
 extern int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name);
 
+extern const __be32 *of_phandle_iter_init(const struct device_node *np,
+ const char *list_name,
+ const __be32 **end);
+extern const __be32 *of_phandle_iter_next(const char *cells_name,
+ int cell_count,
+  

Re: [RFC][PATCHv6+++ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-02 Thread Hiroshi Doyu
Stephen Warren swar...@wwwdotorg.org wrote @ Sun, 1 Dec 2013 20:00:09 +0100:

 On 11/29/2013 04:46 AM, Hiroshi Doyu wrote:
 ...
  Iterating over a property containing a list of phandles with arguments
  is a common operation for device drivers. This patch adds a new
  of_property_for_each_phandle_with_args() macro to make the iteration
  simpler.
  
  Introduced a new struct of_phandle_iter to keep the state when
  iterating over the list.
  
  Signed-off-by: Hiroshi Doyu hd...@nvidia.com
  ---
  v6+++:
 
 Surely that's v9; +++ is rather unusual.

My intention was to put this into the next v7 series after I get this
reviewed as RFC.
...
 Together with removing:
 
  +   const char  *cells_name;
  +   int cell_count;
 
 ... then you'd only be left with cur/end, so I think you could get away
 without a struct at all, but simply cur as the iterator variable, plus
 end as the one temp variable.

Although the above proposal would be alsmot same as [RFC][PATCHv6++
01/13](*1) where I use *list(cur) and rem as remaining count, here's
the update. I'll put this into v7 series.

---8--8--8--8--8--8--8--8--8---
From: Hiroshi Doyu hd...@nvidia.com

Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v6:
Iterate without intrducing a new struct.

v6+++:
Introduced a new struct of_phandle_iter to keep the state when
iterating over the list.

v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

I didn't introduce any struct to hold params and state here.

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/of/base.c  | 53 +
 include/linux/of.h | 34 ++
 2 files changed, 87 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..7501f24 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,59 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk(\n);
 }
 
+const __be32 *of_phandle_iter_next(const char *cells_name, int cell_count,
+  const __be32 *cur, const __be32 *end,
+  struct of_phandle_args *out_args)
+{
+   phandle phandle;
+   struct device_node *dn;
+   int i;
+
+   if (!cells_name  !cell_count)
+   return NULL;
+
+   if (!cur)
+   return NULL;
+
+   if (end - cur = 0)
+   return NULL;
+
+   phandle = be32_to_cpup(cur++);
+   if (!phandle)
+   return NULL;
+
+   dn = of_find_node_by_phandle(phandle);
+   if (!dn)
+   return NULL;
+
+   if (cells_name)
+   if (of_property_read_u32(dn, cells_name, cell_count))
+   return NULL;
+
+   out_args-np = dn;
+   out_args-args_count = cell_count;
+   for (i = 0; i  cell_count; i++)
+   out_args-args[i] = be32_to_cpup(cur++);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_next);
+
+const __be32 *of_phandle_iter_init(const struct device_node *np,
+  const char *list_name,
+  const __be32 **end)
+{
+   size_t bytes;
+   const __be32 *cur;
+
+   cur = of_get_property(np, list_name, bytes);
+   if (bytes)
+   *end = cur + bytes / sizeof(*cur);
+
+   return cur;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_init);
+
 static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..c23710b 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -303,6 +303,14 @@ extern int of_parse_phandle_with_fixed_args(const struct 
device_node *np,
 extern int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name);
 
+extern const __be32 *of_phandle_iter_init(const struct device_node *np,
+ const char *list_name,
+ const __be32 **end);
+extern const __be32 *of_phandle_iter_next(const char *cells_name,
+ int cell_count,
+ const __be32 *cur, const __be32 *end,
+ struct of_phandle_args *out_args);
+
 extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64

Re: [RFC][PATCHv6+++ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-12-02 Thread Hiroshi Doyu
On Mon, 2 Dec 2013 15:39:25 +0100
Rob Herring robherri...@gmail.com wrote:

 On Mon, Dec 2, 2013 at 5:02 AM, Hiroshi Doyu hd...@nvidia.com wrote:
  Stephen Warren swar...@wwwdotorg.org wrote @ Sun, 1 Dec 2013 20:00:09 
  +0100:
 
  On 11/29/2013 04:46 AM, Hiroshi Doyu wrote:
  ...
   Iterating over a property containing a list of phandles with arguments
   is a common operation for device drivers. This patch adds a new
   of_property_for_each_phandle_with_args() macro to make the iteration
   simpler.
  
   Introduced a new struct of_phandle_iter to keep the state when
   iterating over the list.
  
   Signed-off-by: Hiroshi Doyu hd...@nvidia.com


Rob, thank you for review.
I'll fix them and put this one into the next v7 series.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC][PATCHv6+++ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-11-29 Thread Hiroshi Doyu
Hiroshi Doyu  wrote @ Thu, 28 Nov 2013 14:58:18 +0200 (EET):

> > In other words, an implementation more along the lines of
> > include/linux/of.h's:
> > 
> > #define of_property_for_each_u32(np, propname, prop, p, u)  \
> > for (prop = of_find_property(np, propname, NULL),   \
> > p = of_prop_next_u32(prop, NULL, );   \
> > p;  \
> > p = of_prop_next_u32(prop, p, ))
> > 
> > ... so you'd need functions like of_prop_first_specifier() and
> > of_prop_next_specifier(), and perhaps some associated set of state
> > variables, perhaps with all the state wrapped into a single struct for
> > simplicity.
> 
> Although I couldn't invent any struct to hold params and state here,
> I'd like you to review the following interface is ok or not.

Tried again to introduce a new struct to keep track of iteration state
as below:

8<-8<-8<-8<-8<-8<--
From: Hiroshi Doyu 

Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Introduced a new struct "of_phandle_iter" to keep the state when
iterating over the list.

Signed-off-by: Hiroshi Doyu 
---
v6+++:
Introduced a new struct "of_phandle_iter" to keep the state when
iterating over the list.

v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

I didn't introduce any struct to hold params and state here.

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu 
---
 drivers/of/base.c  | 71 ++
 include/linux/of.h | 45 ++
 2 files changed, 116 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..16fb2d9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,77 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk("\n");
 }
 
+void of_phandle_iter_next(struct of_phandle_iter *iter,
+ struct of_phandle_args *out_args)
+{
+   phandle phandle;
+   struct device_node *dn;
+   int i, count = iter->cell_count;
+
+   iter->err = -EINVAL;
+   if (!iter->cells_name && !iter->cell_count)
+   return;
+
+   phandle = be32_to_cpup(iter->cur++);
+   if (!phandle)
+   return;
+
+   dn = of_find_node_by_phandle(phandle);
+   if (!dn)
+   return;
+
+   if (iter->cells_name)
+   if (of_property_read_u32(dn, iter->cells_name, ))
+   return;
+
+   out_args->np = dn;
+   out_args->args_count = count;
+   for (i = 0; i < count; i++)
+   out_args->args[i] = be32_to_cpup(iter->cur++);
+
+   iter->err = 0;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_next);
+
+static void __of_phandle_iter_set(struct of_phandle_iter *iter,
+ const struct device_node *np,
+ const char *list_name)
+{
+   size_t bytes;
+   const __be32 *prop;
+
+   prop = of_get_property(np, list_name, );
+   if (!prop) {
+   iter->err = -EINVAL;
+   return;
+   }
+
+   iter->cur = prop;
+   iter->end = prop + bytes / sizeof(*prop);
+   iter->err = 0;
+}
+
+void of_phandle_iter_start(struct of_phandle_iter *iter,
+  const struct device_node *np,
+  const char *list_name,
+  const char *cells_name,
+  int cell_count,
+  struct of_phandle_args *out_args)
+{
+   iter->err = -EINVAL;
+   if (!cells_name && !cell_count)
+   return;
+
+   iter->cells_name = cells_name;
+   iter->cell_count = cell_count;
+   __of_phandle_iter_set(iter, np, list_name);
+   if (iter->err)
+   return;
+
+   of_phandle_iter_next(iter, out_args);
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_start);
+
 static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..1132b49 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -74,6 +74,18 @@ struct of_phandle_args {
uint32_t args[MAX_PHANDLE_ARGS];
 };
 
+/*
+ * k

[RFC][PATCHv6+++ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-11-29 Thread Hiroshi Doyu
Hiroshi Doyu hd...@nvidia.com wrote @ Thu, 28 Nov 2013 14:58:18 +0200 (EET):

  In other words, an implementation more along the lines of
  include/linux/of.h's:
  
  #define of_property_for_each_u32(np, propname, prop, p, u)  \
  for (prop = of_find_property(np, propname, NULL),   \
  p = of_prop_next_u32(prop, NULL, u);   \
  p;  \
  p = of_prop_next_u32(prop, p, u))
  
  ... so you'd need functions like of_prop_first_specifier() and
  of_prop_next_specifier(), and perhaps some associated set of state
  variables, perhaps with all the state wrapped into a single struct for
  simplicity.
 
 Although I couldn't invent any struct to hold params and state here,
 I'd like you to review the following interface is ok or not.

Tried again to introduce a new struct to keep track of iteration state
as below:

8-8-8-8-8-8--
From: Hiroshi Doyu hd...@nvidia.com

Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Introduced a new struct of_phandle_iter to keep the state when
iterating over the list.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v6+++:
Introduced a new struct of_phandle_iter to keep the state when
iterating over the list.

v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

I didn't introduce any struct to hold params and state here.

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/of/base.c  | 71 ++
 include/linux/of.h | 45 ++
 2 files changed, 116 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..16fb2d9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,77 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk(\n);
 }
 
+void of_phandle_iter_next(struct of_phandle_iter *iter,
+ struct of_phandle_args *out_args)
+{
+   phandle phandle;
+   struct device_node *dn;
+   int i, count = iter-cell_count;
+
+   iter-err = -EINVAL;
+   if (!iter-cells_name  !iter-cell_count)
+   return;
+
+   phandle = be32_to_cpup(iter-cur++);
+   if (!phandle)
+   return;
+
+   dn = of_find_node_by_phandle(phandle);
+   if (!dn)
+   return;
+
+   if (iter-cells_name)
+   if (of_property_read_u32(dn, iter-cells_name, count))
+   return;
+
+   out_args-np = dn;
+   out_args-args_count = count;
+   for (i = 0; i  count; i++)
+   out_args-args[i] = be32_to_cpup(iter-cur++);
+
+   iter-err = 0;
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_next);
+
+static void __of_phandle_iter_set(struct of_phandle_iter *iter,
+ const struct device_node *np,
+ const char *list_name)
+{
+   size_t bytes;
+   const __be32 *prop;
+
+   prop = of_get_property(np, list_name, bytes);
+   if (!prop) {
+   iter-err = -EINVAL;
+   return;
+   }
+
+   iter-cur = prop;
+   iter-end = prop + bytes / sizeof(*prop);
+   iter-err = 0;
+}
+
+void of_phandle_iter_start(struct of_phandle_iter *iter,
+  const struct device_node *np,
+  const char *list_name,
+  const char *cells_name,
+  int cell_count,
+  struct of_phandle_args *out_args)
+{
+   iter-err = -EINVAL;
+   if (!cells_name  !cell_count)
+   return;
+
+   iter-cells_name = cells_name;
+   iter-cell_count = cell_count;
+   __of_phandle_iter_set(iter, np, list_name);
+   if (iter-err)
+   return;
+
+   of_phandle_iter_next(iter, out_args);
+}
+EXPORT_SYMBOL_GPL(of_phandle_iter_start);
+
 static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..1132b49 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -74,6 +74,18 @@ struct of_phandle_args {
uint32_t args[MAX_PHANDLE_ARGS];
 };
 
+/*
+ * keep the state at iterating a list of phandles with variable number
+ * of args
+ */
+struct of_phandle_iter {
+   int err;
+   const __be32*cur;   /* current phandle

[RFC][PATCHv6++ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-11-28 Thread Hiroshi Doyu
Stephen Warren  wrote @ Thu, 21 Nov 2013 19:57:00 +0100:

> On 11/21/2013 10:17 AM, Hiroshi Doyu wrote:
> > Iterating over a property containing a list of phandles with arguments
> > is a common operation for device drivers. This patch adds a new
> > of_property_for_each_phandle_with_args() macro to make the iteration
> > simpler.
> > 
> > Signed-off-by: Hiroshi Doyu 
> > ---
> > v6+:
> > Use the description, which Grant Likely proposed, to be full enough
> > that a future reader can figure out why a patch was written.
> >   http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007062.html
> 
> This new version only addresses one of the concerns that Grant had,
> namely the commit message.
> 
> > diff --git a/include/linux/of.h b/include/linux/of.h
> 
> > +#define of_property_for_each_phandle_with_args(np, list, cells, i, args) \
> > +   for (i = 0; !of_parse_phandle_with_args(np, list, cells, i, args); i++)
> > +
> 
> Grant also wanted the actual implementation fixed so that it wasn't so
> inefficient.
> 
> What this current patch does is basically:
> 
> for every entry in the property:
> for every entry in the property before the current index:
> parse the phandle+specifier
> 
> That's roughly O(n^2). (n is # entries in the property)
> 
> Instead, what should happen is:
> 
> for every entry in the property:
> parse the phandle+specifier
> yield the result
> 
> That's roughly O(n).
> 
> In other words, an implementation more along the lines of
> include/linux/of.h's:
> 
> #define of_property_for_each_u32(np, propname, prop, p, u)  \
> for (prop = of_find_property(np, propname, NULL),   \
> p = of_prop_next_u32(prop, NULL, );   \
> p;  \
> p = of_prop_next_u32(prop, p, ))
> 
> ... so you'd need functions like of_prop_first_specifier() and
> of_prop_next_specifier(), and perhaps some associated set of state
> variables, perhaps with all the state wrapped into a single struct for
> simplicity.

Although I couldn't invent any struct to hold params and state here,
I'd like you to review the following interface is ok or not.

At first, I thought to refactor __of_parse_phandle_with_args() but
it's a bit highly optimized by Stephen and it looked a bit hard to
refactor without perf regressions. Instread, I introduced 2 new
functions "of_parse_{first,next}_phandle_with_args()" to parse
phandles.

If this interface is ok, I'll include this into the next v7 series.

-8<-8<-8<-8<-8<-8<-8<-8<-8<-
From: Hiroshi Doyu 

Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Introduced "of_parse_{first,next}_phandle_with_args()", where "const
__be32 **list" is used to hold the next list to be processed as a
state pramameter, and both "of_parse_{first,next}_phandle_with_args()"
returns the remaining list in the number of cell(4 byte). If any error
happens, "list" is set NULL not to proceed the rest.

Signed-off-by: Hiroshi Doyu 
---
v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu 
---
 drivers/of/base.c  | 82 ++
 include/linux/of.h | 52 ++
 2 files changed, 134 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..3e29b10 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,88 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk("\n");
 }
 
+int __of_parse_next_phandle_with_args(const __be32 **plist,
+ const char *cells_name, int cell_count,
+ struct of_phandle_args *out_args)
+{
+   phandle phandle;
+   int i, count = 0, err;
+   struct device_node *dn;
+   const __be32 *list;
+
+   BUG_ON(!out_args);
+   BUG_ON(!cells_name && !cell_count);
+
+   /*
+* "*plist" should hold phandle, and it's updated to the next
+* phandle at return if no error.
+*/
+   list = *plist;
+   out_args->np = NULL;
+
+   phandle = be32_to_cpup(list);
+   if (!phandle)
+   goto err_out;
+
+   dn = of_f

[RFC][PATCHv6++ 01/13] of: introduce of_property_for_earch_phandle_with_args()

2013-11-28 Thread Hiroshi Doyu
Stephen Warren swar...@wwwdotorg.org wrote @ Thu, 21 Nov 2013 19:57:00 +0100:

 On 11/21/2013 10:17 AM, Hiroshi Doyu wrote:
  Iterating over a property containing a list of phandles with arguments
  is a common operation for device drivers. This patch adds a new
  of_property_for_each_phandle_with_args() macro to make the iteration
  simpler.
  
  Signed-off-by: Hiroshi Doyu hd...@nvidia.com
  ---
  v6+:
  Use the description, which Grant Likely proposed, to be full enough
  that a future reader can figure out why a patch was written.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007062.html
 
 This new version only addresses one of the concerns that Grant had,
 namely the commit message.
 
  diff --git a/include/linux/of.h b/include/linux/of.h
 
  +#define of_property_for_each_phandle_with_args(np, list, cells, i, args) \
  +   for (i = 0; !of_parse_phandle_with_args(np, list, cells, i, args); i++)
  +
 
 Grant also wanted the actual implementation fixed so that it wasn't so
 inefficient.
 
 What this current patch does is basically:
 
 for every entry in the property:
 for every entry in the property before the current index:
 parse the phandle+specifier
 
 That's roughly O(n^2). (n is # entries in the property)
 
 Instead, what should happen is:
 
 for every entry in the property:
 parse the phandle+specifier
 yield the result
 
 That's roughly O(n).
 
 In other words, an implementation more along the lines of
 include/linux/of.h's:
 
 #define of_property_for_each_u32(np, propname, prop, p, u)  \
 for (prop = of_find_property(np, propname, NULL),   \
 p = of_prop_next_u32(prop, NULL, u);   \
 p;  \
 p = of_prop_next_u32(prop, p, u))
 
 ... so you'd need functions like of_prop_first_specifier() and
 of_prop_next_specifier(), and perhaps some associated set of state
 variables, perhaps with all the state wrapped into a single struct for
 simplicity.

Although I couldn't invent any struct to hold params and state here,
I'd like you to review the following interface is ok or not.

At first, I thought to refactor __of_parse_phandle_with_args() but
it's a bit highly optimized by Stephen and it looked a bit hard to
refactor without perf regressions. Instread, I introduced 2 new
functions of_parse_{first,next}_phandle_with_args() to parse
phandles.

If this interface is ok, I'll include this into the next v7 series.

-8-8-8-8-8-8-8-8-8-
From: Hiroshi Doyu hd...@nvidia.com

Iterating over a property containing a list of phandles with arguments
is a common operation for device drivers. This patch adds a new
of_property_for_each_phandle_with_args() macro to make the iteration
simpler.

Introduced of_parse_{first,next}_phandle_with_args(), where const
__be32 **list is used to hold the next list to be processed as a
state pramameter, and both of_parse_{first,next}_phandle_with_args()
returns the remaining list in the number of cell(4 byte). If any error
happens, list is set NULL not to proceed the rest.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v6++:
Optimized to avoid O(n^2), suggested by Stephen Warren.
http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007066.html

v6+:
Use the description, which Grant Likely proposed, to be full enough
that a future reader can figure out why a patch was written.

v5:
New patch for v5.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/of/base.c  | 82 ++
 include/linux/of.h | 52 ++
 2 files changed, 134 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0e..3e29b10 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1201,6 +1201,88 @@ void of_print_phandle_args(const char *msg, const struct 
of_phandle_args *args)
printk(\n);
 }
 
+int __of_parse_next_phandle_with_args(const __be32 **plist,
+ const char *cells_name, int cell_count,
+ struct of_phandle_args *out_args)
+{
+   phandle phandle;
+   int i, count = 0, err;
+   struct device_node *dn;
+   const __be32 *list;
+
+   BUG_ON(!out_args);
+   BUG_ON(!cells_name  !cell_count);
+
+   /*
+* *plist should hold phandle, and it's updated to the next
+* phandle at return if no error.
+*/
+   list = *plist;
+   out_args-np = NULL;
+
+   phandle = be32_to_cpup(list);
+   if (!phandle)
+   goto err_out;
+
+   dn = of_find_node_by_phandle(phandle);
+   if (!dn)
+   goto err_out;
+
+   if (cells_name) {
+   err = of_property_read_u32(dn, cells_name, count);
+   if (err)
+   goto err_out;
+   } else {
+   count = cell_count;
+   }
+
+   out_args-np = dn

Re: [PATCHv6 05/13] iommu/core: add ops->{bound,unbind}_driver()

2013-11-25 Thread Hiroshi Doyu
Hi Joerg,

Do you have some time to review this patch along with the following ones?

  [PATCHv6 02/13] iommu/of: introduce a global iommu device list
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007050.html

  [PATCHv6 03/13] iommu/of: check if dependee iommu is ready or not
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007051.html

With those patches, now I'm trying to populate iommu master devices
after an IOMMU device is populated. Originally [PATCHv6 02/13] was
proposed by Thierry. I'm a bit afraid of adding new IOMMU API as
this, but I think that this new {bound,unbind}_driver() is the right
timiing that depeding devices are populated instead of add_device()
since, even after add_device, a device won't be populated. I'm not so
sure how this affects on the existing IOMMUs.

It would be nice if you give some feedback on this.

On Thu, 21 Nov 2013 14:40:41 +0100
Hiroshi Doyu  wrote:

> ops->{bound,unbind}_driver() functions are called at
> BUS_NOTIFY_{BOUND,UNBIND}_DRIVER respectively.
> 
> This is necessary to control the device population order. IOMMU master
> devices depend on an IOMMU device instanciation. IOMMU master devices
> can be registered to an IOMMU only after it's successfully
> populated. This IOMMU registration is done via
> ops->bound_driver(). Currently this population can be deferred if
> depending IOMMU device hasn't yet been populated in driver core. This
> cannot be done via ops->add_device() since after add_device() device's
> population/instanciation can be still deferred via probe().
> 
> Signed-off-by: Hiroshi Doyu 
> ---
> v6:
> New for v6.
> ---
>  drivers/iommu/iommu.c | 13 +++--
>  include/linux/iommu.h |  4 
>  2 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index efc..5469d36 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -540,14 +540,23 @@ static int iommu_bus_notifier(struct notifier_block *nb,
>* ADD/DEL call into iommu driver ops if provided, which may
>* result in ADD/DEL notifiers to group->notifier
>*/
> - if (action == BUS_NOTIFY_ADD_DEVICE) {
> + switch (action) {
> + case BUS_NOTIFY_ADD_DEVICE:
>   if (ops->add_device)
>   return ops->add_device(dev);
> - } else if (action == BUS_NOTIFY_DEL_DEVICE) {
> + case BUS_NOTIFY_DEL_DEVICE:
>   if (ops->remove_device && dev->iommu_group) {
>   ops->remove_device(dev);
>   return 0;
>   }
> + case BUS_NOTIFY_BOUND_DRIVER:
> + if (ops->bound_driver)
> + ops->bound_driver(dev);
> + break;
> + case BUS_NOTIFY_UNBIND_DRIVER:
> + if (ops->unbind_driver)
> + ops->unbind_driver(dev);
> + break;
>   }
>  
>   /*
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index a444c79..a0e92be 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -96,6 +96,8 @@ enum iommu_attr {
>   * @domain_has_cap: domain capabilities query
>   * @add_device: add device to iommu grouping
>   * @remove_device: remove device from iommu grouping
> + * @bound_driver: called at BUS_NOTIFY_BOUND_DRIVER
> + * @unbind_driver: called at BUS_NOTIFY_UNBIND_DRIVER
>   * @domain_get_attr: Query domain attributes
>   * @domain_set_attr: Change domain attributes
>   * @pgsize_bitmap: bitmap of supported page sizes
> @@ -114,6 +116,8 @@ struct iommu_ops {
> unsigned long cap);
>   int (*add_device)(struct device *dev);
>   void (*remove_device)(struct device *dev);
> + int (*bound_driver)(struct device *dev);
> + void (*unbind_driver)(struct device *dev);
>   int (*device_group)(struct device *dev, unsigned int *groupid);
>   int (*domain_get_attr)(struct iommu_domain *domain,
>  enum iommu_attr attr, void *data);
> -- 
> 1.8.1.5
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv6 05/13] iommu/core: add ops-{bound,unbind}_driver()

2013-11-25 Thread Hiroshi Doyu
Hi Joerg,

Do you have some time to review this patch along with the following ones?

  [PATCHv6 02/13] iommu/of: introduce a global iommu device list
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007050.html

  [PATCHv6 03/13] iommu/of: check if dependee iommu is ready or not
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/007051.html

With those patches, now I'm trying to populate iommu master devices
after an IOMMU device is populated. Originally [PATCHv6 02/13] was
proposed by Thierry. I'm a bit afraid of adding new IOMMU API as
this, but I think that this new {bound,unbind}_driver() is the right
timiing that depeding devices are populated instead of add_device()
since, even after add_device, a device won't be populated. I'm not so
sure how this affects on the existing IOMMUs.

It would be nice if you give some feedback on this.

On Thu, 21 Nov 2013 14:40:41 +0100
Hiroshi Doyu hd...@nvidia.com wrote:

 ops-{bound,unbind}_driver() functions are called at
 BUS_NOTIFY_{BOUND,UNBIND}_DRIVER respectively.
 
 This is necessary to control the device population order. IOMMU master
 devices depend on an IOMMU device instanciation. IOMMU master devices
 can be registered to an IOMMU only after it's successfully
 populated. This IOMMU registration is done via
 ops-bound_driver(). Currently this population can be deferred if
 depending IOMMU device hasn't yet been populated in driver core. This
 cannot be done via ops-add_device() since after add_device() device's
 population/instanciation can be still deferred via probe().
 
 Signed-off-by: Hiroshi Doyu hd...@nvidia.com
 ---
 v6:
 New for v6.
 ---
  drivers/iommu/iommu.c | 13 +++--
  include/linux/iommu.h |  4 
  2 files changed, 15 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
 index efc..5469d36 100644
 --- a/drivers/iommu/iommu.c
 +++ b/drivers/iommu/iommu.c
 @@ -540,14 +540,23 @@ static int iommu_bus_notifier(struct notifier_block *nb,
* ADD/DEL call into iommu driver ops if provided, which may
* result in ADD/DEL notifiers to group-notifier
*/
 - if (action == BUS_NOTIFY_ADD_DEVICE) {
 + switch (action) {
 + case BUS_NOTIFY_ADD_DEVICE:
   if (ops-add_device)
   return ops-add_device(dev);
 - } else if (action == BUS_NOTIFY_DEL_DEVICE) {
 + case BUS_NOTIFY_DEL_DEVICE:
   if (ops-remove_device  dev-iommu_group) {
   ops-remove_device(dev);
   return 0;
   }
 + case BUS_NOTIFY_BOUND_DRIVER:
 + if (ops-bound_driver)
 + ops-bound_driver(dev);
 + break;
 + case BUS_NOTIFY_UNBIND_DRIVER:
 + if (ops-unbind_driver)
 + ops-unbind_driver(dev);
 + break;
   }
  
   /*
 diff --git a/include/linux/iommu.h b/include/linux/iommu.h
 index a444c79..a0e92be 100644
 --- a/include/linux/iommu.h
 +++ b/include/linux/iommu.h
 @@ -96,6 +96,8 @@ enum iommu_attr {
   * @domain_has_cap: domain capabilities query
   * @add_device: add device to iommu grouping
   * @remove_device: remove device from iommu grouping
 + * @bound_driver: called at BUS_NOTIFY_BOUND_DRIVER
 + * @unbind_driver: called at BUS_NOTIFY_UNBIND_DRIVER
   * @domain_get_attr: Query domain attributes
   * @domain_set_attr: Change domain attributes
   * @pgsize_bitmap: bitmap of supported page sizes
 @@ -114,6 +116,8 @@ struct iommu_ops {
 unsigned long cap);
   int (*add_device)(struct device *dev);
   void (*remove_device)(struct device *dev);
 + int (*bound_driver)(struct device *dev);
 + void (*unbind_driver)(struct device *dev);
   int (*device_group)(struct device *dev, unsigned int *groupid);
   int (*domain_get_attr)(struct iommu_domain *domain,
  enum iommu_attr attr, void *data);
 -- 
 1.8.1.5
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

2013-11-20 Thread Hiroshi Doyu
Thierry Reding  wrote @ Wed, 20 Nov 2013 14:14:48 
+0100:

> > Does the above mean the following?
> > 
> > int of_iommu_attach(struct device *dev)
> > {
> > int i;
> > struct of_phandle_args args;
> > 
> > of_property_for_each_phandle_with_args(dev->of_node, "iommus",
> >"#iommu-cells", i, )
> > if (!args->np->dev->driver)
> > return -EPROBE_DEFER;
> > return 0;
> > }
> 
> Not quite. The above would only check that a driver was bound to the
> device. But if that device isn't an IOMMU then this doesn't help you.

I thought that, as long as a device is a normal one, it's ok to let it
go to be populated. We only care about that, IOMMU devices comes
first, and clients should come later than IOMMUs, for population. In
the above if all IOMMUs are not populated, client devices are always
deferred. "args->np->dev" always points an IOMMU device in a
loop. Otherwise(no "iommus=") it goes out from the loop immediately.

+#define of_property_for_each_phandle_with_args(np, list, cells, i, args) \
+for (i = 0; !of_parse_phandle_with_args(np, list, cells, i, args); i++)

> The standard way to solve this issue is to add the IOMMU to a global
> list upon registration. Typically subsystems have some way to do that
> already,

Your implementation has some possibiity that we could construct any
hierarchy of IOMMUs.

> already, but it seems like IOMMU doesn't. It looks like that's one of
> the side-effects of the assumption that there will always only be a
> single IOMMU (per bus).

There's the following case at least we have already had.

"memory controller"---"smmu_a"---bus--+--"smmu_b"--"device_a"
  |
  |
  +--"device_b"

"smmu_b" isn't related to a bus at all.

> There's also no base object that IOMMU drivers implement, which is the
> way it's usually done in other subsystems. The absence of that makes it
> more difficult. I suspect the easiest way to do that would be to add a
> new type, something like this:


> With that you can use of_find_iommu_by_node() in the loop to check
> whether an IOMMU has really been registered.

Do you think if it's acceptable to see if a device is populated or not
via "dev->driver"[1]? Grant Likely proposed to use flag[2] instead of
struct device[2], though.

[1] http://lists.linuxfoundation.org/pipermail/iommu/2013-July/006023.html
[2] http://lists.linuxfoundation.org/pipermail/iommu/2013-October/006763.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

2013-11-20 Thread Hiroshi Doyu
Thierry Reding thierry.red...@gmail.com wrote @ Wed, 20 Nov 2013 14:14:48 
+0100:

  Does the above mean the following?
  
  int of_iommu_attach(struct device *dev)
  {
  int i;
  struct of_phandle_args args;
  
  of_property_for_each_phandle_with_args(dev-of_node, iommus,
 #iommu-cells, i, args)
  if (!args-np-dev-driver)
  return -EPROBE_DEFER;
  return 0;
  }
 
 Not quite. The above would only check that a driver was bound to the
 device. But if that device isn't an IOMMU then this doesn't help you.

I thought that, as long as a device is a normal one, it's ok to let it
go to be populated. We only care about that, IOMMU devices comes
first, and clients should come later than IOMMUs, for population. In
the above if all IOMMUs are not populated, client devices are always
deferred. args-np-dev always points an IOMMU device in a
loop. Otherwise(no iommus=) it goes out from the loop immediately.

+#define of_property_for_each_phandle_with_args(np, list, cells, i, args) \
+for (i = 0; !of_parse_phandle_with_args(np, list, cells, i, args); i++)

 The standard way to solve this issue is to add the IOMMU to a global
 list upon registration. Typically subsystems have some way to do that
 already,

Your implementation has some possibiity that we could construct any
hierarchy of IOMMUs.

 already, but it seems like IOMMU doesn't. It looks like that's one of
 the side-effects of the assumption that there will always only be a
 single IOMMU (per bus).

There's the following case at least we have already had.

memory controller---smmu_a---bus--+--smmu_b--device_a
  |
  |
  +--device_b

smmu_b isn't related to a bus at all.

 There's also no base object that IOMMU drivers implement, which is the
 way it's usually done in other subsystems. The absence of that makes it
 more difficult. I suspect the easiest way to do that would be to add a
 new type, something like this:


 With that you can use of_find_iommu_by_node() in the loop to check
 whether an IOMMU has really been registered.

Do you think if it's acceptable to see if a device is populated or not
via dev-driver[1]? Grant Likely proposed to use flag[2] instead of
struct device[2], though.

[1] http://lists.linuxfoundation.org/pipermail/iommu/2013-July/006023.html
[2] http://lists.linuxfoundation.org/pipermail/iommu/2013-October/006763.html
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] fs: partitions: efi: Fix bound check

2013-11-19 Thread Hiroshi Doyu
Antti Miettinen  wrote @ Wed, 20 Nov 2013 08:18:50 +0100:

> On 20.11.2013 02:04, Andrew Morton wrote:
> > On Fri, 15 Nov 2013 19:14:22 +0200 (EET) Antti P Miettinen
> >  wrote:
> >
> >  > Use ARRAY_SIZE instead of sizeof to get proper max for label
> >  > length.
> >  >
> >  > Signed-off-by: Antti P Miettinen 
> >  > Reviewed-by: Hiroshi Doyu 
> >  > Tested-by: Hiroshi Doyu 
> >
> > When fixing a bug, please provide a description of the user-visible
> > impact of that bug.  This is so that others can decide which kernel
> > version(s) need the patch.
> >
> > Hiroshi Doyu tested this patch, so I assume there was some observable
> > misbehaviour to test.  Please fully describe that.
> 
> Since this is just a read out of bounds it's not that bad, but the 
> problem becomes user-visible e.g. if one tries to use 
> CONFIG_DEBUG_PAGEALLOC and CONFIG_DEBUG_RODATA, at least with some 
> enhancements from Hiroshi.

The above enhancement is almost ARCH_SUPPORTS_DEBUG_PAGEALLOC for ARM,
which could catch illegal memory access(read/write) with a page fault
although that enhancement itself needs some cleanups before being
upstreamed.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

2013-11-19 Thread Hiroshi Doyu
Stephen Warren  wrote @ Tue, 19 Nov 2013 22:22:47 +0100:

> On 11/19/2013 05:03 AM, Hiroshi Doyu wrote:
> > Hi Thierry,
> > 
> > Thierry Reding  wrote @ Tue, 19 Nov 2013 11:25:07 
> > +0100:
> > 
> >> From earlier discussions I thought the goal was to actually defer this
> >> until all nodes referred to by the iommus property were actually
> >> registered. The above only checks that the phandles can be resolved to
> >> valid struct device_node:s. That doesn't mean that an actual IOMMU has
> >> been registered for it, only that the devices have been created.
> > 
> > Currently "bus->iommu_ops" is set at the end of tegra_smmu_probe(). So
> > if "bus->iommu_ops" is set, it means that an iommu instance is
> > populated at that time.
> 
> Yes, but that's the register bus, upon which the device is a client, not
> the bus upon which the device is a bus master. They aren't necessarily
> the same.
> 
> There's no getting around the fact that, as Thierry said, you need to
> search for a registered IOMMU device for each phandle, and defer probe
> if any aren't registered yet.
> 
> If we do that, then you shouldn't need to look at the value of
> dev->bus->iommu_ops at all; if all IOMMUs in the list were registered,
> then iommu_ops must have been set when (one of them) was registered, and
> if not, then it possibly wasn't, so defer probe.
> 
> That way, this code won't have to change if the core IOMMU code gets
> extended to support multiple IOMMUs, devices mastering transactions onto
> buses other than their register bus, etc.

Does the above mean the following?

int of_iommu_attach(struct device *dev)
{
int i;
struct of_phandle_args args;

of_property_for_each_phandle_with_args(dev->of_node, "iommus",
   "#iommu-cells", i, )
if (!args->np->dev->driver)
return -EPROBE_DEFER;
return 0;
}


"args->np->dev->driver" needs the following patch:

  http://lists.linuxfoundation.org/pipermail/iommu/2013-July/006023.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv5 7/9] iommu/tegra: smmu: allow duplicate ASID wirte

2013-11-19 Thread Hiroshi Doyu
The device, which belongs to the same ASID, can try to enable the same
ASID as the other swgroup devices. This should be allowed but just
skip the actual register write. If the write value is different, it
will return -EINVAL.

Signed-off-by: Hiroshi Doyu 
---
v4:
This was the part of v3, which isn't used any more.
  [PATCHv3 10/19] iommu/tegra: smmu: Get "nvidia,swgroups" from DT
---
 drivers/iommu/tegra-smmu.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index e915201a..c2ed075 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -418,9 +418,13 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
offs = HWGRP_ASID_REG(i);
val = smmu_read(smmu, offs);
if (on) {
-   if (WARN_ON(val & mask))
-   goto err_hw_busy;
-   val |= mask;
+   if (val) {
+   if (WARN_ON(val != mask))
+   return -EINVAL;
+   goto skip;
+   }
+
+   val = mask;
memcpy(c->hwgrp, map, sizeof(u64));
} else {
WARN_ON((val & mask) == mask);
@@ -430,16 +434,8 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
}
 
FLUSH_SMMU_REGS(smmu);
+skip:
return 0;
-
-err_hw_busy:
-   for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
-   offs = HWGRP_ASID_REG(i);
-   val = smmu_read(smmu, offs);
-   val &= ~mask;
-   smmu_write(smmu, val, offs);
-   }
-   return -EBUSY;
 }
 
 static int smmu_client_set_hwgrp(struct smmu_client *c,
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv5 8/9] iommu/tegra: smmu: Rename hwgrp -> swgroups

2013-11-19 Thread Hiroshi Doyu
Use the correct term for SWGROUP related variables and macros.

The term "swgroup" is the collection of "memory client". A "memory
client" usually represents a HardWare Accelerator(HWA) like
GPU. Sometimes a strut device can belong to multiple "swgroup" so that
"swgroup's'" is used here. This "swgroups" is the term used in Tegra
TRM. Rename along with TRM.

Signed-off-by: Hiroshi Doyu 
---
v4:
New for v4
---
 drivers/iommu/tegra-smmu.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index c2ed075..003a491 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -179,12 +179,12 @@ enum {
 
 #define NUM_SMMU_REG_BANKS 3
 
-#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1)
-#define smmu_client_disable_hwgrp(c)   smmu_client_set_hwgrp(c, 0, 0)
-#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
-#define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0)
+#define smmu_client_enable_swgroups(c, m) smmu_client_set_swgroups(c, m, 1)
+#define smmu_client_disable_swgroups(c) smmu_client_set_swgroups(c, 0, 0)
+#define __smmu_client_enable_swgroups(c, m) __smmu_client_set_swgroups(c, m, 1)
+#define __smmu_client_disable_swgroups(c) __smmu_client_set_swgroups(c, 0, 0)
 
-#define HWGRP_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
+#define SWGROUPS_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
 
 /*
  * Per client for address space
@@ -195,7 +195,7 @@ struct smmu_client {
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
-   unsigned long   hwgrp[2];
+   unsigned long   swgroups[2];
 };
 
 /*
@@ -377,7 +377,7 @@ static int register_smmu_client(struct smmu_device *smmu,
 
client->dev = dev;
client->of_node = dev->of_node;
-   memcpy(client->hwgrp, swgroups, sizeof(u64));
+   memcpy(client->swgroups, swgroups, sizeof(u64));
return insert_smmu_client(smmu, client);
 }
 
@@ -403,7 +403,7 @@ static int smmu_of_get_swgroups(struct device *dev, 
unsigned long *swgroups)
return -ENODEV;
 }
 
-static int __smmu_client_set_hwgrp(struct smmu_client *c,
+static int __smmu_client_set_swgroups(struct smmu_client *c,
   unsigned long *map, int on)
 {
int i;
@@ -412,10 +412,10 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
struct smmu_device *smmu = as->smmu;
 
if (!on)
-   map = c->hwgrp;
+   map = c->swgroups;
 
for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
-   offs = HWGRP_ASID_REG(i);
+   offs = SWGROUPS_ASID_REG(i);
val = smmu_read(smmu, offs);
if (on) {
if (val) {
@@ -425,7 +425,7 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
}
 
val = mask;
-   memcpy(c->hwgrp, map, sizeof(u64));
+   memcpy(c->swgroups, map, sizeof(u64));
} else {
WARN_ON((val & mask) == mask);
val &= ~mask;
@@ -438,7 +438,7 @@ skip:
return 0;
 }
 
-static int smmu_client_set_hwgrp(struct smmu_client *c,
+static int smmu_client_set_swgroups(struct smmu_client *c,
 unsigned long *map, int on)
 {
int err;
@@ -447,7 +447,7 @@ static int smmu_client_set_hwgrp(struct smmu_client *c,
struct smmu_device *smmu = as->smmu;
 
spin_lock_irqsave(>lock, flags);
-   err = __smmu_client_set_hwgrp(c, map, on);
+   err = __smmu_client_set_swgroups(c, map, on);
spin_unlock_irqrestore(>lock, flags);
return err;
 }
@@ -487,7 +487,7 @@ static int smmu_setup_regs(struct smmu_device *smmu)
smmu_write(smmu, val, SMMU_PTB_DATA);
 
list_for_each_entry(c, >client, list)
-   __smmu_client_set_hwgrp(c, c->hwgrp, 1);
+   __smmu_client_set_swgroups(c, c->swgroups, 1);
}
 
smmu_write(smmu, smmu->translation_enable_0, SMMU_TRANSLATION_ENABLE_0);
@@ -815,7 +815,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain 
*domain,
return -ENOMEM;
 
client->as = as;
-   err = smmu_client_enable_hwgrp(client, client->hwgrp);
+   err = smmu_client_enable_swgroups(client, client->swgroups);
if (err)
return -EINVAL;
 
@@ -835,7 +835,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain 
*domain,
 * Reserve "page zero" for AVP vectors using a common dummy
 * page.
 */
-   if (test_bit(TEGRA_SWGROUP_AVPC, client->hwgrp)) {
+   if (test_

[PATCHv5 3/9] ARM: tegra: create a DT header defining SWGROUP ID

2013-11-19 Thread Hiroshi Doyu
Create a header file to define the swgroup IDs used by the IOMMU(SMMU)
binding. "swgroup" is a group of H/W clients which a Tegra SoC
supports. This unique ID can be used to calculate MC_SMMU__ASID_0 register offset and MC__HOTRESET_*_0
register bit. This will allow the same header to be used by both
device tree files, and drivers implementing this binding, which
guarantees that the two stay in sync. This also makes device trees
more readable by using names instead of magic numbers. For HOTRESET
bit shifting we need another conversion table, which will come later.

Signed-off-by: Hiroshi Doyu 
---
v5:
Added new macro TEGRA_SWGROUP_CELLS() and WO_U32_OF_U64().

v4:
This is almost same as the previous v3. Just TEGRA_SWGROUP_MAX is
added.
  [PATCHv3 15/19] ARM: tegra: Create a DT header defining SWGROUP ID
---
 include/dt-bindings/memory/tegra-swgroup.h | 50 ++
 1 file changed, 50 insertions(+)
 create mode 100644 include/dt-bindings/memory/tegra-swgroup.h

diff --git a/include/dt-bindings/memory/tegra-swgroup.h 
b/include/dt-bindings/memory/tegra-swgroup.h
new file mode 100644
index 000..73079ad
--- /dev/null
+++ b/include/dt-bindings/memory/tegra-swgroup.h
@@ -0,0 +1,50 @@
+/*
+ * This header provides constants for binding nvidia,swgroup ID
+ */
+
+#ifndef _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H
+#define _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H
+
+#define TEGRA_SWGROUP_AFI  0   /* 0x238 */
+#define TEGRA_SWGROUP_AVPC 1   /* 0x23c */
+#define TEGRA_SWGROUP_DC   2   /* 0x240 */
+#define TEGRA_SWGROUP_DCB  3   /* 0x244 */
+#define TEGRA_SWGROUP_EPP  4   /* 0x248 */
+#define TEGRA_SWGROUP_G2   5   /* 0x24c */
+#define TEGRA_SWGROUP_HC   6   /* 0x250 */
+#define TEGRA_SWGROUP_HDA  7   /* 0x254 */
+#define TEGRA_SWGROUP_ISP  8   /* 0x258 */
+#define TEGRA_SWGROUP_ISP2 SWGROUP_ISP
+#define TEGRA_SWGROUP_DC14 9   /* 0x490 *//* Exceptional non-linear */
+#define TEGRA_SWGROUP_DC12 10  /* 0xa88 *//* Exceptional non-linear */
+#define TEGRA_SWGROUP_MPE  11  /* 0x264 */
+#define TEGRA_SWGROUP_MSENCSWGROUP_MPE
+#define TEGRA_SWGROUP_NV   12  /* 0x268 */
+#define TEGRA_SWGROUP_NV2  13  /* 0x26c */
+#define TEGRA_SWGROUP_PPCS 14  /* 0x270 */
+#define TEGRA_SWGROUP_SATA215  /* 0x274 */
+#define TEGRA_SWGROUP_SATA 16  /* 0x278 */
+#define TEGRA_SWGROUP_VDE  17  /* 0x27c */
+#define TEGRA_SWGROUP_VI   18  /* 0x280 */
+#define TEGRA_SWGROUP_VIC  19  /* 0x284 */
+#define TEGRA_SWGROUP_XUSB_HOST20  /* 0x288 */
+#define TEGRA_SWGROUP_XUSB_DEV 21  /* 0x28c */
+#define TEGRA_SWGROUP_A9AVP22  /* 0x290 */
+#define TEGRA_SWGROUP_TSEC 23  /* 0x294 */
+#define TEGRA_SWGROUP_PPCS124  /* 0x298 */
+#define TEGRA_SWGROUP_SDMMC1A  25  /* 0xa94 *//* Linear shift again */
+#define TEGRA_SWGROUP_SDMMC2A  26  /* 0xa98 */
+#define TEGRA_SWGROUP_SDMMC3A  27  /* 0xa9c */
+#define TEGRA_SWGROUP_SDMMC4A  28  /* 0xaa0 */
+#define TEGRA_SWGROUP_ISP2B29  /* 0xaa4 */
+#define TEGRA_SWGROUP_GPU  30  /* 0xaa8 */
+#define TEGRA_SWGROUP_GPUB 31  /* 0xaac */
+#define TEGRA_SWGROUP_PPCS232  /* 0xab0 */
+
+#define TWO_U32_OF_U64(x)  ((x) & ~0UL) ((x) >> 32)
+#define TEGRA_SWGROUP_BIT(x)   (1ULL << TEGRA_SWGROUP_##x)
+#define TEGRA_SWGROUP_CELLS(x) TWO_U32_OF_U64(TEGRA_SWGROUP_BIT(x))
+
+#define TEGRA_SWGROUP_MAX  64
+
+#endif /* _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H */
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv5 6/9] iommu/tegra: smmu: get swgroups from DT "iommus="

2013-11-19 Thread Hiroshi Doyu
This provides the info about which swgroups a device belongs to. This
info is passed from DT. This is necessary for the unified SMMU driver
among Tegra SoCs since each has different H/W accelerators.

Signed-off-by: Hiroshi Doyu 
---
v5:
"iommu=" in a device DT is used instead of "mmu-masters" in an iommu
DT. This is "iommu=" version of:

  [PATCHv4 5/7] iommu/tegra: smmu: Support "mmu-masters" binding
---
 .../bindings/iommu/nvidia,tegra30-smmu.txt |  17 ++-
 drivers/iommu/tegra-smmu.c | 125 ++---
 2 files changed, 126 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt 
b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
index 89fb543..44a4dc3 100644
--- a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
@@ -8,9 +8,12 @@ Required properties:
 - nvidia,#asids : # of ASIDs
 - dma-window : IOVA start address and length.
 - nvidia,ahb : phandle to the ahb bus connected to SMMU.
+- iommus: phandle to an iommu device which a device is
+  attached to and indicates which swgroups a device belongs to(SWGROUP ID).
+  SWGROUP ID is from 0 to 63, and a device can belong to multiple SWGROUPS.
 
 Example:
-   smmu {
+   smmu: iommu {
compatible = "nvidia,tegra30-smmu";
reg = <0x7000f010 0x02c
   0x7000f1f0 0x010
@@ -18,4 +21,16 @@ Example:
nvidia,#asids = <4>;/* # of ASIDs */
dma-window = <0 0x4000>;/* IOVA start & length */
nvidia,ahb = <>;
+   #iommu-cells = <2>;
};
+
+   host1x {
+   compatible = "nvidia,tegra30-host1x", "simple-bus";
+   iommus = < TEGRA_SWGROUP_CELLS(HC)>;
+   
+   gr3d {
+   compatible = "nvidia,tegra30-gr3d";
+   nvidia,memory-clients = < TEGRA_SWGROUP_CELLS(NV)
+  
TEGRA_SWGROUP_CELLS(NV2)>;
+   
+   };
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index e999ad0..e915201a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -190,6 +190,8 @@ enum {
  * Per client for address space
  */
 struct smmu_client {
+   struct device_node  *of_node;
+   struct rb_node  node;
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
@@ -233,6 +235,7 @@ struct smmu_device {
spinlock_t  lock;
char*name;
struct device   *dev;
+   struct rb_root  clients;
struct page *avp_vector_page;   /* dummy page shared by all AS's */
 
/*
@@ -310,6 +313,96 @@ static inline void smmu_write(struct smmu_device *smmu, 
u32 val, size_t offs)
  */
 #define FLUSH_SMMU_REGS(smmu)  smmu_read(smmu, SMMU_CONFIG)
 
+static struct smmu_client *find_smmu_client(struct smmu_device *smmu,
+   struct device_node *dev_node)
+{
+   struct rb_node *node = smmu->clients.rb_node;
+
+   while (node) {
+   struct smmu_client *client;
+
+   client = container_of(node, struct smmu_client, node);
+   if (dev_node < client->of_node)
+   node = node->rb_left;
+   else if (dev_node > client->of_node)
+   node = node->rb_right;
+   else
+   return client;
+   }
+
+   return NULL;
+}
+
+static int insert_smmu_client(struct smmu_device *smmu,
+ struct smmu_client *client)
+{
+   struct rb_node **new, *parent;
+
+   new = >clients.rb_node;
+   parent = NULL;
+   while (*new) {
+   struct smmu_client *this;
+   this = container_of(*new, struct smmu_client, node);
+
+   parent = *new;
+   if (client->of_node < this->of_node)
+   new = &((*new)->rb_left);
+   else if (client->of_node > this->of_node)
+   new = &((*new)->rb_right);
+   else
+   return -EEXIST;
+   }
+
+   rb_link_node(>node, parent, new);
+   rb_insert_color(>node, >clients);
+   return 0;
+}
+
+static int register_smmu_client(struct smmu_device *smmu,
+   struct device *dev, unsigned long *swgroups)
+{
+   struct smmu_client *client;
+
+   client = find_smmu_client(smmu, dev->of_node);
+   if (client) {
+   dev_err(dev,
+   "rejecting multiple regis

[PATCHv5 0/9] Unifying Tegra IOMMU(SMMU) driver among Tegra SoCs

2013-11-19 Thread Hiroshi Doyu
Hi,

This series provide:

(1) Unified IOMMU(SMMU) driver among Tegra SoCs
(2) Multiple Address Space support(MASID) in IOMMU(SMMMU)
(3) Tegra IOMMU'able devices, most of platform devices are IOMMU'able.

There's been some discussion[1] about device population order, and for
the solution I implemented an IOMMU hook in driver core:

  [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

which is based on:
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006933.html

The main problem here is,

IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, "iommus=" DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an iommu device is populated. Once
an iommu device is populated, "dev->bus->iommu_ops" is set in the
bus. Then, those defered iommu master devices are populated and
configured for IOMMU with help of the already populated iommu device
via iommu_ops->add_device(). Multiple IOMMUs can be listed on this
"iommus" binding so that a device can have multiple IOMMUs attached.

Currenly this "iommus=" binding is used as the global binding.

Tested IOMMU functionality with T30 SD/MMC. Any further testing with
T114 and/or other devices would be really appreciated.

v4:
Add a hook in driver core to control device populatin order.
Introduced arm,smmu "mmu-master" binding instead of tegra own.
Removed DT patches from this series.
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006931.html

v3:
Updated based on Stephen Warren's feedback
  http://lists.linuxfoundation.org/pipermail/iommu/2013-October/006724.html

v2:
Updated based on Thierry Reding's and Stephen Warren's feedback
  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/181888.html

v1:
  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/180267.html

Available in the git repository at:

  git://g...@nv-tegra.nvidia.com/user/hdoyu/linux.git smmu-upstreaming@20131119


Hiroshi Doyu (9):
  of: introduce of_property_for_earch_phandle_with_args()
  driver/core: populate devices in order for IOMMUs
  ARM: tegra: create a DT header defining SWGROUP ID
  iommu/tegra: smmu: register device to iommu dynamically
  iommu/tegra: smmu: calculate ASID register offset by ID
  iommu/tegra: smmu: get swgroups from DT "iommus="
  iommu/tegra: smmu: allow duplicate ASID wirte
  iommu/tegra: smmu: Rename hwgrp -> swgroups
  [FOR TEST] ARM: dt: tegra30: add "iommus" binding

 .../bindings/iommu/nvidia,tegra30-smmu.txt |  17 +-
 arch/arm/boot/dts/tegra30.dtsi |  23 +-
 drivers/base/dd.c  |   5 +
 drivers/iommu/Kconfig  |   1 +
 drivers/iommu/of_iommu.c   |  22 ++
 drivers/iommu/tegra-smmu.c | 334 +
 include/dt-bindings/memory/tegra-swgroup.h |  50 +++
 include/linux/of.h |   3 +
 include/linux/of_iommu.h   |   7 +
 9 files changed, 336 insertions(+), 126 deletions(-)
 create mode 100644 include/dt-bindings/memory/tegra-swgroup.h

[1] 
https://lists.ozlabs.org/pipermail/devicetree-discuss/2013-June/thread.html#36542
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv5 4/9] iommu/tegra: smmu: register device to iommu dynamically

2013-11-19 Thread Hiroshi Doyu
platform_devices are registered as IOMMU'able dynamically via
add_device() and remove_device().

Tegra SMMU can have multiple address spaces(AS). IOMMU'able devices
can belong to one of them. Multiple IOVA maps are created at boot-up,
which can be attached to devices later. We reserve 2 of them for
static assignment, AS[0] for system default, AS[1] for AHB clusters as
protected domain from others, where there are many traditional
pheripheral devices like USB, SD/MMC. They should be isolated from
some smart devices like host1x for system robustness. Even if smart
devices behaves wrongly, the traditional devices(SD/MMC, USB) wouldn't
be affected, and the system could continue most likely. DMA API(ARM)
needs ARM_DMA_USE_IOMMU to be enabled.

Signed-off-by: Hiroshi Doyu 
---
v5:
Add check NUM_OF_STATIC_MAPS < #asids.

v4:
Combined the following from v3. This makes more sense what they do.
  [PATCHv3 06/19] iommu/tegra: smmu: Select ARM_DMA_USE_IOMMU in Kconfig
  [PATCHv3 07/19] iommu/tegra: smmu: Create default IOVA maps
  [PATCHv3 08/19] iommu/tegra: smmu: Register platform_device to IOMMU 
dynamically
  [PATCHv3 19/19] iommu/tegra: smmu: Support Multiple ASID
---
 drivers/iommu/Kconfig  |  1 +
 drivers/iommu/tegra-smmu.c | 70 +-
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c880eba..d1bc65d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -170,6 +170,7 @@ config TEGRA_IOMMU_SMMU
bool "Tegra SMMU IOMMU Support"
depends on ARCH_TEGRA && TEGRA_AHB
select IOMMU_API
+   select ARM_DMA_USE_IOMMU
help
  Enables support for remapping discontiguous physical memory
  shared with the operating system into contiguous I/O virtual
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 37dd862..d836a6b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -39,6 +39,9 @@
 
 #include 
 #include 
+#include 
+
+#include 
 
 enum smmu_hwgrp {
HWGRP_AFI,
@@ -319,6 +322,8 @@ struct smmu_device {
 
struct device_node *ahb;
 
+   struct dma_iommu_mapping **map;
+
int num_as;
struct smmu_as  as[0];  /* Run-time allocated array */
 };
@@ -947,6 +952,44 @@ static void smmu_iommu_domain_destroy(struct iommu_domain 
*domain)
dev_dbg(smmu->dev, "smmu_as@%p\n", as);
 }
 
+/*
+ * ASID[0] for the system default
+ * ASID[1] for PPCS("AHB bus children"), which has SDMMC
+ * ASID[2][3].. open for drivers, first come, first served.
+ */
+enum {
+   SYSTEM_DEFAULT,
+   SYSTEM_PROTECTED,
+   NUM_OF_STATIC_MAPS,
+};
+
+static int smmu_iommu_add_device(struct device *dev)
+{
+   int err = -EPROBE_DEFER;
+   u32 swgroups = dev->platform_data;
+   struct dma_iommu_mapping *map = NULL;
+
+   if (test_bit(TEGRA_SWGROUP_PPCS, swgroups))
+   map = smmu_handle->map[SYSTEM_PROTECTED];
+   else
+   map = smmu_handle->map[SYSTEM_DEFAULT];
+
+   if (map)
+   err = arm_iommu_attach_device(dev, map);
+   else
+   return -EPROBE_DEFER;
+
+   pr_debug("swgroups=%08lx map=%p err=%d %s\n",
+swgroups, map, err, dev_name(dev));
+   return err;
+}
+
+static void smmu_iommu_remove_device(struct device *dev)
+{
+   dev_dbg(dev, "Detaching from map %p\n", to_dma_iommu_mapping(dev));
+   arm_iommu_detach_device(dev);
+}
+
 static struct iommu_ops smmu_iommu_ops = {
.domain_init= smmu_iommu_domain_init,
.domain_destroy = smmu_iommu_domain_destroy,
@@ -956,6 +999,8 @@ static struct iommu_ops smmu_iommu_ops = {
.unmap  = smmu_iommu_unmap,
.iova_to_phys   = smmu_iommu_iova_to_phys,
.domain_has_cap = smmu_iommu_domain_has_cap,
+   .add_device = smmu_iommu_add_device,
+   .remove_device  = smmu_iommu_remove_device,
.pgsize_bitmap  = SMMU_IOMMU_PGSIZES,
 };
 
@@ -1144,6 +1189,23 @@ static int tegra_smmu_resume(struct device *dev)
return err;
 }
 
+static void tegra_smmu_create_default_map(struct smmu_device *smmu)
+{
+   int i;
+
+   for (i = 0; i < smmu->num_as; i++) {
+   dma_addr_t base = smmu->iovmm_base;
+   size_t size = smmu->page_count << PAGE_SHIFT;
+
+   smmu->map[i] = arm_iommu_create_mapping(_bus_type,
+   base, size, 0);
+   if (IS_ERR(smmu->map[i]))
+   dev_err(smmu->dev,
+   "Couldn't create: asid=%d map=%p %pa-%pa\n",
+   i, smmu->map[i], ,  + size - 1);
+   }
+}
+
 static int tegra_smmu_probe(struct platform_device *pdev)
 {
struct smmu_device *smmu;
@@ -1160,13 +1222,18 @@ 

[PATCHv5 1/9] of: introduce of_property_for_earch_phandle_with_args()

2013-11-19 Thread Hiroshi Doyu
The following pattern of code is tempting:

  for (i = 0; !of_parse_phandle_with_args(np, list, cells, i, args); i++)

Signed-off-by: Hiroshi Doyu 
---
v5:
New patch for v5.
---
 include/linux/of.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..131fef5 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -613,6 +613,9 @@ static inline int of_property_read_u32(const struct 
device_node *np,
s;  \
s = of_prop_next_string(prop, s))
 
+#define of_property_for_each_phandle_with_args(np, list, cells, i, args) \
+   for (i = 0; !of_parse_phandle_with_args(np, list, cells, i, args); i++)
+
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE)
 extern void proc_device_tree_add_node(struct device_node *, struct 
proc_dir_entry *);
 extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct 
property *prop);
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv5 1/9] of: introduce of_property_for_earch_phandle_with_args()

2013-11-19 Thread Hiroshi Doyu
The following pattern of code is tempting:

  for (i = 0; !of_parse_phandle_with_args(np, list, cells, i, args); i++)

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v5:
New patch for v5.
---
 include/linux/of.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..131fef5 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -613,6 +613,9 @@ static inline int of_property_read_u32(const struct 
device_node *np,
s;  \
s = of_prop_next_string(prop, s))
 
+#define of_property_for_each_phandle_with_args(np, list, cells, i, args) \
+   for (i = 0; !of_parse_phandle_with_args(np, list, cells, i, args); i++)
+
 #if defined(CONFIG_PROC_FS)  defined(CONFIG_PROC_DEVICETREE)
 extern void proc_device_tree_add_node(struct device_node *, struct 
proc_dir_entry *);
 extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct 
property *prop);
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv5 4/9] iommu/tegra: smmu: register device to iommu dynamically

2013-11-19 Thread Hiroshi Doyu
platform_devices are registered as IOMMU'able dynamically via
add_device() and remove_device().

Tegra SMMU can have multiple address spaces(AS). IOMMU'able devices
can belong to one of them. Multiple IOVA maps are created at boot-up,
which can be attached to devices later. We reserve 2 of them for
static assignment, AS[0] for system default, AS[1] for AHB clusters as
protected domain from others, where there are many traditional
pheripheral devices like USB, SD/MMC. They should be isolated from
some smart devices like host1x for system robustness. Even if smart
devices behaves wrongly, the traditional devices(SD/MMC, USB) wouldn't
be affected, and the system could continue most likely. DMA API(ARM)
needs ARM_DMA_USE_IOMMU to be enabled.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v5:
Add check NUM_OF_STATIC_MAPS  #asids.

v4:
Combined the following from v3. This makes more sense what they do.
  [PATCHv3 06/19] iommu/tegra: smmu: Select ARM_DMA_USE_IOMMU in Kconfig
  [PATCHv3 07/19] iommu/tegra: smmu: Create default IOVA maps
  [PATCHv3 08/19] iommu/tegra: smmu: Register platform_device to IOMMU 
dynamically
  [PATCHv3 19/19] iommu/tegra: smmu: Support Multiple ASID
---
 drivers/iommu/Kconfig  |  1 +
 drivers/iommu/tegra-smmu.c | 70 +-
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c880eba..d1bc65d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -170,6 +170,7 @@ config TEGRA_IOMMU_SMMU
bool Tegra SMMU IOMMU Support
depends on ARCH_TEGRA  TEGRA_AHB
select IOMMU_API
+   select ARM_DMA_USE_IOMMU
help
  Enables support for remapping discontiguous physical memory
  shared with the operating system into contiguous I/O virtual
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 37dd862..d836a6b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -39,6 +39,9 @@
 
 #include asm/page.h
 #include asm/cacheflush.h
+#include asm/dma-iommu.h
+
+#include dt-bindings/memory/tegra-swgroup.h
 
 enum smmu_hwgrp {
HWGRP_AFI,
@@ -319,6 +322,8 @@ struct smmu_device {
 
struct device_node *ahb;
 
+   struct dma_iommu_mapping **map;
+
int num_as;
struct smmu_as  as[0];  /* Run-time allocated array */
 };
@@ -947,6 +952,44 @@ static void smmu_iommu_domain_destroy(struct iommu_domain 
*domain)
dev_dbg(smmu-dev, smmu_as@%p\n, as);
 }
 
+/*
+ * ASID[0] for the system default
+ * ASID[1] for PPCS(AHB bus children), which has SDMMC
+ * ASID[2][3].. open for drivers, first come, first served.
+ */
+enum {
+   SYSTEM_DEFAULT,
+   SYSTEM_PROTECTED,
+   NUM_OF_STATIC_MAPS,
+};
+
+static int smmu_iommu_add_device(struct device *dev)
+{
+   int err = -EPROBE_DEFER;
+   u32 swgroups = dev-platform_data;
+   struct dma_iommu_mapping *map = NULL;
+
+   if (test_bit(TEGRA_SWGROUP_PPCS, swgroups))
+   map = smmu_handle-map[SYSTEM_PROTECTED];
+   else
+   map = smmu_handle-map[SYSTEM_DEFAULT];
+
+   if (map)
+   err = arm_iommu_attach_device(dev, map);
+   else
+   return -EPROBE_DEFER;
+
+   pr_debug(swgroups=%08lx map=%p err=%d %s\n,
+swgroups, map, err, dev_name(dev));
+   return err;
+}
+
+static void smmu_iommu_remove_device(struct device *dev)
+{
+   dev_dbg(dev, Detaching from map %p\n, to_dma_iommu_mapping(dev));
+   arm_iommu_detach_device(dev);
+}
+
 static struct iommu_ops smmu_iommu_ops = {
.domain_init= smmu_iommu_domain_init,
.domain_destroy = smmu_iommu_domain_destroy,
@@ -956,6 +999,8 @@ static struct iommu_ops smmu_iommu_ops = {
.unmap  = smmu_iommu_unmap,
.iova_to_phys   = smmu_iommu_iova_to_phys,
.domain_has_cap = smmu_iommu_domain_has_cap,
+   .add_device = smmu_iommu_add_device,
+   .remove_device  = smmu_iommu_remove_device,
.pgsize_bitmap  = SMMU_IOMMU_PGSIZES,
 };
 
@@ -1144,6 +1189,23 @@ static int tegra_smmu_resume(struct device *dev)
return err;
 }
 
+static void tegra_smmu_create_default_map(struct smmu_device *smmu)
+{
+   int i;
+
+   for (i = 0; i  smmu-num_as; i++) {
+   dma_addr_t base = smmu-iovmm_base;
+   size_t size = smmu-page_count  PAGE_SHIFT;
+
+   smmu-map[i] = arm_iommu_create_mapping(platform_bus_type,
+   base, size, 0);
+   if (IS_ERR(smmu-map[i]))
+   dev_err(smmu-dev,
+   Couldn't create: asid=%d map=%p %pa-%pa\n,
+   i, smmu-map[i], base, base + size - 1);
+   }
+}
+
 static int tegra_smmu_probe(struct platform_device *pdev)
 {
struct smmu_device *smmu;
@@ -1160,13 +1222,18 @@ static int tegra_smmu_probe(struct

[PATCHv5 0/9] Unifying Tegra IOMMU(SMMU) driver among Tegra SoCs

2013-11-19 Thread Hiroshi Doyu
Hi,

This series provide:

(1) Unified IOMMU(SMMU) driver among Tegra SoCs
(2) Multiple Address Space support(MASID) in IOMMU(SMMMU)
(3) Tegra IOMMU'able devices, most of platform devices are IOMMU'able.

There's been some discussion[1] about device population order, and for
the solution I implemented an IOMMU hook in driver core:

  [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

which is based on:
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006933.html

The main problem here is,

IOMMU devices on the bus need to be poplulated first, then iommu
master devices are done later.

With CONFIG_OF_IOMMU, iommus= DT binding would be used to identify
whether a device can be an iommu msater or not. If a device can, we'll
defer to populate that device till an iommu device is populated. Once
an iommu device is populated, dev-bus-iommu_ops is set in the
bus. Then, those defered iommu master devices are populated and
configured for IOMMU with help of the already populated iommu device
via iommu_ops-add_device(). Multiple IOMMUs can be listed on this
iommus binding so that a device can have multiple IOMMUs attached.

Currenly this iommus= binding is used as the global binding.

Tested IOMMU functionality with T30 SD/MMC. Any further testing with
T114 and/or other devices would be really appreciated.

v4:
Add a hook in driver core to control device populatin order.
Introduced arm,smmu mmu-master binding instead of tegra own.
Removed DT patches from this series.
  http://lists.linuxfoundation.org/pipermail/iommu/2013-November/006931.html

v3:
Updated based on Stephen Warren's feedback
  http://lists.linuxfoundation.org/pipermail/iommu/2013-October/006724.html

v2:
Updated based on Thierry Reding's and Stephen Warren's feedback
  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-July/181888.html

v1:
  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-June/180267.html

Available in the git repository at:

  git://g...@nv-tegra.nvidia.com/user/hdoyu/linux.git smmu-upstreaming@20131119


Hiroshi Doyu (9):
  of: introduce of_property_for_earch_phandle_with_args()
  driver/core: populate devices in order for IOMMUs
  ARM: tegra: create a DT header defining SWGROUP ID
  iommu/tegra: smmu: register device to iommu dynamically
  iommu/tegra: smmu: calculate ASID register offset by ID
  iommu/tegra: smmu: get swgroups from DT iommus=
  iommu/tegra: smmu: allow duplicate ASID wirte
  iommu/tegra: smmu: Rename hwgrp - swgroups
  [FOR TEST] ARM: dt: tegra30: add iommus binding

 .../bindings/iommu/nvidia,tegra30-smmu.txt |  17 +-
 arch/arm/boot/dts/tegra30.dtsi |  23 +-
 drivers/base/dd.c  |   5 +
 drivers/iommu/Kconfig  |   1 +
 drivers/iommu/of_iommu.c   |  22 ++
 drivers/iommu/tegra-smmu.c | 334 +
 include/dt-bindings/memory/tegra-swgroup.h |  50 +++
 include/linux/of.h |   3 +
 include/linux/of_iommu.h   |   7 +
 9 files changed, 336 insertions(+), 126 deletions(-)
 create mode 100644 include/dt-bindings/memory/tegra-swgroup.h

[1] 
https://lists.ozlabs.org/pipermail/devicetree-discuss/2013-June/thread.html#36542
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv5 6/9] iommu/tegra: smmu: get swgroups from DT iommus=

2013-11-19 Thread Hiroshi Doyu
This provides the info about which swgroups a device belongs to. This
info is passed from DT. This is necessary for the unified SMMU driver
among Tegra SoCs since each has different H/W accelerators.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v5:
iommu= in a device DT is used instead of mmu-masters in an iommu
DT. This is iommu= version of:

  [PATCHv4 5/7] iommu/tegra: smmu: Support mmu-masters binding
---
 .../bindings/iommu/nvidia,tegra30-smmu.txt |  17 ++-
 drivers/iommu/tegra-smmu.c | 125 ++---
 2 files changed, 126 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt 
b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
index 89fb543..44a4dc3 100644
--- a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
@@ -8,9 +8,12 @@ Required properties:
 - nvidia,#asids : # of ASIDs
 - dma-window : IOVA start address and length.
 - nvidia,ahb : phandle to the ahb bus connected to SMMU.
+- iommus: phandle to an iommu device which a device is
+  attached to and indicates which swgroups a device belongs to(SWGROUP ID).
+  SWGROUP ID is from 0 to 63, and a device can belong to multiple SWGROUPS.
 
 Example:
-   smmu {
+   smmu: iommu {
compatible = nvidia,tegra30-smmu;
reg = 0x7000f010 0x02c
   0x7000f1f0 0x010
@@ -18,4 +21,16 @@ Example:
nvidia,#asids = 4;/* # of ASIDs */
dma-window = 0 0x4000;/* IOVA start  length */
nvidia,ahb = ahb;
+   #iommu-cells = 2;
};
+
+   host1x {
+   compatible = nvidia,tegra30-host1x, simple-bus;
+   iommus = smmu TEGRA_SWGROUP_CELLS(HC);
+   
+   gr3d {
+   compatible = nvidia,tegra30-gr3d;
+   nvidia,memory-clients = smmu TEGRA_SWGROUP_CELLS(NV)
+  
TEGRA_SWGROUP_CELLS(NV2);
+   
+   };
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index e999ad0..e915201a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -190,6 +190,8 @@ enum {
  * Per client for address space
  */
 struct smmu_client {
+   struct device_node  *of_node;
+   struct rb_node  node;
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
@@ -233,6 +235,7 @@ struct smmu_device {
spinlock_t  lock;
char*name;
struct device   *dev;
+   struct rb_root  clients;
struct page *avp_vector_page;   /* dummy page shared by all AS's */
 
/*
@@ -310,6 +313,96 @@ static inline void smmu_write(struct smmu_device *smmu, 
u32 val, size_t offs)
  */
 #define FLUSH_SMMU_REGS(smmu)  smmu_read(smmu, SMMU_CONFIG)
 
+static struct smmu_client *find_smmu_client(struct smmu_device *smmu,
+   struct device_node *dev_node)
+{
+   struct rb_node *node = smmu-clients.rb_node;
+
+   while (node) {
+   struct smmu_client *client;
+
+   client = container_of(node, struct smmu_client, node);
+   if (dev_node  client-of_node)
+   node = node-rb_left;
+   else if (dev_node  client-of_node)
+   node = node-rb_right;
+   else
+   return client;
+   }
+
+   return NULL;
+}
+
+static int insert_smmu_client(struct smmu_device *smmu,
+ struct smmu_client *client)
+{
+   struct rb_node **new, *parent;
+
+   new = smmu-clients.rb_node;
+   parent = NULL;
+   while (*new) {
+   struct smmu_client *this;
+   this = container_of(*new, struct smmu_client, node);
+
+   parent = *new;
+   if (client-of_node  this-of_node)
+   new = ((*new)-rb_left);
+   else if (client-of_node  this-of_node)
+   new = ((*new)-rb_right);
+   else
+   return -EEXIST;
+   }
+
+   rb_link_node(client-node, parent, new);
+   rb_insert_color(client-node, smmu-clients);
+   return 0;
+}
+
+static int register_smmu_client(struct smmu_device *smmu,
+   struct device *dev, unsigned long *swgroups)
+{
+   struct smmu_client *client;
+
+   client = find_smmu_client(smmu, dev-of_node);
+   if (client) {
+   dev_err(dev,
+   rejecting multiple registrations for client device 
%s\n,
+   dev-of_node-full_name);
+   return -EBUSY;
+   }
+
+   client = devm_kzalloc(smmu-dev, sizeof(*client), GFP_KERNEL

[PATCHv5 3/9] ARM: tegra: create a DT header defining SWGROUP ID

2013-11-19 Thread Hiroshi Doyu
Create a header file to define the swgroup IDs used by the IOMMU(SMMU)
binding. swgroup is a group of H/W clients which a Tegra SoC
supports. This unique ID can be used to calculate MC_SMMU_swgroup
name_ASID_0 register offset and MC_swgroup name_HOTRESET_*_0
register bit. This will allow the same header to be used by both
device tree files, and drivers implementing this binding, which
guarantees that the two stay in sync. This also makes device trees
more readable by using names instead of magic numbers. For HOTRESET
bit shifting we need another conversion table, which will come later.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v5:
Added new macro TEGRA_SWGROUP_CELLS() and WO_U32_OF_U64().

v4:
This is almost same as the previous v3. Just TEGRA_SWGROUP_MAX is
added.
  [PATCHv3 15/19] ARM: tegra: Create a DT header defining SWGROUP ID
---
 include/dt-bindings/memory/tegra-swgroup.h | 50 ++
 1 file changed, 50 insertions(+)
 create mode 100644 include/dt-bindings/memory/tegra-swgroup.h

diff --git a/include/dt-bindings/memory/tegra-swgroup.h 
b/include/dt-bindings/memory/tegra-swgroup.h
new file mode 100644
index 000..73079ad
--- /dev/null
+++ b/include/dt-bindings/memory/tegra-swgroup.h
@@ -0,0 +1,50 @@
+/*
+ * This header provides constants for binding nvidia,swgroup ID
+ */
+
+#ifndef _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H
+#define _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H
+
+#define TEGRA_SWGROUP_AFI  0   /* 0x238 */
+#define TEGRA_SWGROUP_AVPC 1   /* 0x23c */
+#define TEGRA_SWGROUP_DC   2   /* 0x240 */
+#define TEGRA_SWGROUP_DCB  3   /* 0x244 */
+#define TEGRA_SWGROUP_EPP  4   /* 0x248 */
+#define TEGRA_SWGROUP_G2   5   /* 0x24c */
+#define TEGRA_SWGROUP_HC   6   /* 0x250 */
+#define TEGRA_SWGROUP_HDA  7   /* 0x254 */
+#define TEGRA_SWGROUP_ISP  8   /* 0x258 */
+#define TEGRA_SWGROUP_ISP2 SWGROUP_ISP
+#define TEGRA_SWGROUP_DC14 9   /* 0x490 *//* Exceptional non-linear */
+#define TEGRA_SWGROUP_DC12 10  /* 0xa88 *//* Exceptional non-linear */
+#define TEGRA_SWGROUP_MPE  11  /* 0x264 */
+#define TEGRA_SWGROUP_MSENCSWGROUP_MPE
+#define TEGRA_SWGROUP_NV   12  /* 0x268 */
+#define TEGRA_SWGROUP_NV2  13  /* 0x26c */
+#define TEGRA_SWGROUP_PPCS 14  /* 0x270 */
+#define TEGRA_SWGROUP_SATA215  /* 0x274 */
+#define TEGRA_SWGROUP_SATA 16  /* 0x278 */
+#define TEGRA_SWGROUP_VDE  17  /* 0x27c */
+#define TEGRA_SWGROUP_VI   18  /* 0x280 */
+#define TEGRA_SWGROUP_VIC  19  /* 0x284 */
+#define TEGRA_SWGROUP_XUSB_HOST20  /* 0x288 */
+#define TEGRA_SWGROUP_XUSB_DEV 21  /* 0x28c */
+#define TEGRA_SWGROUP_A9AVP22  /* 0x290 */
+#define TEGRA_SWGROUP_TSEC 23  /* 0x294 */
+#define TEGRA_SWGROUP_PPCS124  /* 0x298 */
+#define TEGRA_SWGROUP_SDMMC1A  25  /* 0xa94 *//* Linear shift again */
+#define TEGRA_SWGROUP_SDMMC2A  26  /* 0xa98 */
+#define TEGRA_SWGROUP_SDMMC3A  27  /* 0xa9c */
+#define TEGRA_SWGROUP_SDMMC4A  28  /* 0xaa0 */
+#define TEGRA_SWGROUP_ISP2B29  /* 0xaa4 */
+#define TEGRA_SWGROUP_GPU  30  /* 0xaa8 */
+#define TEGRA_SWGROUP_GPUB 31  /* 0xaac */
+#define TEGRA_SWGROUP_PPCS232  /* 0xab0 */
+
+#define TWO_U32_OF_U64(x)  ((x)  ~0UL) ((x)  32)
+#define TEGRA_SWGROUP_BIT(x)   (1ULL  TEGRA_SWGROUP_##x)
+#define TEGRA_SWGROUP_CELLS(x) TWO_U32_OF_U64(TEGRA_SWGROUP_BIT(x))
+
+#define TEGRA_SWGROUP_MAX  64
+
+#endif /* _DT_BINDINGS_MEMORY_TEGRA_SWGROUP_H */
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv5 8/9] iommu/tegra: smmu: Rename hwgrp - swgroups

2013-11-19 Thread Hiroshi Doyu
Use the correct term for SWGROUP related variables and macros.

The term swgroup is the collection of memory client. A memory
client usually represents a HardWare Accelerator(HWA) like
GPU. Sometimes a strut device can belong to multiple swgroup so that
swgroup's' is used here. This swgroups is the term used in Tegra
TRM. Rename along with TRM.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v4:
New for v4
---
 drivers/iommu/tegra-smmu.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index c2ed075..003a491 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -179,12 +179,12 @@ enum {
 
 #define NUM_SMMU_REG_BANKS 3
 
-#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1)
-#define smmu_client_disable_hwgrp(c)   smmu_client_set_hwgrp(c, 0, 0)
-#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
-#define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0)
+#define smmu_client_enable_swgroups(c, m) smmu_client_set_swgroups(c, m, 1)
+#define smmu_client_disable_swgroups(c) smmu_client_set_swgroups(c, 0, 0)
+#define __smmu_client_enable_swgroups(c, m) __smmu_client_set_swgroups(c, m, 1)
+#define __smmu_client_disable_swgroups(c) __smmu_client_set_swgroups(c, 0, 0)
 
-#define HWGRP_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
+#define SWGROUPS_ASID_REG(x) ((x) * sizeof(u32) + SMMU_ASID_BASE)
 
 /*
  * Per client for address space
@@ -195,7 +195,7 @@ struct smmu_client {
struct device   *dev;
struct list_headlist;
struct smmu_as  *as;
-   unsigned long   hwgrp[2];
+   unsigned long   swgroups[2];
 };
 
 /*
@@ -377,7 +377,7 @@ static int register_smmu_client(struct smmu_device *smmu,
 
client-dev = dev;
client-of_node = dev-of_node;
-   memcpy(client-hwgrp, swgroups, sizeof(u64));
+   memcpy(client-swgroups, swgroups, sizeof(u64));
return insert_smmu_client(smmu, client);
 }
 
@@ -403,7 +403,7 @@ static int smmu_of_get_swgroups(struct device *dev, 
unsigned long *swgroups)
return -ENODEV;
 }
 
-static int __smmu_client_set_hwgrp(struct smmu_client *c,
+static int __smmu_client_set_swgroups(struct smmu_client *c,
   unsigned long *map, int on)
 {
int i;
@@ -412,10 +412,10 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
struct smmu_device *smmu = as-smmu;
 
if (!on)
-   map = c-hwgrp;
+   map = c-swgroups;
 
for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
-   offs = HWGRP_ASID_REG(i);
+   offs = SWGROUPS_ASID_REG(i);
val = smmu_read(smmu, offs);
if (on) {
if (val) {
@@ -425,7 +425,7 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
}
 
val = mask;
-   memcpy(c-hwgrp, map, sizeof(u64));
+   memcpy(c-swgroups, map, sizeof(u64));
} else {
WARN_ON((val  mask) == mask);
val = ~mask;
@@ -438,7 +438,7 @@ skip:
return 0;
 }
 
-static int smmu_client_set_hwgrp(struct smmu_client *c,
+static int smmu_client_set_swgroups(struct smmu_client *c,
 unsigned long *map, int on)
 {
int err;
@@ -447,7 +447,7 @@ static int smmu_client_set_hwgrp(struct smmu_client *c,
struct smmu_device *smmu = as-smmu;
 
spin_lock_irqsave(smmu-lock, flags);
-   err = __smmu_client_set_hwgrp(c, map, on);
+   err = __smmu_client_set_swgroups(c, map, on);
spin_unlock_irqrestore(smmu-lock, flags);
return err;
 }
@@ -487,7 +487,7 @@ static int smmu_setup_regs(struct smmu_device *smmu)
smmu_write(smmu, val, SMMU_PTB_DATA);
 
list_for_each_entry(c, as-client, list)
-   __smmu_client_set_hwgrp(c, c-hwgrp, 1);
+   __smmu_client_set_swgroups(c, c-swgroups, 1);
}
 
smmu_write(smmu, smmu-translation_enable_0, SMMU_TRANSLATION_ENABLE_0);
@@ -815,7 +815,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain 
*domain,
return -ENOMEM;
 
client-as = as;
-   err = smmu_client_enable_hwgrp(client, client-hwgrp);
+   err = smmu_client_enable_swgroups(client, client-swgroups);
if (err)
return -EINVAL;
 
@@ -835,7 +835,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain 
*domain,
 * Reserve page zero for AVP vectors using a common dummy
 * page.
 */
-   if (test_bit(TEGRA_SWGROUP_AVPC, client-hwgrp)) {
+   if (test_bit(TEGRA_SWGROUP_AVPC, client-swgroups)) {
struct page *page;
 
page = as-smmu-avp_vector_page;
@@ -848,7 +848,7

[PATCHv5 7/9] iommu/tegra: smmu: allow duplicate ASID wirte

2013-11-19 Thread Hiroshi Doyu
The device, which belongs to the same ASID, can try to enable the same
ASID as the other swgroup devices. This should be allowed but just
skip the actual register write. If the write value is different, it
will return -EINVAL.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
v4:
This was the part of v3, which isn't used any more.
  [PATCHv3 10/19] iommu/tegra: smmu: Get nvidia,swgroups from DT
---
 drivers/iommu/tegra-smmu.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index e915201a..c2ed075 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -418,9 +418,13 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
offs = HWGRP_ASID_REG(i);
val = smmu_read(smmu, offs);
if (on) {
-   if (WARN_ON(val  mask))
-   goto err_hw_busy;
-   val |= mask;
+   if (val) {
+   if (WARN_ON(val != mask))
+   return -EINVAL;
+   goto skip;
+   }
+
+   val = mask;
memcpy(c-hwgrp, map, sizeof(u64));
} else {
WARN_ON((val  mask) == mask);
@@ -430,16 +434,8 @@ static int __smmu_client_set_hwgrp(struct smmu_client *c,
}
 
FLUSH_SMMU_REGS(smmu);
+skip:
return 0;
-
-err_hw_busy:
-   for_each_set_bit(i, map, TEGRA_SWGROUP_MAX) {
-   offs = HWGRP_ASID_REG(i);
-   val = smmu_read(smmu, offs);
-   val = ~mask;
-   smmu_write(smmu, val, offs);
-   }
-   return -EBUSY;
 }
 
 static int smmu_client_set_hwgrp(struct smmu_client *c,
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs

2013-11-19 Thread Hiroshi Doyu
Stephen Warren swar...@wwwdotorg.org wrote @ Tue, 19 Nov 2013 22:22:47 +0100:

 On 11/19/2013 05:03 AM, Hiroshi Doyu wrote:
  Hi Thierry,
  
  Thierry Reding thierry.red...@gmail.com wrote @ Tue, 19 Nov 2013 11:25:07 
  +0100:
  
  From earlier discussions I thought the goal was to actually defer this
  until all nodes referred to by the iommus property were actually
  registered. The above only checks that the phandles can be resolved to
  valid struct device_node:s. That doesn't mean that an actual IOMMU has
  been registered for it, only that the devices have been created.
  
  Currently bus-iommu_ops is set at the end of tegra_smmu_probe(). So
  if bus-iommu_ops is set, it means that an iommu instance is
  populated at that time.
 
 Yes, but that's the register bus, upon which the device is a client, not
 the bus upon which the device is a bus master. They aren't necessarily
 the same.
 
 There's no getting around the fact that, as Thierry said, you need to
 search for a registered IOMMU device for each phandle, and defer probe
 if any aren't registered yet.
 
 If we do that, then you shouldn't need to look at the value of
 dev-bus-iommu_ops at all; if all IOMMUs in the list were registered,
 then iommu_ops must have been set when (one of them) was registered, and
 if not, then it possibly wasn't, so defer probe.
 
 That way, this code won't have to change if the core IOMMU code gets
 extended to support multiple IOMMUs, devices mastering transactions onto
 buses other than their register bus, etc.

Does the above mean the following?

int of_iommu_attach(struct device *dev)
{
int i;
struct of_phandle_args args;

of_property_for_each_phandle_with_args(dev-of_node, iommus,
   #iommu-cells, i, args)
if (!args-np-dev-driver)
return -EPROBE_DEFER;
return 0;
}


args-np-dev-driver needs the following patch:

  http://lists.linuxfoundation.org/pipermail/iommu/2013-July/006023.html
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] fs: partitions: efi: Fix bound check

2013-11-19 Thread Hiroshi Doyu
Antti Miettinen amietti...@nvidia.com wrote @ Wed, 20 Nov 2013 08:18:50 +0100:

 On 20.11.2013 02:04, Andrew Morton wrote:
  On Fri, 15 Nov 2013 19:14:22 +0200 (EET) Antti P Miettinen
  amietti...@nvidia.com wrote:
 
Use ARRAY_SIZE instead of sizeof to get proper max for label
length.
   
Signed-off-by: Antti P Miettinen amietti...@nvidia.com
Reviewed-by: Hiroshi Doyu hd...@nvidia.com
Tested-by: Hiroshi Doyu hd...@nvidia.com
 
  When fixing a bug, please provide a description of the user-visible
  impact of that bug.  This is so that others can decide which kernel
  version(s) need the patch.
 
  Hiroshi Doyu tested this patch, so I assume there was some observable
  misbehaviour to test.  Please fully describe that.
 
 Since this is just a read out of bounds it's not that bad, but the 
 problem becomes user-visible e.g. if one tries to use 
 CONFIG_DEBUG_PAGEALLOC and CONFIG_DEBUG_RODATA, at least with some 
 enhancements from Hiroshi.

The above enhancement is almost ARCH_SUPPORTS_DEBUG_PAGEALLOC for ARM,
which could catch illegal memory access(read/write) with a page fault
although that enhancement itself needs some cleanups before being
upstreamed.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] ARM: dma-mapping: Drop GFP_COMP for DMA memory allocations

2013-10-16 Thread Hiroshi Doyu
arm_iommu_alloc_attrs wants to split pages after allocation in order
to reduce the memory footprint. This does not work well with GFP_COMP
pages, so drop this flag before allocation.

ref: ea2e7057c0234cfb8b09467d8f137760d371fc72:

ARM: 7172/1: dma: Drop GFP_COMP for DMA memory allocations

dma_alloc_coherent wants to split pages after allocation in order to
reduce the memory footprint. This does not work well with GFP_COMP
pages, so drop this flag before allocation.

Signed-off-by: Hiroshi Doyu 
---
 arch/arm/mm/dma-mapping.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f5e1a84..955dd3e 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1321,6 +1321,13 @@ static void *arm_iommu_alloc_attrs(struct device *dev, 
size_t size,
struct page **pages;
void *addr = NULL;
 
+   /* Following is a work-around (a.k.a. hack) to prevent pages
+* with __GFP_COMP being passed to split_page() which cannot
+* handle them.  The real problem is that this flag probably
+* should be 0 on ARM as it is not supported on this
+* platform--see CONFIG_HUGETLB_PAGE. */
+   gfp &= ~(__GFP_COMP);
+
*handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
 
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] ARM: dma-mapping: Drop GFP_COMP for DMA memory allocations

2013-10-16 Thread Hiroshi Doyu
arm_iommu_alloc_attrs wants to split pages after allocation in order
to reduce the memory footprint. This does not work well with GFP_COMP
pages, so drop this flag before allocation.

ref: ea2e7057c0234cfb8b09467d8f137760d371fc72:

ARM: 7172/1: dma: Drop GFP_COMP for DMA memory allocations

dma_alloc_coherent wants to split pages after allocation in order to
reduce the memory footprint. This does not work well with GFP_COMP
pages, so drop this flag before allocation.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 arch/arm/mm/dma-mapping.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f5e1a84..955dd3e 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1321,6 +1321,13 @@ static void *arm_iommu_alloc_attrs(struct device *dev, 
size_t size,
struct page **pages;
void *addr = NULL;
 
+   /* Following is a work-around (a.k.a. hack) to prevent pages
+* with __GFP_COMP being passed to split_page() which cannot
+* handle them.  The real problem is that this flag probably
+* should be 0 on ARM as it is not supported on this
+* platform--see CONFIG_HUGETLB_PAGE. */
+   gfp = ~(__GFP_COMP);
+
*handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
 
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ARM: dma-mapping: Get pages if the cpu_addr is out of atomic_pool

2013-06-16 Thread Hiroshi Doyu
YoungJun Cho  wrote @ Mon, 17 Jun 2013 06:18:52 +0200:

> In __iommu_get_pages(), the cpu_addr is checked wheather in
> atomic_pool range or not. So if the cpu_addr is in atomic_pool
> range, it does not need to check twice.
> 
> Signed-off-by: YoungJun Cho 
> Signed-off-by: Kyungmin Park 

Looks ok to me, at least.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ARM: dma-mapping: Get pages if the cpu_addr is out of atomic_pool

2013-06-16 Thread Hiroshi Doyu
YoungJun Cho yj44@samsung.com wrote @ Mon, 17 Jun 2013 06:18:52 +0200:

 In __iommu_get_pages(), the cpu_addr is checked wheather in
 atomic_pool range or not. So if the cpu_addr is in atomic_pool
 range, it does not need to check twice.
 
 Signed-off-by: YoungJun Cho yj44@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com

Looks ok to me, at least.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/1] amba: tegra-ahb: Fix build error w/ PM_SLEEP w/o PM_RUNTIME

2013-03-15 Thread Hiroshi Doyu
Stephen Warren  wrote @ Fri, 15 Mar 2013 06:23:38 +0100:

> On 03/14/2013 03:08 AM, Hiroshi Doyu wrote:
> > Make this depend on CONFIG_PM. This protection is necessary to not
> > cause any build errors with any combination of PM features especially
> > when supporting a new SoC where each PM features are being enabled
> > one-by-one during its depelopment.
> 
> Looks fine to me.
> 
> Acked-by: Stephen Warren 
> 
> I assume Russell will want this to go through his patch tracker.

FYI: Patch has been accepted as patch 7675/1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/1] amba: tegra-ahb: Fix build error w/ PM_SLEEP w/o PM_RUNTIME

2013-03-15 Thread Hiroshi Doyu
Stephen Warren swar...@wwwdotorg.org wrote @ Fri, 15 Mar 2013 06:23:38 +0100:

 On 03/14/2013 03:08 AM, Hiroshi Doyu wrote:
  Make this depend on CONFIG_PM. This protection is necessary to not
  cause any build errors with any combination of PM features especially
  when supporting a new SoC where each PM features are being enabled
  one-by-one during its depelopment.
 
 Looks fine to me.
 
 Acked-by: Stephen Warren swar...@nvidia.com
 
 I assume Russell will want this to go through his patch tracker.

FYI: Patch has been accepted as patch 7675/1
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] memory: tegra30: Fix build error w/o PM

2013-03-14 Thread Hiroshi Doyu
Make this depend on CONFIG_PM.

Signed-off-by: Hiroshi Doyu 
---
 drivers/memory/tegra30-mc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/memory/tegra30-mc.c b/drivers/memory/tegra30-mc.c
index 0b97598..f4ae074 100644
--- a/drivers/memory/tegra30-mc.c
+++ b/drivers/memory/tegra30-mc.c
@@ -268,6 +268,7 @@ static const u32 tegra30_mc_ctx[] = {
MC_INTMASK,
 };
 
+#ifdef CONFIG_PM
 static int tegra30_mc_suspend(struct device *dev)
 {
int i;
@@ -291,6 +292,7 @@ static int tegra30_mc_resume(struct device *dev)
mc_readl(mc, MC_TIMING_CONTROL);
return 0;
 }
+#endif
 
 static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm,
tegra30_mc_suspend,
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] amba: tegra-ahb: Fix build error w/ PM_SLEEP w/o PM_RUNTIME

2013-03-14 Thread Hiroshi Doyu
Make this depend on CONFIG_PM. This protection is necessary to not
cause any build errors with any combination of PM features especially
when supporting a new SoC where each PM features are being enabled
one-by-one during its depelopment.

Signed-off-by: Hiroshi Doyu 
Reported-by: Joseph Lo 
---
 drivers/amba/tegra-ahb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
index 093c435..1f44e56 100644
--- a/drivers/amba/tegra-ahb.c
+++ b/drivers/amba/tegra-ahb.c
@@ -158,7 +158,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn)
 EXPORT_SYMBOL(tegra_ahb_enable_smmu);
 #endif
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
 static int tegra_ahb_suspend(struct device *dev)
 {
int i;
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] amba: tegra-ahb: Fix build error w/ PM_SLEEP w/o PM_RUNTIME

2013-03-14 Thread Hiroshi Doyu
Make this depend on CONFIG_PM. This protection is necessary to not
cause any build errors with any combination of PM features especially
when supporting a new SoC where each PM features are being enabled
one-by-one during its depelopment.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
Reported-by: Joseph Lo jose...@nvidia.com
---
 drivers/amba/tegra-ahb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
index 093c435..1f44e56 100644
--- a/drivers/amba/tegra-ahb.c
+++ b/drivers/amba/tegra-ahb.c
@@ -158,7 +158,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn)
 EXPORT_SYMBOL(tegra_ahb_enable_smmu);
 #endif
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
 static int tegra_ahb_suspend(struct device *dev)
 {
int i;
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] memory: tegra30: Fix build error w/o PM

2013-03-14 Thread Hiroshi Doyu
Make this depend on CONFIG_PM.

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 drivers/memory/tegra30-mc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/memory/tegra30-mc.c b/drivers/memory/tegra30-mc.c
index 0b97598..f4ae074 100644
--- a/drivers/memory/tegra30-mc.c
+++ b/drivers/memory/tegra30-mc.c
@@ -268,6 +268,7 @@ static const u32 tegra30_mc_ctx[] = {
MC_INTMASK,
 };
 
+#ifdef CONFIG_PM
 static int tegra30_mc_suspend(struct device *dev)
 {
int i;
@@ -291,6 +292,7 @@ static int tegra30_mc_resume(struct device *dev)
mc_readl(mc, MC_TIMING_CONTROL);
return 0;
 }
+#endif
 
 static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm,
tegra30_mc_suspend,
-- 
1.8.1.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [REPOST PATCH 1/2] clk: add table lookup to mux

2013-02-26 Thread Hiroshi Doyu
On Fri, 22 Feb 2013 16:02:28 +0100
Peter De Schrijver  wrote:

> Add a table lookup feature to the mux clock. Also allow arbitrary masks
> instead of the width. This will be used by some clocks on Tegra114.
>
> Signed-off-by: Peter De Schrijver 

> @@ -42,7 +43,17 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
>* val = 0x4 really means "bit 2, index starts at bit 0"
>*/

> + if (mux->table) {
> + int i;
> +
> + for (i = 0; i < num_parents; i++)
> + if (mux->table[i] == val)
> + return i;
> + if (i == num_parents)
> + return -EINVAL;
> + }

Can't we just return after for-loop without checking i == num_parents as below?

+   for (i = 0; i < num_parents; i++) {
+   if (mux->table[i] == val)
+   return i;
+   }
+
+   return -EINVAL;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [REPOST PATCH 1/2] clk: add table lookup to mux

2013-02-26 Thread Hiroshi Doyu
On Fri, 22 Feb 2013 16:02:28 +0100
Peter De Schrijver pdeschrij...@nvidia.com wrote:

 Add a table lookup feature to the mux clock. Also allow arbitrary masks
 instead of the width. This will be used by some clocks on Tegra114.

 Signed-off-by: Peter De Schrijver pdeschrij...@nvidia.com

 @@ -42,7 +43,17 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
* val = 0x4 really means bit 2, index starts at bit 0
*/

 + if (mux-table) {
 + int i;
 +
 + for (i = 0; i  num_parents; i++)
 + if (mux-table[i] == val)
 + return i;
 + if (i == num_parents)
 + return -EINVAL;
 + }

Can't we just return after for-loop without checking i == num_parents as below?

+   for (i = 0; i  num_parents; i++) {
+   if (mux-table[i] == val)
+   return i;
+   }
+
+   return -EINVAL;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 2/2] clk: tegra20: Use DT defines for CLK ID

2013-02-15 Thread Hiroshi Doyu
To avoid the duplication of CLK ID defines both in boot/dts and kernel
source, use the one from the DT header file and get rid of own
definitions in kernel source.

Signed-off-by: Hiroshi Doyu 
---
 drivers/clk/tegra/clk-tegra20.c |  307 ++-
 1 file changed, 145 insertions(+), 162 deletions(-)

diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 847dabc..b2009c9 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -23,6 +23,8 @@
 #include 
 #include 
 
+#include 
+
 #include "clk.h"
 
 #define RST_DEVICES_L 0x004
@@ -201,21 +203,21 @@ static DEFINE_SPINLOCK(sysrate_lock);
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,  \
_regs, _clk_num, periph_clk_enb_refcnt, \
-   _gate_flags, _clk_id)
+   _gate_flags, TEGRA20_CLK_##_clk_id)
 
 #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset,
\
_clk_num, _regs, _gate_flags, _clk_id)  \
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\
_clk_num, periph_clk_enb_refcnt, _gate_flags,   \
-   _clk_id)
+   TEGRA20_CLK_##_clk_id)
 
 #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \
  _clk_num, _regs, _gate_flags, _clk_id)\
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, _regs, \
_clk_num, periph_clk_enb_refcnt, _gate_flags,   \
-   _clk_id)
+   TEGRA20_CLK_##_clk_id)
 
 #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
  _mux_shift, _mux_width, _clk_num, _regs,  \
@@ -223,28 +225,9 @@ static DEFINE_SPINLOCK(sysrate_lock);
TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \
_mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs,   \
_clk_num, periph_clk_enb_refcnt, _gate_flags,   \
-   _clk_id)
-
-/* IDs assigned here must be in sync with DT bindings definition
- * for Tegra20 clocks .
- */
-enum tegra20_clk {
-   cpu, ac97 = 3, rtc, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1,
-   ndflash, sdmmc1, sdmmc4, twc, pwm, i2s2, epp, gr2d = 21, usbd, isp,
-   gr3d, ide, disp2, disp1, host1x, vcp, cache2 = 31, mem, ahbdma, apbdma,
-   kbc = 36, stat_mon, pmc, fuse, kfuse, sbc1, nor, spi, sbc2, xio, sbc3,
-   dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2,
-   usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3,
-   pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb,
-   iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev1, cdev2,
-   uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve,
-   osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0,
-   pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1,
-   pll_p, pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_s, pll_u,
-   pll_x, cop, audio, pll_ref, twd, clk_max,
-};
+   TEGRA20_CLK_##_clk_id)
 
-static struct clk *clks[clk_max];
+static struct clk *clks[TEGRA20_CLK_MAX];
 static struct clk_onecell_data clk_data;
 
 static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
@@ -580,7 +563,7 @@ static void tegra20_pll_init(void)
0, _c_params, TEGRA_PLL_HAS_CPCON,
pll_c_freq_table, NULL);
clk_register_clkdev(clk, "pll_c", NULL);
-   clks[pll_c] = clk;
+   clks[TEGRA20_CLK_PLL_C] = clk;
 
/* PLLC_OUT1 */
clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
@@ -590,14 +573,14 @@ static void tegra20_pll_init(void)
clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT,
0, NULL);
clk_register_clkdev(clk, "pll_c_out1", NULL);
-   clks[pll_c_out1] = clk;
+   clks[TEGRA20_CLK_PLL_C_OUT1] = clk;
 
/* PLLP */
clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, NULL, 0,
21600, _p_params, TEGRA_PLL_FIXED |
TEGRA_PLL_HAS_CPCON, pll_p_freq_table, NULL);
clk_register_clkdev(clk, "pll_p", NULL);
-   clks[pll_p] = clk;
+   clks[TEGRA20_CLK_PLL_P] = clk;
 
/* PLLP_OUT1 */
clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p",
@@ -609,7 +592,7 @@ static vo

[RFC 1/2] Makefile: Add arch/arch/$(hdr-arch)/boot in header include path

2013-02-15 Thread Hiroshi Doyu
With a new feature dtc+cpp, DT can introduces some definitions in its
header files for their own. Some of those DT info can be used in
kernel source as well, instead of having the duplicate info in kernel
headers. This patch allows kernel source to include those DT
headers. For example:

+ #include 

Signed-off-by: Hiroshi Doyu 
---
 Makefile |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 0b4bf62..7f54cdb 100644
--- a/Makefile
+++ b/Makefile
@@ -364,7 +364,7 @@ LINUXINCLUDE:= \
-I$(srctree)/arch/$(hdr-arch)/include \
-Iarch/$(hdr-arch)/include/generated \
$(if $(KBUILD_SRC), -I$(srctree)/include) \
-   -Iinclude \
+   -Iinclude -Iarch/$(hdr-arch)/boot \
$(USERINCLUDE)
 
 KBUILD_CPPFLAGS := -D__KERNEL__
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[v3 6/6] ARM: tegra114: convert device tree files to use CLK defines

2013-02-15 Thread Hiroshi Doyu
Replace magic number in tegra_car:

-   clocks = <_car 28>;
+   clocks = <_car CLK_HOST1X>;

Signed-off-by: Hiroshi Doyu 
---
 .../bindings/clock/nvidia,tegra114-car.txt |  261 +---
 arch/arm/boot/dts/tegra114.dtsip   |   13 +-
 2 files changed, 8 insertions(+), 266 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt 
b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt
index 25e088d..c8956ed 100644
--- a/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt
+++ b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt
@@ -14,265 +14,6 @@ Required properties :
 - #clock-cells : Should be 1.
   In clock consumers, this cell represents the clock ID exposed by the CAR.
 
-  The first 160 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
-  registers. These IDs often match those in the CAR's RST_DEVICES registers,
-  but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
-  this case, those clocks are assigned IDs above 160 in order to highlight
-  this issue. Implementations that interpret these clock IDs as bit values
-  within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
-  explicitly handle these special cases.
-
-  The balance of the clocks controlled by the CAR are assigned IDs of 160 and
-  above.
-
-  0cpu
-  1unassigned
-  2unassigned
-  3unassigned
-  4rtc
-  5timer
-  6uarta
-  7unassigned  (register bit affects uartb and vfir)
-  8unassigned
-  9sdmmc2
-  10   unassigned  (register bit affects spdif_in and spdif_out)
-  11   i2s1
-  12   i2c1
-  13   ndflash
-  14   sdmmc1
-  15   sdmmc4
-  16   unassigned
-  17   pwm
-  18   i2s2
-  19   epp
-  20   unassigned  (register bit affects vi and vi_sensor)
-  21   2d
-  22   usbd
-  23   isp
-  24   3d
-  25   unassigned
-  26   disp2
-  27   disp1
-  28   host1x
-  29   vcp
-  30   i2s0
-  31   unassigned
-
-  32   unassigned
-  33   unassigned
-  34   apbdma
-  35   unassigned
-  36   kbc
-  37   unassigned
-  38   unassigned
-  39   unassigned  (register bit affects fuse and fuse_burn)
-  40   kfuse
-  41   sbc1
-  42   nor
-  43   unassigned
-  44   sbc2
-  45   unassigned
-  46   sbc3
-  47   i2c5
-  48   dsia
-  49   unassigned
-  50   mipi
-  51   hdmi
-  52   csi
-  53   unassigned
-  54   i2c2
-  55   uartc
-  56   mipi-cal
-  57   unassigned
-  58   usb2
-  59   usb3
-  60   msenc
-  61   vde
-  62   bsea
-  63   bsev
-
-  64   unassigned
-  65   uartd
-  66   unassigned
-  67   i2c3
-  68   sbc4
-  69   sdmmc3
-  70   unassigned
-  71   owr
-  72   afi
-  73   csite
-  74   unassigned
-  75   unassigned
-  76   la
-  77   trace
-  78   soc_therm
-  79   dtv
-  80   ndspeed
-  81   i2cslow
-  82   dsib
-  83   tsec
-  84   unassigned
-  85   unassigned
-  86   unassigned
-  87   unassigned
-  88   unassigned
-  89   xusb_host
-  90   unassigned
-  91   msenc
-  92   csus
-  93   unassigned
-  94   unassigned
-  95   unassigned  (bit affects xusb_dev and xusb_dev_src)
-
-  96   unassigned
-  97   unassigned
-  98   unassigned
-  99   mselect
-  100  tsensor
-  101  i2s3
-  102  i2s4
-  103  i2c4
-  104  sbc5
-  105  sbc6
-  106  d_audio
-  107  apbif
-  108  dam0
-  109  dam1
-  110  dam2
-  111  hda2codec_2x
-  112  unassigned
-  113  audio0_2x
-  114  audio1_2x
-  115  audio2_2x
-  116  audio3_2x
-  117  audio4_2x
-  118  spdif_2x
-  119  actmon
-  120  extern1
-  121  extern2
-  122  extern3
-  123  unassigned
-  124  unassigned
-  125  hda
-  126  unassigned
-  127  se
-
-  128  hda2hdmi
-  129  unassigned
-  130  unassigned
-  131  unassigned
-  132  unassigned
-  133  unassigned
-  134  unassigned
-  135  unassigned
-  136  unassigned
-  137  unassigned
-  138  unassigned
-  139  unassigned
-  140  unassigned
-  141  unassigned
-  142  unassigned
-  143  unassigned  (bit affects xusb_falcon_src, xusb_fs_src,
-xusb_host_src and xusb_ss_src)
-  144  cilab
-  145  cilcd
-  146  cile
-  147  dsialp
-  148  dsiblp
-  149  unassigned
-  150  dds
-  151  unassigned
-  152  dp2
-  153  amx
-  154  adx
-  155  unassigned
-  156  xusb_ss
-
-  192  uartb
-  193  vfir
-  194  spdif_in
-  195  spdif_out
-  196  vi
-  197  vi_sensor
-  198  fuse
-  199  fuse_burn
-  200  clk_32k
-  201  clk_m
-  202  clk_m_div2
-  203  clk_m_div4
-  204  pll_ref
-  205  pll_c
-  206  pll_c_out1
-  207  pll_c2
-  208  pll_c3
-  209  pll_m
-  210  pll_m_out1
-  211  pll_p
-  212  pll_p_out1
-  213  pll_p_out2
-  214  pll_p_out3
-  214  mipi_cal_fast
-  214  dsi1_fixed
-  214  dsi2_fixed
-  215  pll_p_out4
-  216  pll_a
-  217  pll_a_out1
-  218  pll_d
-  219  pll_d_out0
-  220  pll_d2
-  221  pll_d2_out0
-  222  pll_u
-  223  pll_u_480M
-  224  pll_u_60M
-  225  pll_u_48M
-  226  pll_u_12M
-  227  pll_x
-  228  pll_x_out0
-  229  pll_re_vco
-  230  pll_re_out
-  231  pll_e_out0
-  232  s

[v3 5/6] ARM: tegra114: create a DT header defining CLK IDs

2013-02-15 Thread Hiroshi Doyu
To replace magic number in tegra_car:

-   clocks = <_car 28>;
+   clocks = <_car CLK_HOST1X>;

Signed-off-by: Hiroshi Doyu 
---
 arch/arm/boot/dts/tegra114-car.h |  272 ++
 1 file changed, 272 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra114-car.h

diff --git a/arch/arm/boot/dts/tegra114-car.h b/arch/arm/boot/dts/tegra114-car.h
new file mode 100644
index 000..1fa425a
--- /dev/null
+++ b/arch/arm/boot/dts/tegra114-car.h
@@ -0,0 +1,272 @@
+/*
+ * This header provides constants for binding nvidia,tegra114-car.
+ *
+ * The first 160 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
+ * registers. These IDs often match those in the CAR's RST_DEVICES registers,
+ * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
+ * this case, those clocks are assigned IDs above 160 in order to highlight
+ * this issue. Implementations that interpret these clock IDs as bit values
+ * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
+ * explicitly handle these special cases.
+ *
+ * The balance of the clocks controlled by the CAR are assigned IDs of 160 and
+ * above.
+ */
+
+#ifndef _DT_TEGRA114_CAR_H
+#define _DT_TEGRA114_CAR_H
+
+#define TEGRA114_CLK_CPU 0
+/* 1 */
+/* 2 */
+/* 3 */
+#define TEGRA114_CLK_RTC 4
+#define TEGRA114_CLK_TIMER 5
+#define TEGRA114_CLK_UARTA 6
+/* 7 */ /* register bit affects uartb and vfir */
+/* 8 */
+#define TEGRA114_CLK_SDMMC2 9
+/* 10 */ /* register bit affects spdif_in and spdif_out */
+#define TEGRA114_CLK_I2S1 11
+#define TEGRA114_CLK_I2C1 12
+#define TEGRA114_CLK_NDFLASH 13
+#define TEGRA114_CLK_SDMMC1 14
+#define TEGRA114_CLK_SDMMC4 15
+/* 16 */
+#define TEGRA114_CLK_PWM 17
+#define TEGRA114_CLK_I2S2 18
+#define TEGRA114_CLK_EPP 19
+/* 20 */ /* register bit affects vi and vi_sensor */
+#define TEGRA114_CLK_GR_2D 21
+#define TEGRA114_CLK_USBD 22
+#define TEGRA114_CLK_ISP 23
+#define TEGRA114_CLK_GR_3D 24
+/* 25 */
+#define TEGRA114_CLK_DISP2 26
+#define TEGRA114_CLK_DISP1 27
+#define TEGRA114_CLK_HOST1X 28
+#define TEGRA114_CLK_VCP 29
+#define TEGRA114_CLK_I2S0 30
+/* 31 */
+
+/* 32 */
+/* 33 */
+#define TEGRA114_CLK_APBDMA 34
+/* 35 */
+#define TEGRA114_CLK_KBC 36
+/* 37 */
+/* 38 */
+/* 39 */
+#define TEGRA114_CLK_KFUSE 40
+#define TEGRA114_CLK_SBC1 41
+#define TEGRA114_CLK_NOR 42
+/* 43 */
+#define TEGRA114_CLK_SBC2 44
+/* 45 */
+#define TEGRA114_CLK_SBC3 46
+#define TEGRA114_CLK_I2C5 47
+#define TEGRA114_CLK_DSIA 48
+/* 49 */
+#define TEGRA114_CLK_MIPI 50
+#define TEGRA114_CLK_HDMI 51
+#define TEGRA114_CLK_CSI 52
+/* 53 */
+#define TEGRA114_CLK_I2C2 54
+#define TEGRA114_CLK_UARTC 55
+#define TEGRA114_CLK_MIPI_CAL 56
+/* 57 */
+#define TEGRA114_CLK_USB2 58
+#define TEGRA114_CLK_USB3 59
+/* 60 */
+#define TEGRA114_CLK_VDE 61
+#define TEGRA114_CLK_BSEA 62
+#define TEGRA114_CLK_BSEV 63
+
+/* 64 */
+#define TEGRA114_CLK_UARTD 65
+#define TEGRA114_CLK_UARTE 66
+#define TEGRA114_CLK_I2C3 67
+#define TEGRA114_CLK_SBC4 68
+#define TEGRA114_CLK_SDMMC3 69
+/* 70 */
+#define TEGRA114_CLK_OWR 71
+/* 72 */
+#define TEGRA114_CLK_CSITE 73
+/* 74 */
+/* 75 */
+#define TEGRA114_CLK_LA 76
+#define TEGRA114_CLK_TRACE 77
+#define TEGRA114_CLK_SOC_THERM 78
+#define TEGRA114_CLK_DTV 79
+#define TEGRA114_CLK_NDSPEED 80
+#define TEGRA114_CLK_I2CSLOW 81
+#define TEGRA114_CLK_DSIB 82
+#define TEGRA114_CLK_TSEC 83
+/* 84 */
+/* 85 */
+/* 86 */
+/* 87 */
+/* 88 */
+#define TEGRA114_CLK_XUSB_HOST 89
+/* 90 */
+#define TEGRA114_CLK_MSENC 91
+#define TEGRA114_CLK_CSUS 92
+/* 93 */
+/* 94 */
+/* 95 */ /* bit affects xusb_dev and xusb_dev_src */
+
+/* 96 */
+/* 97 */
+/* 98 */
+#define TEGRA114_CLK_MSELECT 99
+#define TEGRA114_CLK_TSENSOR 100
+#define TEGRA114_CLK_I2S3 101
+#define TEGRA114_CLK_I2S4 102
+#define TEGRA114_CLK_I2C4 103
+#define TEGRA114_CLK_SBC5 104
+#define TEGRA114_CLK_SBC6 105
+#define TEGRA114_CLK_D_AUDIO 106
+#define TEGRA114_CLK_APBIF 107
+#define TEGRA114_CLK_DAM0 108
+#define TEGRA114_CLK_DAM1 109
+#define TEGRA114_CLK_DAM2 110
+#define TEGRA114_CLK_HDA2CODEC_2X 111
+/* 112 */
+#define TEGRA114_CLK_AUDIO0_2X 113
+#define TEGRA114_CLK_AUDIO1_2X 114
+#define TEGRA114_CLK_AUDIO2_2X 115
+#define TEGRA114_CLK_AUDIO3_2X 116
+#define TEGRA114_CLK_AUDIO4_2X 117
+#define TEGRA114_CLK_SPDIF_2X 118
+#define TEGRA114_CLK_ACTMON 119
+#define TEGRA114_CLK_EXTERN1 120
+#define TEGRA114_CLK_EXTERN2 121
+#define TEGRA114_CLK_EXTERN3 122
+/* 123 */
+/* 124 */
+#define TEGRA114_CLK_HDA 125
+/* 126 */
+#define TEGRA114_CLK_SE 127
+
+#define TEGRA114_CLK_HDA2HDMI 128
+/* 129 */
+/* 130 */
+/* 131 */
+/* 132 */
+/* 133 */
+/* 134 */
+/* 135 */
+/* 136 */
+/* 137 */
+/* 138 */
+/* 139 */
+/* 140 */
+/* 141 */
+/* 142 */
+/* 143 */ /* bit affects xusb_falcon_src, xusb_fs_src, xusb_host_src and 
xusb_ss_src */
+#define TEGRA114_CLK_CILAB 144
+#define TEGRA114_CLK_CILCD 145
+#define TEGRA114_CLK_CILE 146
+#define TEGRA114_CLK_DSIALP 147
+#define TEGRA114_CLK_DSIBLP 148
+/* 149

[v3 4/6] ARM: tegra30: convert device tree files to use CLK defines

2013-02-15 Thread Hiroshi Doyu
Replace magic number in tegra_car:

-   clocks = <_car 28>;
+   clocks = <_car CLK_HOST1X>;

Signed-off-by: Hiroshi Doyu 
---
 .../bindings/clock/nvidia,tegra30-car.txt  |  207 +---
 arch/arm/boot/dts/tegra30.dtsip|   87 
 2 files changed, 45 insertions(+), 249 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt 
b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt
index f3da3be..ac5797b 100644
--- a/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt
+++ b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt
@@ -14,211 +14,6 @@ Required properties :
 - #clock-cells : Should be 1.
   In clock consumers, this cell represents the clock ID exposed by the CAR.
 
-  The first 130 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
-  registers. These IDs often match those in the CAR's RST_DEVICES registers,
-  but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
-  this case, those clocks are assigned IDs above 160 in order to highlight
-  this issue. Implementations that interpret these clock IDs as bit values
-  within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
-  explicitly handle these special cases.
-
-  The balance of the clocks controlled by the CAR are assigned IDs of 160 and
-  above.
-
-  0cpu
-  1unassigned
-  2unassigned
-  3unassigned
-  4rtc
-  5timer
-  6uarta
-  7unassigned  (register bit affects uartb and vfir)
-  8gpio
-  9sdmmc2
-  10   unassigned  (register bit affects spdif_in and spdif_out)
-  11   i2s1
-  12   i2c1
-  13   ndflash
-  14   sdmmc1
-  15   sdmmc4
-  16   unassigned
-  17   pwm
-  18   i2s2
-  19   epp
-  20   unassigned  (register bit affects vi and vi_sensor)
-  21   2d
-  22   usbd
-  23   isp
-  24   3d
-  25   unassigned
-  26   disp2
-  27   disp1
-  28   host1x
-  29   vcp
-  30   i2s0
-  31   cop_cache
-
-  32   mc
-  33   ahbdma
-  34   apbdma
-  35   unassigned
-  36   kbc
-  37   statmon
-  38   pmc
-  39   unassigned  (register bit affects fuse and fuse_burn)
-  40   kfuse
-  41   sbc1
-  42   nor
-  43   unassigned
-  44   sbc2
-  45   unassigned
-  46   sbc3
-  47   i2c5
-  48   dsia
-  49   unassigned  (register bit affects cve and tvo)
-  50   mipi
-  51   hdmi
-  52   csi
-  53   tvdac
-  54   i2c2
-  55   uartc
-  56   unassigned
-  57   emc
-  58   usb2
-  59   usb3
-  60   mpe
-  61   vde
-  62   bsea
-  63   bsev
-
-  64   speedo
-  65   uartd
-  66   uarte
-  67   i2c3
-  68   sbc4
-  69   sdmmc3
-  70   pcie
-  71   owr
-  72   afi
-  73   csite
-  74   pciex
-  75   avpucq
-  76   la
-  77   unassigned
-  78   unassigned
-  79   dtv
-  80   ndspeed
-  81   i2cslow
-  82   dsib
-  83   unassigned
-  84   irama
-  85   iramb
-  86   iramc
-  87   iramd
-  88   cram2
-  89   unassigned
-  90   audio_2xa/k/a audio_2x_sync_clk
-  91   unassigned
-  92   csus
-  93   cdev2
-  94   cdev1
-  95   unassigned
-
-  96   cpu_g
-  97   cpu_lp
-  98   3d2
-  99   mselect
-  100  tsensor
-  101  i2s3
-  102  i2s4
-  103  i2c4
-  104  sbc5
-  105  sbc6
-  106  d_audio
-  107  apbif
-  108  dam0
-  109  dam1
-  110  dam2
-  111  hda2codec_2x
-  112  atomics
-  113  audio0_2x
-  114  audio1_2x
-  115  audio2_2x
-  116  audio3_2x
-  117  audio4_2x
-  118  audio5_2x
-  119  actmon
-  120  extern1
-  121  extern2
-  122  extern3
-  123  sata_oob
-  124  sata
-  125  hda
-  127  se
-  128  hda2hdmi
-  129  sata_cold
-
-  160  uartb
-  161  vfir
-  162  spdif_in
-  163  spdif_out
-  164  vi
-  165  vi_sensor
-  166  fuse
-  167  fuse_burn
-  168  cve
-  169  tvo
-
-  170  clk_32k
-  171  clk_m
-  172  clk_m_div2
-  173  clk_m_div4
-  174  pll_ref
-  175  pll_c
-  176  pll_c_out1
-  177  pll_m
-  178  pll_m_out1
-  179  pll_p
-  180  pll_p_out1
-  181  pll_p_out2
-  182  pll_p_out3
-  183  pll_p_out4
-  184  pll_a
-  185  pll_a_out0
-  186  pll_d
-  187  pll_d_out0
-  188  pll_d2
-  189  pll_d2_out0
-  190  pll_u
-  191  pll_x
-  192  pll_x_out0
-  193  pll_e
-  194  spdif_in_sync
-  195  i2s0_sync
-  196  i2s1_sync
-  197  i2s2_sync
-  198  i2s3_sync
-  199  i2s4_sync
-  200  vimclk
-  201  audio0
-  202  audio1
-  203  audio2
-  204  audio3
-  205  audio4
-  206  audio5
-  207  clk_out_1 (extern1)
-  208  clk_out_2 (extern2)
-  209  clk_out_3 (extern3)
-  210  sclk
-  211  blink
-  212  cclk_g
-  213  cclk_lp
-  214  twd
-  215  cml0
-  216  cml1
-  217  hclk
-  218  pclk
-
 Example SoC include file:
 
 / {
@@ -229,7 +24,7 @@ Example SoC include file:
};
 
usb@c5004000 {
-   clocks = <_car 58>; /* usb2 */
+   clocks = <_car TEGRA30_CLK_USB2>;
};
 };
 
diff --git a/arch/arm/boot/dts/tegra30.dtsip b/arch/arm/boot/dts/tegra30.dtsip
index 0148459..3c87b71 100644
--- a/arch/arm/boot/dts/tegra30.dtsip
+++ b/arch/arm/boot/dts/tegra30.dtsip
@

[v3 3/6] ARM: tegra30: create a DT header defining CLK IDs

2013-02-15 Thread Hiroshi Doyu
To replace magic number in tegra_car:

-   clocks = <_car 28>;
+   clocks = <_car CLK_HOST1X>;

Signed-off-by: Hiroshi Doyu 
---
 arch/arm/boot/dts/tegra30-car.h |  218 +++
 1 file changed, 218 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra30-car.h

diff --git a/arch/arm/boot/dts/tegra30-car.h b/arch/arm/boot/dts/tegra30-car.h
new file mode 100644
index 000..75edf761
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-car.h
@@ -0,0 +1,218 @@
+/*
+ * This header provides constants for binding nvidia,tegra30-car.
+ *
+ * The first 130 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
+ * registers. These IDs often match those in the CAR's RST_DEVICES registers,
+ * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
+ * this case, those clocks are assigned IDs above 160 in order to highlight
+ * this issue. Implementations that interpret these clock IDs as bit values
+ * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
+ * explicitly handle these special cases.
+ *
+ * The balance of the clocks controlled by the CAR are assigned IDs of 160 and
+ * above.
+ */
+
+#ifndef _DT_TEGRA30_CAR_H
+#define _DT_TEGRA30_CAR_H
+
+#define TEGRA30_CLK_CPU 0
+/* 1 */
+/* 2 */
+/* 3 */
+#define TEGRA30_CLK_RTC 4
+#define TEGRA30_CLK_TIMER 5
+#define TEGRA30_CLK_UARTA 6
+/* 7 */ /* register bit affects uartb and vfir */
+#define TEGRA30_CLK_GPIO 8
+#define TEGRA30_CLK_SDMMC2 9
+/* 10 */ /* register bit affects spdif_in and spdif_out */
+#define TEGRA30_CLK_I2S1 11
+#define TEGRA30_CLK_I2C1 12
+#define TEGRA30_CLK_NDFLASH 13
+#define TEGRA30_CLK_SDMMC1 14
+#define TEGRA30_CLK_SDMMC4 15
+/* 16 */
+#define TEGRA30_CLK_PWM 17
+#define TEGRA30_CLK_I2S2 18
+#define TEGRA30_CLK_EPP 19
+/* 20 */ /* register bit affects vi and vi_sensor */
+#define TEGRA30_CLK_GR2D 21
+#define TEGRA30_CLK_USBD 22
+#define TEGRA30_CLK_ISP 23
+#define TEGRA30_CLK_GR3D 24
+/* 25 */
+#define TEGRA30_CLK_DISP2 26
+#define TEGRA30_CLK_DISP1 27
+#define TEGRA30_CLK_HOST1X 28
+#define TEGRA30_CLK_VCP 29
+#define TEGRA30_CLK_I2S0 30
+#define TEGRA30_CLK_COP_CACHE 31
+
+#define TEGRA30_CLK_MC 32
+#define TEGRA30_CLK_AHBDMA 33
+#define TEGRA30_CLK_APBDMA 34
+/* 35 */
+#define TEGRA30_CLK_KBC 36
+#define TEGRA30_CLK_STATMON 37
+#define TEGRA30_CLK_PMC 38
+/* 39 */ /* register bit affects fuse and fuse_burn */
+#define TEGRA30_CLK_KFUSE 40
+#define TEGRA30_CLK_SBC1 41
+#define TEGRA30_CLK_NOR 42
+/* 43 */
+#define TEGRA30_CLK_SBC2 44
+/* 45 */
+#define TEGRA30_CLK_SBC3 46
+#define TEGRA30_CLK_I2C5 47
+#define TEGRA30_CLK_DSIA 48
+/* 49 */ /* register bit affects cve and tvo */
+#define TEGRA30_CLK_MIPI 50
+#define TEGRA30_CLK_HDMI 51
+#define TEGRA30_CLK_CSI 52
+#define TEGRA30_CLK_TVDAC 53
+#define TEGRA30_CLK_I2C2 54
+#define TEGRA30_CLK_UARTC 55
+/* 56 */
+#define TEGRA30_CLK_EMC 57
+#define TEGRA30_CLK_USB2 58
+#define TEGRA30_CLK_USB3 59
+#define TEGRA30_CLK_MPE 60
+#define TEGRA30_CLK_VDE 61
+#define TEGRA30_CLK_BSEA 62
+#define TEGRA30_CLK_BSEV 63
+
+#define TEGRA30_CLK_SPEEDO 64
+#define TEGRA30_CLK_UARTD 65
+#define TEGRA30_CLK_UARTE 66
+#define TEGRA30_CLK_I2C3 67
+#define TEGRA30_CLK_SBC4 68
+#define TEGRA30_CLK_SDMMC3 69
+#define TEGRA30_CLK_PCIE 70
+#define TEGRA30_CLK_OWR 71
+#define TEGRA30_CLK_AFI 72
+#define TEGRA30_CLK_CSITE 73
+#define TEGRA30_CLK_PCIEX 74
+#define TEGRA30_CLK_AVPUCQ 75
+#define TEGRA30_CLK_LA 76
+/* 77 */
+/* 78 */
+#define TEGRA30_CLK_DTV 79
+#define TEGRA30_CLK_NDSPEED 80
+#define TEGRA30_CLK_I2CSLOW 81
+#define TEGRA30_CLK_DSIB 82
+/* 83 */
+#define TEGRA30_CLK_IRAMA 84
+#define TEGRA30_CLK_IRAMB 85
+#define TEGRA30_CLK_IRAMC 86
+#define TEGRA30_CLK_IRAMD 87
+#define TEGRA30_CLK_CRAM2 88
+/* 89 */
+#define TEGRA30_CLK_AUDIO_2X 90 /* audio_2x_sync_clk */
+/* 91 */
+#define TEGRA30_CLK_CSUS 92
+#define TEGRA30_CLK_CDEV1 93
+#define TEGRA30_CLK_CDEV2 94
+/* 95 */
+
+#define TEGRA30_CLK_CPU_G 96
+#define TEGRA30_CLK_CPU_LP 97
+#define TEGRA30_CLK_GR3D2 98
+#define TEGRA30_CLK_MSELECT 99
+#define TEGRA30_CLK_TSENSOR 100
+#define TEGRA30_CLK_I2S3 101
+#define TEGRA30_CLK_I2S4 102
+#define TEGRA30_CLK_I2C4 103
+#define TEGRA30_CLK_SBC5 104
+#define TEGRA30_CLK_SBC6 105
+#define TEGRA30_CLK_D_AUDIO 106
+#define TEGRA30_CLK_APBIF 107
+#define TEGRA30_CLK_DAM0 108
+#define TEGRA30_CLK_DAM1 109
+#define TEGRA30_CLK_DAM2 110
+#define TEGRA30_CLK_HDA2CODEC_2X 111
+#define TEGRA30_CLK_ATOMICS 112
+#define TEGRA30_CLK_AUDIO0_2X 113
+#define TEGRA30_CLK_AUDIO1_2X 114
+#define TEGRA30_CLK_AUDIO2_2X 115
+#define TEGRA30_CLK_AUDIO3_2X 116
+#define TEGRA30_CLK_AUDIO4_2X 117
+#define TEGRA30_CLK_SPDIF_2X 118
+#define TEGRA30_CLK_ACTMON 119
+#define TEGRA30_CLK_EXTERN1 120
+#define TEGRA30_CLK_EXTERN2 121
+#define TEGRA30_CLK_EXTERN3 122
+#define TEGRA30_CLK_SATA_OOB 123
+#define TEGRA30_CLK_SATA 124
+#define TEGRA30_CLK_HDA 125
+/* 126 */
+#define TEGRA30_CLK_SE 127
+
+#define TEGRA30_CLK_HDA2HDMI 

[v3 2/6] ARM: tegra20: convert device tree files to use CLK defines

2013-02-15 Thread Hiroshi Doyu
Replace magic number in tegra_car:

-   clocks = <_car 28>;
+   clocks = <_car CLK_HOST1X>;

Signed-off-by: Hiroshi Doyu 
---
 .../bindings/clock/nvidia,tegra20-car.txt  |  150 +---
 arch/arm/boot/dts/tegra20-paz00.dtsp   |2 +-
 arch/arm/boot/dts/tegra20.dtsip|   85 +--
 3 files changed, 45 insertions(+), 192 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt 
b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt
index 0921fac..18eda44 100644
--- a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt
+++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt
@@ -14,154 +14,6 @@ Required properties :
 - #clock-cells : Should be 1.
   In clock consumers, this cell represents the clock ID exposed by the CAR.
 
-  The first 96 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
-  registers. These IDs often match those in the CAR's RST_DEVICES registers,
-  but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
-  this case, those clocks are assigned IDs above 95 in order to highlight
-  this issue. Implementations that interpret these clock IDs as bit values
-  within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
-  explicitly handle these special cases.
-
-  The balance of the clocks controlled by the CAR are assigned IDs of 96 and
-  above.
-
-  0cpu
-  1unassigned
-  2unassigned
-  3ac97
-  4rtc
-  5tmr
-  6uart1
-  7unassigned  (register bit affects uart2 and vfir)
-  8gpio
-  9sdmmc2
-  10   unassigned  (register bit affects spdif_in and spdif_out)
-  11   i2s1
-  12   i2c1
-  13   ndflash
-  14   sdmmc1
-  15   sdmmc4
-  16   twc
-  17   pwm
-  18   i2s2
-  19   epp
-  20   unassigned  (register bit affects vi and vi_sensor)
-  21   2d
-  22   usbd
-  23   isp
-  24   3d
-  25   ide
-  26   disp2
-  27   disp1
-  28   host1x
-  29   vcp
-  30   unassigned
-  31   cache2
-
-  32   mem
-  33   ahbdma
-  34   apbdma
-  35   unassigned
-  36   kbc
-  37   stat_mon
-  38   pmc
-  39   fuse
-  40   kfuse
-  41   sbc1
-  42   snor
-  43   spi1
-  44   sbc2
-  45   xio
-  46   sbc3
-  47   dvc
-  48   dsi
-  49   unassigned  (register bit affects tvo and cve)
-  50   mipi
-  51   hdmi
-  52   csi
-  53   tvdac
-  54   i2c2
-  55   uart3
-  56   unassigned
-  57   emc
-  58   usb2
-  59   usb3
-  60   mpe
-  61   vde
-  62   bsea
-  63   bsev
-
-  64   speedo
-  65   uart4
-  66   uart5
-  67   i2c3
-  68   sbc4
-  69   sdmmc3
-  70   pcie
-  71   owr
-  72   afi
-  73   csite
-  74   unassigned
-  75   avpucq
-  76   la
-  77   unassigned
-  78   unassigned
-  79   unassigned
-  80   unassigned
-  81   unassigned
-  82   unassigned
-  83   unassigned
-  84   irama
-  85   iramb
-  86   iramc
-  87   iramd
-  88   cram2
-  89   audio_2xa/k/a audio_2x_sync_clk
-  90   clk_d
-  91   unassigned
-  92   sus
-  93   cdev1
-  94   cdev2
-  95   unassigned
-
-  96   uart2
-  97   vfir
-  98   spdif_in
-  99   spdif_out
-  100  vi
-  101  vi_sensor
-  102  tvo
-  103  cve
-  104  osc
-  105  clk_32k a/k/a clk_s
-  106  clk_m
-  107  sclk
-  108  cclk
-  109  hclk
-  110  pclk
-  111  blink
-  112  pll_a
-  113  pll_a_out0
-  114  pll_c
-  115  pll_c_out1
-  116  pll_d
-  117  pll_d_out0
-  118  pll_e
-  119  pll_m
-  120  pll_m_out1
-  121  pll_p
-  122  pll_p_out1
-  123  pll_p_out2
-  124  pll_p_out3
-  125  pll_p_out4
-  126  pll_s
-  127  pll_u
-  128  pll_x
-  129  cop a/k/a avp
-  130  audio   a/k/a audio_sync_clk
-  131  pll_ref
-  132  twd
-
 Example SoC include file:
 
 / {
@@ -172,7 +24,7 @@ Example SoC include file:
};
 
usb@c5004000 {
-   clocks = <_car 58>; /* usb2 */
+   clocks = <_car TEGRA20_CLK_USB2>;
};
 };
 
diff --git a/arch/arm/boot/dts/tegra20-paz00.dtsp 
b/arch/arm/boot/dts/tegra20-paz00.dtsp
index e63473b..3aa9f7a 100644
--- a/arch/arm/boot/dts/tegra20-paz00.dtsp
+++ b/arch/arm/boot/dts/tegra20-paz00.dtsp
@@ -277,7 +277,7 @@
clock-frequency = <8>;
request-gpios = < TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
slave-addr = <138>;
-   clocks = <_car 67>, <_car 124>;
+   clocks = <_car TEGRA20_CLK_I2C3>, <_car 
TEGRA20_CLK_PLL_P_OUT3>;
clock-names = "div-clk", "fast-clk";
};
 
diff --git a/arch/arm/boot/dts/tegra20.dtsip b/arch/arm/boot/dts/tegra20.dtsip
index 7b05f53..db118ec 100644
--- a/arch/arm/boot/dts/tegra20.dtsip
+++ b/arch/arm/boot/dts/tegra20.dtsip
@@ -1,6 +1,7 @@
 #include "skeleton.dtsi"
 #include "tegra-gpio.h"
 #include "arm-gic.h"
+#include "tegra20-car.h"
 
 / {
compatible = "nvidia,tegra20";
@@ -19,7 +20,7

[v3 1/6] ARM: tegra20: create a DT header defining CLK IDs

2013-02-15 Thread Hiroshi Doyu
To replace magic number in tegra_car:

-   clocks = <_car 28>;
+   clocks = <_car CLK_HOST1X>;

Signed-off-by: Hiroshi Doyu 
---
 arch/arm/boot/dts/tegra20-car.h |  158 +++
 1 file changed, 158 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra20-car.h

diff --git a/arch/arm/boot/dts/tegra20-car.h b/arch/arm/boot/dts/tegra20-car.h
new file mode 100644
index 000..5508b66
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-car.h
@@ -0,0 +1,158 @@
+/*
+ * This header provides constants for binding nvidia,tegra20-car.
+ *
+ * The first 96 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
+ * registers. These IDs often match those in the CAR's RST_DEVICES registers,
+ * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
+ * this case, those clocks are assigned IDs above 95 in order to highlight
+ * this issue. Implementations that interpret these clock IDs as bit values
+ * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
+ * explicitly handle these special cases.
+ *
+ * The balance of the clocks controlled by the CAR are assigned IDs of 96 and
+ * above.
+ */
+
+#ifndef _DT_TEGRA20_CAR_H
+#define _DT_TEGRA20_CAR_H
+
+#define TEGRA20_CLK_CPU 0
+/* 1 */
+/* 2 */
+#define TEGRA20_CLK_AC97 3
+#define TEGRA20_CLK_RTC 4
+#define TEGRA20_CLK_TIMER 5
+#define TEGRA20_CLK_UARTA 6
+/* 7 */ /* register bit affects uart2 and vfir */
+#define TEGRA20_CLK_GPIO 8
+#define TEGRA20_CLK_SDMMC2 9
+/* 10 */ /* register bit affects spdif_in and spdif_out */
+#define TEGRA20_CLK_I2S1 11
+#define TEGRA20_CLK_I2C1 12
+#define TEGRA20_CLK_NDFLASH 13
+#define TEGRA20_CLK_SDMMC1 14
+#define TEGRA20_CLK_SDMMC4 15
+#define TEGRA20_CLK_TWC 16
+#define TEGRA20_CLK_PWM 17
+#define TEGRA20_CLK_I2S2 18
+#define TEGRA20_CLK_EPP 19
+/* 20 */ /* register bit affects vi and vi_sensor */
+#define TEGRA20_CLK_GR2D 21
+#define TEGRA20_CLK_USBD 22
+#define TEGRA20_CLK_ISP 23
+#define TEGRA20_CLK_GR3D 24
+#define TEGRA20_CLK_IDE 25
+#define TEGRA20_CLK_DISP2 26
+#define TEGRA20_CLK_DISP1 27
+#define TEGRA20_CLK_HOST1X 28
+#define TEGRA20_CLK_VCP 29
+/* 30 */
+#define TEGRA20_CLK_CACHE2 31
+
+#define TEGRA20_CLK_MEM 32
+#define TEGRA20_CLK_AHBDMA 33
+#define TEGRA20_CLK_APBDMA 34
+/* 35 */
+#define TEGRA20_CLK_KBC 36
+#define TEGRA20_CLK_STAT_MON 37
+#define TEGRA20_CLK_PMC 38
+#define TEGRA20_CLK_FUSE 39
+#define TEGRA20_CLK_KFUSE 40
+#define TEGRA20_CLK_SBC1 41
+#define TEGRA20_CLK_NOR 42
+#define TEGRA20_CLK_SPI 43
+#define TEGRA20_CLK_SBC2 44
+#define TEGRA20_CLK_XIO 45
+#define TEGRA20_CLK_SBC3 46
+#define TEGRA20_CLK_DVC 47
+#define TEGRA20_CLK_DSI 48
+/* 49 */ /* register bit affects tvo and cve */
+#define TEGRA20_CLK_MIPI 50
+#define TEGRA20_CLK_HDMI 51
+#define TEGRA20_CLK_CSI 52
+#define TEGRA20_CLK_TVDAC 53
+#define TEGRA20_CLK_I2C2 54
+#define TEGRA20_CLK_UARTC 55
+/* 56 */
+#define TEGRA20_CLK_EMC 57
+#define TEGRA20_CLK_USB2 58
+#define TEGRA20_CLK_USB3 59
+#define TEGRA20_CLK_MPE 60
+#define TEGRA20_CLK_VDE 61
+#define TEGRA20_CLK_BSEA 62
+#define TEGRA20_CLK_BSEV 63
+
+#define TEGRA20_CLK_SPEEDO 64
+#define TEGRA20_CLK_UARTD 65
+#define TEGRA20_CLK_UARTE 66
+#define TEGRA20_CLK_I2C3 67
+#define TEGRA20_CLK_SBC4 68
+#define TEGRA20_CLK_SDMMC3 69
+#define TEGRA20_CLK_PEX 70
+#define TEGRA20_CLK_OWR 71
+#define TEGRA20_CLK_AFI 72
+#define TEGRA20_CLK_CSITE 73
+#define TEGRA20_CLK_PCIE_XCLK 74
+#define TEGRA20_CLK_AVPUCQ 75
+#define TEGRA20_CLK_LA 76
+/* 77 */
+/* 78 */
+/* 79 */
+/* 80 */
+/* 81 */
+/* 82 */
+/* 83 */
+#define TEGRA20_CLK_IRAMA 84
+#define TEGRA20_CLK_IRAMB 85
+#define TEGRA20_CLK_IRAMC 86
+#define TEGRA20_CLK_IRAMD 87
+#define TEGRA20_CLK_CRAM2 88
+#define TEGRA20_CLK_AUDIO_2X 89 /* audio_2x_sync_clk */
+#define TEGRA20_CLK_D 90
+/* 91 */
+#define TEGRA20_CLK_CSUS 92
+#define TEGRA20_CLK_CDEV1 93
+#define TEGRA20_CLK_CDEV2 94
+/* 95 */
+
+#define TEGRA20_CLK_UARTB 96
+#define TEGRA20_CLK_VFIR 97
+#define TEGRA20_CLK_SPDIF_IN 98
+#define TEGRA20_CLK_SPDIF_OUT 99
+#define TEGRA20_CLK_VI 100
+#define TEGRA20_CLK_VI_SENSOR 101
+#define TEGRA20_CLK_TVO 102
+#define TEGRA20_CLK_CVE 103
+#define TEGRA20_CLK_OSC 104
+#define TEGRA20_CLK_32K 105 /* clk_s */
+#define TEGRA20_CLK_M 106
+#define TEGRA20_CLK_SCLK 107
+#define TEGRA20_CLK_CCLK 108
+#define TEGRA20_CLK_HCLK 109
+#define TEGRA20_CLK_PCLK 110
+#define TEGRA20_CLK_BLINK 111
+#define TEGRA20_CLK_PLL_A 112
+#define TEGRA20_CLK_PLL_A_OUT0 113
+#define TEGRA20_CLK_PLL_C 114
+#define TEGRA20_CLK_PLL_C_OUT1 115
+#define TEGRA20_CLK_PLL_D 116
+#define TEGRA20_CLK_PLL_D_OUT0 117
+#define TEGRA20_CLK_PLL_E 118
+#define TEGRA20_CLK_PLL_M 119
+#define TEGRA20_CLK_PLL_M_OUT1 120
+#define TEGRA20_CLK_PLL_P 121
+#define TEGRA20_CLK_PLL_P_OUT1 122
+#define TEGRA20_CLK_PLL_P_OUT2 123
+#define TEGRA20_CLK_PLL_P_OUT3 124
+#define TEGRA20_CLK_PLL_P_OUT4 125
+#define TEGRA20_CLK_PLL_S 126
+#define TEGRA20_CLK_PLL_U 127
+
+#define TEGRA20_CLK_PLL_X 

[v3 0/6] ARM: tegra: convert device tree files to use CLK defines

2013-02-15 Thread Hiroshi Doyu
Hi,

With new dtc+cpp feature, we could get rid of magic numbers in dts*
files. This patch replaces CLK IDs.

We also plan to share those DT header files with kernel source
later[1].

This series depends on:
  [PATCH 0/9] ARM: tegra: use new dtc+cpp feature
  
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/149613.html

[5/6] and [6/6] depend on:
  [PATCH v6 00/10] Tegra114 clockframework
  
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/148895.html

v2:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/149816.html

v1:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/149672.html

[1] 
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/149804.html


Hiroshi Doyu (6):
  ARM: tegra20: create a DT header defining CLK IDs
  ARM: tegra20: convert device tree files to use CLK defines
  ARM: tegra30: create a DT header defining CLK IDs
  ARM: tegra30: convert device tree files to use CLK defines
  ARM: tegra114: create a DT header defining CLK IDs
  ARM: tegra114: convert device tree files to use CLK defines

 .../bindings/clock/nvidia,tegra114-car.txt |  261 +--
 .../bindings/clock/nvidia,tegra20-car.txt  |  150 +--
 .../bindings/clock/nvidia,tegra30-car.txt  |  207 +--
 arch/arm/boot/dts/tegra114-car.h   |  272 
 arch/arm/boot/dts/tegra114.dtsip   |   13 +-
 arch/arm/boot/dts/tegra20-car.h|  158 
 arch/arm/boot/dts/tegra20-paz00.dtsp   |2 +-
 arch/arm/boot/dts/tegra20.dtsip|   85 +++---
 arch/arm/boot/dts/tegra30-car.h|  218 
 arch/arm/boot/dts/tegra30.dtsip|   87 +++
 10 files changed, 746 insertions(+), 707 deletions(-)
 create mode 100644 arch/arm/boot/dts/tegra114-car.h
 create mode 100644 arch/arm/boot/dts/tegra20-car.h
 create mode 100644 arch/arm/boot/dts/tegra30-car.h

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[v3 0/6] ARM: tegra: convert device tree files to use CLK defines

2013-02-15 Thread Hiroshi Doyu
Hi,

With new dtc+cpp feature, we could get rid of magic numbers in dts*
files. This patch replaces CLK IDs.

We also plan to share those DT header files with kernel source
later[1].

This series depends on:
  [PATCH 0/9] ARM: tegra: use new dtc+cpp feature
  
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/149613.html

[5/6] and [6/6] depend on:
  [PATCH v6 00/10] Tegra114 clockframework
  
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/148895.html

v2:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/149816.html

v1:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/149672.html

[1] 
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/149804.html


Hiroshi Doyu (6):
  ARM: tegra20: create a DT header defining CLK IDs
  ARM: tegra20: convert device tree files to use CLK defines
  ARM: tegra30: create a DT header defining CLK IDs
  ARM: tegra30: convert device tree files to use CLK defines
  ARM: tegra114: create a DT header defining CLK IDs
  ARM: tegra114: convert device tree files to use CLK defines

 .../bindings/clock/nvidia,tegra114-car.txt |  261 +--
 .../bindings/clock/nvidia,tegra20-car.txt  |  150 +--
 .../bindings/clock/nvidia,tegra30-car.txt  |  207 +--
 arch/arm/boot/dts/tegra114-car.h   |  272 
 arch/arm/boot/dts/tegra114.dtsip   |   13 +-
 arch/arm/boot/dts/tegra20-car.h|  158 
 arch/arm/boot/dts/tegra20-paz00.dtsp   |2 +-
 arch/arm/boot/dts/tegra20.dtsip|   85 +++---
 arch/arm/boot/dts/tegra30-car.h|  218 
 arch/arm/boot/dts/tegra30.dtsip|   87 +++
 10 files changed, 746 insertions(+), 707 deletions(-)
 create mode 100644 arch/arm/boot/dts/tegra114-car.h
 create mode 100644 arch/arm/boot/dts/tegra20-car.h
 create mode 100644 arch/arm/boot/dts/tegra30-car.h

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[v3 1/6] ARM: tegra20: create a DT header defining CLK IDs

2013-02-15 Thread Hiroshi Doyu
To replace magic number in tegra_car:

-   clocks = tegra_car 28;
+   clocks = tegra_car CLK_HOST1X;

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 arch/arm/boot/dts/tegra20-car.h |  158 +++
 1 file changed, 158 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra20-car.h

diff --git a/arch/arm/boot/dts/tegra20-car.h b/arch/arm/boot/dts/tegra20-car.h
new file mode 100644
index 000..5508b66
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-car.h
@@ -0,0 +1,158 @@
+/*
+ * This header provides constants for binding nvidia,tegra20-car.
+ *
+ * The first 96 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
+ * registers. These IDs often match those in the CAR's RST_DEVICES registers,
+ * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
+ * this case, those clocks are assigned IDs above 95 in order to highlight
+ * this issue. Implementations that interpret these clock IDs as bit values
+ * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
+ * explicitly handle these special cases.
+ *
+ * The balance of the clocks controlled by the CAR are assigned IDs of 96 and
+ * above.
+ */
+
+#ifndef _DT_TEGRA20_CAR_H
+#define _DT_TEGRA20_CAR_H
+
+#define TEGRA20_CLK_CPU 0
+/* 1 */
+/* 2 */
+#define TEGRA20_CLK_AC97 3
+#define TEGRA20_CLK_RTC 4
+#define TEGRA20_CLK_TIMER 5
+#define TEGRA20_CLK_UARTA 6
+/* 7 */ /* register bit affects uart2 and vfir */
+#define TEGRA20_CLK_GPIO 8
+#define TEGRA20_CLK_SDMMC2 9
+/* 10 */ /* register bit affects spdif_in and spdif_out */
+#define TEGRA20_CLK_I2S1 11
+#define TEGRA20_CLK_I2C1 12
+#define TEGRA20_CLK_NDFLASH 13
+#define TEGRA20_CLK_SDMMC1 14
+#define TEGRA20_CLK_SDMMC4 15
+#define TEGRA20_CLK_TWC 16
+#define TEGRA20_CLK_PWM 17
+#define TEGRA20_CLK_I2S2 18
+#define TEGRA20_CLK_EPP 19
+/* 20 */ /* register bit affects vi and vi_sensor */
+#define TEGRA20_CLK_GR2D 21
+#define TEGRA20_CLK_USBD 22
+#define TEGRA20_CLK_ISP 23
+#define TEGRA20_CLK_GR3D 24
+#define TEGRA20_CLK_IDE 25
+#define TEGRA20_CLK_DISP2 26
+#define TEGRA20_CLK_DISP1 27
+#define TEGRA20_CLK_HOST1X 28
+#define TEGRA20_CLK_VCP 29
+/* 30 */
+#define TEGRA20_CLK_CACHE2 31
+
+#define TEGRA20_CLK_MEM 32
+#define TEGRA20_CLK_AHBDMA 33
+#define TEGRA20_CLK_APBDMA 34
+/* 35 */
+#define TEGRA20_CLK_KBC 36
+#define TEGRA20_CLK_STAT_MON 37
+#define TEGRA20_CLK_PMC 38
+#define TEGRA20_CLK_FUSE 39
+#define TEGRA20_CLK_KFUSE 40
+#define TEGRA20_CLK_SBC1 41
+#define TEGRA20_CLK_NOR 42
+#define TEGRA20_CLK_SPI 43
+#define TEGRA20_CLK_SBC2 44
+#define TEGRA20_CLK_XIO 45
+#define TEGRA20_CLK_SBC3 46
+#define TEGRA20_CLK_DVC 47
+#define TEGRA20_CLK_DSI 48
+/* 49 */ /* register bit affects tvo and cve */
+#define TEGRA20_CLK_MIPI 50
+#define TEGRA20_CLK_HDMI 51
+#define TEGRA20_CLK_CSI 52
+#define TEGRA20_CLK_TVDAC 53
+#define TEGRA20_CLK_I2C2 54
+#define TEGRA20_CLK_UARTC 55
+/* 56 */
+#define TEGRA20_CLK_EMC 57
+#define TEGRA20_CLK_USB2 58
+#define TEGRA20_CLK_USB3 59
+#define TEGRA20_CLK_MPE 60
+#define TEGRA20_CLK_VDE 61
+#define TEGRA20_CLK_BSEA 62
+#define TEGRA20_CLK_BSEV 63
+
+#define TEGRA20_CLK_SPEEDO 64
+#define TEGRA20_CLK_UARTD 65
+#define TEGRA20_CLK_UARTE 66
+#define TEGRA20_CLK_I2C3 67
+#define TEGRA20_CLK_SBC4 68
+#define TEGRA20_CLK_SDMMC3 69
+#define TEGRA20_CLK_PEX 70
+#define TEGRA20_CLK_OWR 71
+#define TEGRA20_CLK_AFI 72
+#define TEGRA20_CLK_CSITE 73
+#define TEGRA20_CLK_PCIE_XCLK 74
+#define TEGRA20_CLK_AVPUCQ 75
+#define TEGRA20_CLK_LA 76
+/* 77 */
+/* 78 */
+/* 79 */
+/* 80 */
+/* 81 */
+/* 82 */
+/* 83 */
+#define TEGRA20_CLK_IRAMA 84
+#define TEGRA20_CLK_IRAMB 85
+#define TEGRA20_CLK_IRAMC 86
+#define TEGRA20_CLK_IRAMD 87
+#define TEGRA20_CLK_CRAM2 88
+#define TEGRA20_CLK_AUDIO_2X 89 /* audio_2x_sync_clk */
+#define TEGRA20_CLK_D 90
+/* 91 */
+#define TEGRA20_CLK_CSUS 92
+#define TEGRA20_CLK_CDEV1 93
+#define TEGRA20_CLK_CDEV2 94
+/* 95 */
+
+#define TEGRA20_CLK_UARTB 96
+#define TEGRA20_CLK_VFIR 97
+#define TEGRA20_CLK_SPDIF_IN 98
+#define TEGRA20_CLK_SPDIF_OUT 99
+#define TEGRA20_CLK_VI 100
+#define TEGRA20_CLK_VI_SENSOR 101
+#define TEGRA20_CLK_TVO 102
+#define TEGRA20_CLK_CVE 103
+#define TEGRA20_CLK_OSC 104
+#define TEGRA20_CLK_32K 105 /* clk_s */
+#define TEGRA20_CLK_M 106
+#define TEGRA20_CLK_SCLK 107
+#define TEGRA20_CLK_CCLK 108
+#define TEGRA20_CLK_HCLK 109
+#define TEGRA20_CLK_PCLK 110
+#define TEGRA20_CLK_BLINK 111
+#define TEGRA20_CLK_PLL_A 112
+#define TEGRA20_CLK_PLL_A_OUT0 113
+#define TEGRA20_CLK_PLL_C 114
+#define TEGRA20_CLK_PLL_C_OUT1 115
+#define TEGRA20_CLK_PLL_D 116
+#define TEGRA20_CLK_PLL_D_OUT0 117
+#define TEGRA20_CLK_PLL_E 118
+#define TEGRA20_CLK_PLL_M 119
+#define TEGRA20_CLK_PLL_M_OUT1 120
+#define TEGRA20_CLK_PLL_P 121
+#define TEGRA20_CLK_PLL_P_OUT1 122
+#define TEGRA20_CLK_PLL_P_OUT2 123
+#define TEGRA20_CLK_PLL_P_OUT3 124
+#define TEGRA20_CLK_PLL_P_OUT4 125
+#define TEGRA20_CLK_PLL_S 126
+#define TEGRA20_CLK_PLL_U 127
+
+#define TEGRA20_CLK_PLL_X

[v3 3/6] ARM: tegra30: create a DT header defining CLK IDs

2013-02-15 Thread Hiroshi Doyu
To replace magic number in tegra_car:

-   clocks = tegra_car 28;
+   clocks = tegra_car CLK_HOST1X;

Signed-off-by: Hiroshi Doyu hd...@nvidia.com
---
 arch/arm/boot/dts/tegra30-car.h |  218 +++
 1 file changed, 218 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra30-car.h

diff --git a/arch/arm/boot/dts/tegra30-car.h b/arch/arm/boot/dts/tegra30-car.h
new file mode 100644
index 000..75edf761
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-car.h
@@ -0,0 +1,218 @@
+/*
+ * This header provides constants for binding nvidia,tegra30-car.
+ *
+ * The first 130 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
+ * registers. These IDs often match those in the CAR's RST_DEVICES registers,
+ * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
+ * this case, those clocks are assigned IDs above 160 in order to highlight
+ * this issue. Implementations that interpret these clock IDs as bit values
+ * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
+ * explicitly handle these special cases.
+ *
+ * The balance of the clocks controlled by the CAR are assigned IDs of 160 and
+ * above.
+ */
+
+#ifndef _DT_TEGRA30_CAR_H
+#define _DT_TEGRA30_CAR_H
+
+#define TEGRA30_CLK_CPU 0
+/* 1 */
+/* 2 */
+/* 3 */
+#define TEGRA30_CLK_RTC 4
+#define TEGRA30_CLK_TIMER 5
+#define TEGRA30_CLK_UARTA 6
+/* 7 */ /* register bit affects uartb and vfir */
+#define TEGRA30_CLK_GPIO 8
+#define TEGRA30_CLK_SDMMC2 9
+/* 10 */ /* register bit affects spdif_in and spdif_out */
+#define TEGRA30_CLK_I2S1 11
+#define TEGRA30_CLK_I2C1 12
+#define TEGRA30_CLK_NDFLASH 13
+#define TEGRA30_CLK_SDMMC1 14
+#define TEGRA30_CLK_SDMMC4 15
+/* 16 */
+#define TEGRA30_CLK_PWM 17
+#define TEGRA30_CLK_I2S2 18
+#define TEGRA30_CLK_EPP 19
+/* 20 */ /* register bit affects vi and vi_sensor */
+#define TEGRA30_CLK_GR2D 21
+#define TEGRA30_CLK_USBD 22
+#define TEGRA30_CLK_ISP 23
+#define TEGRA30_CLK_GR3D 24
+/* 25 */
+#define TEGRA30_CLK_DISP2 26
+#define TEGRA30_CLK_DISP1 27
+#define TEGRA30_CLK_HOST1X 28
+#define TEGRA30_CLK_VCP 29
+#define TEGRA30_CLK_I2S0 30
+#define TEGRA30_CLK_COP_CACHE 31
+
+#define TEGRA30_CLK_MC 32
+#define TEGRA30_CLK_AHBDMA 33
+#define TEGRA30_CLK_APBDMA 34
+/* 35 */
+#define TEGRA30_CLK_KBC 36
+#define TEGRA30_CLK_STATMON 37
+#define TEGRA30_CLK_PMC 38
+/* 39 */ /* register bit affects fuse and fuse_burn */
+#define TEGRA30_CLK_KFUSE 40
+#define TEGRA30_CLK_SBC1 41
+#define TEGRA30_CLK_NOR 42
+/* 43 */
+#define TEGRA30_CLK_SBC2 44
+/* 45 */
+#define TEGRA30_CLK_SBC3 46
+#define TEGRA30_CLK_I2C5 47
+#define TEGRA30_CLK_DSIA 48
+/* 49 */ /* register bit affects cve and tvo */
+#define TEGRA30_CLK_MIPI 50
+#define TEGRA30_CLK_HDMI 51
+#define TEGRA30_CLK_CSI 52
+#define TEGRA30_CLK_TVDAC 53
+#define TEGRA30_CLK_I2C2 54
+#define TEGRA30_CLK_UARTC 55
+/* 56 */
+#define TEGRA30_CLK_EMC 57
+#define TEGRA30_CLK_USB2 58
+#define TEGRA30_CLK_USB3 59
+#define TEGRA30_CLK_MPE 60
+#define TEGRA30_CLK_VDE 61
+#define TEGRA30_CLK_BSEA 62
+#define TEGRA30_CLK_BSEV 63
+
+#define TEGRA30_CLK_SPEEDO 64
+#define TEGRA30_CLK_UARTD 65
+#define TEGRA30_CLK_UARTE 66
+#define TEGRA30_CLK_I2C3 67
+#define TEGRA30_CLK_SBC4 68
+#define TEGRA30_CLK_SDMMC3 69
+#define TEGRA30_CLK_PCIE 70
+#define TEGRA30_CLK_OWR 71
+#define TEGRA30_CLK_AFI 72
+#define TEGRA30_CLK_CSITE 73
+#define TEGRA30_CLK_PCIEX 74
+#define TEGRA30_CLK_AVPUCQ 75
+#define TEGRA30_CLK_LA 76
+/* 77 */
+/* 78 */
+#define TEGRA30_CLK_DTV 79
+#define TEGRA30_CLK_NDSPEED 80
+#define TEGRA30_CLK_I2CSLOW 81
+#define TEGRA30_CLK_DSIB 82
+/* 83 */
+#define TEGRA30_CLK_IRAMA 84
+#define TEGRA30_CLK_IRAMB 85
+#define TEGRA30_CLK_IRAMC 86
+#define TEGRA30_CLK_IRAMD 87
+#define TEGRA30_CLK_CRAM2 88
+/* 89 */
+#define TEGRA30_CLK_AUDIO_2X 90 /* audio_2x_sync_clk */
+/* 91 */
+#define TEGRA30_CLK_CSUS 92
+#define TEGRA30_CLK_CDEV1 93
+#define TEGRA30_CLK_CDEV2 94
+/* 95 */
+
+#define TEGRA30_CLK_CPU_G 96
+#define TEGRA30_CLK_CPU_LP 97
+#define TEGRA30_CLK_GR3D2 98
+#define TEGRA30_CLK_MSELECT 99
+#define TEGRA30_CLK_TSENSOR 100
+#define TEGRA30_CLK_I2S3 101
+#define TEGRA30_CLK_I2S4 102
+#define TEGRA30_CLK_I2C4 103
+#define TEGRA30_CLK_SBC5 104
+#define TEGRA30_CLK_SBC6 105
+#define TEGRA30_CLK_D_AUDIO 106
+#define TEGRA30_CLK_APBIF 107
+#define TEGRA30_CLK_DAM0 108
+#define TEGRA30_CLK_DAM1 109
+#define TEGRA30_CLK_DAM2 110
+#define TEGRA30_CLK_HDA2CODEC_2X 111
+#define TEGRA30_CLK_ATOMICS 112
+#define TEGRA30_CLK_AUDIO0_2X 113
+#define TEGRA30_CLK_AUDIO1_2X 114
+#define TEGRA30_CLK_AUDIO2_2X 115
+#define TEGRA30_CLK_AUDIO3_2X 116
+#define TEGRA30_CLK_AUDIO4_2X 117
+#define TEGRA30_CLK_SPDIF_2X 118
+#define TEGRA30_CLK_ACTMON 119
+#define TEGRA30_CLK_EXTERN1 120
+#define TEGRA30_CLK_EXTERN2 121
+#define TEGRA30_CLK_EXTERN3 122
+#define TEGRA30_CLK_SATA_OOB 123
+#define TEGRA30_CLK_SATA 124
+#define TEGRA30_CLK_HDA 125
+/* 126 */
+#define TEGRA30_CLK_SE 127
+
+#define TEGRA30_CLK_HDA2HDMI 128

  1   2   3   4   5   >