Re: [PATCH v8 11/14] iommu/rockchip: Use OF_IOMMU to attach devices automatically

2018-03-26 Thread Daniel Kurtz
roup, >dev, NULL);
> +   iommu_device_link(>iommu, dev);

>  return 0;
>   }

> -static int rk_iommu_add_device(struct device *dev)
> +static void rk_iommu_remove_device(struct device *dev)
>   {
> -   struct iommu_group *group;
>  struct rk_iommu *iommu;
> -   int ret;
> -
> -   if (!rk_iommu_is_dev_iommu_master(dev))
> -   return -ENODEV;
> -
> -   group = iommu_group_get(dev);
> -   if (!group) {
> -   group = iommu_group_alloc();
> -   if (IS_ERR(group)) {
> -   dev_err(dev, "Failed to allocate IOMMU group\n");
> -   return PTR_ERR(group);
> -   }
> -   }
> -
> -   ret = iommu_group_add_device(group, dev);
> -   if (ret)
> -   goto err_put_group;
> -
> -   ret = rk_iommu_group_set_iommudata(group, dev);
> -   if (ret)
> -   goto err_remove_device;

>  iommu = rk_iommu_from_dev(dev);
> -   if (iommu)
> -   iommu_device_link(>iommu, dev);

> -   iommu_group_put(group);
> -
> -   return 0;
> -
> -err_remove_device:
> +   iommu_device_unlink(>iommu, dev);
>  iommu_group_remove_device(dev);
> -err_put_group:
> -   iommu_group_put(group);
> -   return ret;
>   }

> -static void rk_iommu_remove_device(struct device *dev)
> +static int rk_iommu_of_xlate(struct device *dev,
> +struct of_phandle_args *args)
>   {
> -   struct rk_iommu *iommu;
> +   struct platform_device *iommu_dev;
> +   struct rk_iommudata *data;

> -   if (!rk_iommu_is_dev_iommu_master(dev))
> -   return;
> +   data = devm_kzalloc(dma_dev, sizeof(*data), GFP_KERNEL);
> +   if (!data)
> +   return -ENOMEM;

> -   iommu = rk_iommu_from_dev(dev);
> -   if (iommu)
> -   iommu_device_unlink(>iommu, dev);
> +   iommu_dev = of_find_device_by_node(args->np);

> -   iommu_group_remove_device(dev);
> +   data->iommu = platform_get_drvdata(iommu_dev);
> +   dev->archdata.iommu = data;
> +
> +   of_dev_put(iommu_dev);
> +
> +   return 0;
>   }

>   static const struct iommu_ops rk_iommu_ops = {
> @@ -1106,7 +1045,9 @@ static const struct iommu_ops rk_iommu_ops = {
>  .add_device = rk_iommu_add_device,
>  .remove_device = rk_iommu_remove_device,
>  .iova_to_phys = rk_iommu_iova_to_phys,
> +   .device_group = generic_device_group,
>  .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
> +   .of_xlate = rk_iommu_of_xlate,
>   };

>   static int rk_iommu_probe(struct platform_device *pdev)
> @@ -1178,6 +1119,8 @@ static int rk_iommu_probe(struct platform_device
*pdev)
>  goto err_unprepare_clocks;

>  iommu_device_set_ops(>iommu, _iommu_ops);
> +   iommu_device_set_fwnode(>iommu, >of_node->fwnode);
> +
>  err = iommu_device_register(>iommu);
>  if (err)
>  goto err_remove_sysfs;
> @@ -1250,6 +1193,8 @@ static int __init rk_iommu_init(void)
>   }
>   subsys_initcall(rk_iommu_init);

> +IOMMU_OF_DECLARE(rk_iommu_of, "rockchip,iommu");
> +
>   MODULE_DESCRIPTION("IOMMU API for Rockchip");
>   MODULE_AUTHOR("Simon Xue <x...@rock-chips.com> and Daniel Kurtz <
djku...@chromium.org>");
>   MODULE_ALIAS("platform:rockchip-iommu");
> --
> 2.11.0
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/dma: Map scatterlists more parsimoniously

2016-02-01 Thread Daniel Kurtz
On Thu, Dec 10, 2015 at 8:49 PM, Daniel Kurtz <djku...@chromium.org> wrote:
> On Thu, Nov 12, 2015 at 1:47 PM, Yong Wu <yong...@mediatek.com> wrote:
>> On Wed, 2015-11-11 at 14:54 +, Robin Murphy wrote:
>>> Whilst blindly assuming the worst case for segment boundaries and
>>> aligning every segment individually is safe from the point of view
>>> of respecting the device's parameters, it is also undeniably a waste
>>> of IOVA space. Futhermore, the knock-on effects of more pages than
>
> "Furthermore" (checkpatch actually caught this, not me ;-) )
>
>>> necessary being exposed to device access, additional overhead in page
>>> table updates and TLB invalidations, etc., are even more undesirable.
>>>
>>> Improve matters by taking the actual boundary mask into account to
>>> actively detect the cases in which we really do need to adjust a
>>> segment, and avoid wasting space in the remainder.
>>>
>>> Signed-off-by: Robin Murphy <robin.mur...@arm.com>
>>> ---
>>>
>>> Hi all,
>>>
>>> I've given this some brief testing on Juno with USB and (via magic
>>> PCI hacks) SATA to confirm that all the +1s and -1s at least seem to
>>> be in the right places, so I'm throwing it out now for a head-start on
>>> checking whether it also helps the media folks with the v4l portability
>>> issues they're up against (I'm confident it should). If all goes well I
>>> figure I'll repost next week based on rc1 instead of some random local
>>> development commit.
>>>
>>> Robin.
>>
>> It works well on MT8173. containing
>> VDA/VEA(VideoDecodeAccelerator/VideoEncodeAccelerator) unit test.
>>
>> Tested-by: Yong Wu <yong...@mediatek.com>
>
> Reviewed-by: Daniel Kurtz <djku...@chromium.org>


Did this patch get lost?
Can we pick it up as a fix for v4.5?
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v8 5/5] dts: mt8173: Add iommu/smi nodes for mt8173

2016-01-28 Thread Daniel Kurtz via iommu
On Tue, Jan 26, 2016 at 12:12 PM, Yong Wu <yong...@mediatek.com> wrote:
> This patch add the iommu/larbs nodes for mt8173
>
> Signed-off-by: Yong Wu <yong...@mediatek.com>

Reviewed-by: Daniel Kurtz <djku...@chromium.org>
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v8 3/5] memory: mediatek: Add SMI driver

2016-01-28 Thread Daniel Kurtz via iommu
On Tue, Jan 26, 2016 at 12:12 PM, Yong Wu <yong...@mediatek.com> wrote:
> This patch add SMI(Smart Multimedia Interface) driver. This driver
> is responsible to enable/disable iommu and control the power domain
> and clocks of each local arbiter.
>
> Signed-off-by: Yong Wu <yong...@mediatek.com>
> Tested-by: Philipp Zabel <p.za...@pengutronix.de>

Reviewed-by: Daniel Kurtz <djku...@chromium.org>
Tested-by: Daniel Kurtz <djku...@chromium.org>

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


Re: [PATCH v6 3/5] memory: mediatek: Add SMI driver

2015-12-14 Thread Daniel Kurtz
Hi Yong,

On Tue, Dec 15, 2015 at 10:38 AM, Yong Wu  wrote:
> On Mon, 2015-12-14 at 19:18 +0100, Matthias Brugger wrote:
>> On Tuesday 08 Dec 2015 17:49:11 Yong Wu wrote:
>> > This patch add SMI(Smart Multimedia Interface) driver. This driver
>> > is responsible to enable/disable iommu and control the power domain
>> > and clocks of each local arbiter.
>> >
>> > Signed-off-by: Yong Wu 
>> > ---
>> >   Currently SMI offer mtk_smi_larb_get/put to enable the power-domain
>> > ,clocks and initialize the iommu configuration register for each a local
>> > arbiter, The reason is:
>> >   a) If a device would like to disable iommu, it also need call
>> > mtk_smi_larb_get/put to enable its power and clocks.
>> >   b) The iommu core don't support attach/detach a device within a
>> > iommu-group. So we cann't use iommu_attach_device(iommu_detach_device)
>> > instead
>> > of mtk_smi_larb_get/put.
>> >
> [..]
>> > +static int
>> > +mtk_smi_enable(struct device *dev, struct clk *apb, struct clk *smi)
>> > +{
>> > +   int ret;
>> > +
>> > +   ret = pm_runtime_get_sync(dev);
>> > +   if (ret < 0)
>> > +   return ret;
>> > +
>> > +   ret = clk_prepare_enable(apb);
>> > +   if (ret)
>> > +   goto err_put_pm;
>> > +
>> > +   ret = clk_prepare_enable(smi);
>> > +   if (ret)
>> > +   goto err_disable_apb;
>> > +
>> > +   return 0;
>> > +
>> > +err_disable_apb:
>> > +   clk_disable_unprepare(apb);
>> > +err_put_pm:
>> > +   pm_runtime_put_sync(dev);
>> > +   return ret;
>> > +}
>> > +
>> > +static void
>> > +mtk_smi_disable(struct device *dev, struct clk *apb, struct clk *smi)
>> > +{
>> > +   clk_disable_unprepare(smi);
>> > +   clk_disable_unprepare(apb);
>> > +   pm_runtime_put_sync(dev);
>> > +}
>> > +
>> > +static int mtk_smi_common_enable(struct mtk_smi_common *common)
>> > +{
>> > +   return mtk_smi_enable(common->dev, common->clk_apb, common->clk_smi);
>> > +}
>> > +
>> > +static void mtk_smi_common_disable(struct mtk_smi_common *common)
>> > +{
>> > +   mtk_smi_disable(common->dev, common->clk_apb, common->clk_smi);
>> > +}
>> > +
>> > +static int mtk_smi_larb_enable(struct mtk_smi_larb *larb)
>> > +{
>> > +   return mtk_smi_enable(larb->dev, larb->clk_apb, larb->clk_smi);
>> > +}
>> > +
>> > +static void mtk_smi_larb_disable(struct mtk_smi_larb *larb)
>> > +{
>> > +   mtk_smi_disable(larb->dev, larb->clk_apb, larb->clk_smi);
>> > +}
>> > +
>>
>> This is somehow over-engineered. Just use mtk_smi_enable and mtk_smi_disable
>> instead of adding an extra indirection.
>
> I added this only for readable...then the code in mtk_smi_larb_get below
> may looks simple and readable.
>
> If I use mtk_smi_enable/disable directly, the code will be like our
> v5[1], is it OK?
> Maybe I don't need these help function here, and only add more comment
> based on v5.
>
> [1]
> http://lists.linuxfoundation.org/pipermail/iommu/2015-October/014590.html

bike-shedding...

I like the fact that Yong is trying to make his helpers more type-safe.
But, perhaps we can rename "struct mtk_smi_common" as "struct
mtk_smi", and then make "struct mtk_smi_larb" contain a "struct
mtk_smi":

struct mtk_smi {
  struct device *dev;
  struct clk *clk_apb, *clk_smi;
}

struct mtk_smi_larb {
  struct mtk_smi;
  ...
}


Then, have:

int mtk_smi_enable(struct mtk_smi *smi)
{
  clk_enable(smi->clk_apb);
  ...
}

int mtk_smi_disable(struct mtk_smi *smi)
{
}

int mtk_smi_larb_get(struct device *larbdev)
{
  struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
  struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);

  mtk_smi_enable(common);
  mtk_smi_enable(>smi);
  ...
}

>>
>> > +int mtk_smi_larb_get(struct device *larbdev)
>> > +{
>> > +   struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
>> > +   struct mtk_smi_common *common = dev_get_drvdata(larb->smi_common_dev);
>> > +   int ret;
>> > +
>> > +   ret = mtk_smi_common_enable(common);
>> > +   if (ret)
>> > +   return ret;
>> > +
>> > +   ret = mtk_smi_larb_enable(larb);
>> > +   if (ret)
>> > +   goto err_put_smi;
>> > +
>> > +   /* Configure the iommu info */
>> > +   writel_relaxed(larb->mmu, larb->base + SMI_LARB_MMU_EN);

I think this should probably be writel() not writel_relaxed, since you
really do want the barrier to ensure all other register accesses have
completed before enabling the MMU.

>> > +
>> > +   return 0;
>> > +
>> > +err_put_smi:
>> > +   mtk_smi_common_disable(common);
>> > +   return ret;
>> > +}
>> > +
>> > +void mtk_smi_larb_put(struct device *larbdev)
>> > +{
>> > +   struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
>> > +   struct mtk_smi_common *common = dev_get_drvdata(larb->smi_common_dev);
>> > +
>> > +   writel_relaxed(0, larb->base + SMI_LARB_MMU_EN);
>> > +   mtk_smi_larb_disable(larb);
>> > +   mtk_smi_common_disable(common);
>> > +}
>> > +
>>
>> Looks strange that you just disable all MMUs while you only enable some of
>> them at runtime. Unfortunately the datasheet I have 

Re: [PATCH] iommu/dma: Map scatterlists more parsimoniously

2015-12-10 Thread Daniel Kurtz
On Thu, Nov 12, 2015 at 1:47 PM, Yong Wu <yong...@mediatek.com> wrote:
> On Wed, 2015-11-11 at 14:54 +, Robin Murphy wrote:
>> Whilst blindly assuming the worst case for segment boundaries and
>> aligning every segment individually is safe from the point of view
>> of respecting the device's parameters, it is also undeniably a waste
>> of IOVA space. Futhermore, the knock-on effects of more pages than

"Furthermore" (checkpatch actually caught this, not me ;-) )

>> necessary being exposed to device access, additional overhead in page
>> table updates and TLB invalidations, etc., are even more undesirable.
>>
>> Improve matters by taking the actual boundary mask into account to
>> actively detect the cases in which we really do need to adjust a
>> segment, and avoid wasting space in the remainder.
>>
>> Signed-off-by: Robin Murphy <robin.mur...@arm.com>
>> ---
>>
>> Hi all,
>>
>> I've given this some brief testing on Juno with USB and (via magic
>> PCI hacks) SATA to confirm that all the +1s and -1s at least seem to
>> be in the right places, so I'm throwing it out now for a head-start on
>> checking whether it also helps the media folks with the v4l portability
>> issues they're up against (I'm confident it should). If all goes well I
>> figure I'll repost next week based on rc1 instead of some random local
>> development commit.
>>
>> Robin.
>
> It works well on MT8173. containing
> VDA/VEA(VideoDecodeAccelerator/VideoEncodeAccelerator) unit test.
>
> Tested-by: Yong Wu <yong...@mediatek.com>

Reviewed-by: Daniel Kurtz <djku...@chromium.org>
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v6 1/3] iommu: Implement common IOMMU ops for DMA mapping

2015-11-02 Thread Daniel Kurtz
+Tomasz, so he can reply to the thread
+Marek and Russell as recommended by Tomasz

On Oct 30, 2015 22:27, "Robin Murphy" <robin.mur...@arm.com> wrote:
>
> Hi Dan,
>
> On 30/10/15 01:17, Daniel Kurtz wrote:
>>
>> +linux-media & VIDEOBUF2 FRAMEWORK maintainers since this is about the
>> v4l2-contig's usage of the DMA API.
>>
>> Hi Robin,
>>
>> On Tue, Oct 27, 2015 at 12:55 AM, Robin Murphy <robin.mur...@arm.com> wrote:
>>>
>>> On 26/10/15 13:44, Yong Wu wrote:
>>>>
>>>>
>>>> On Thu, 2015-10-01 at 20:13 +0100, Robin Murphy wrote:
>>>> [...]
>>>>>
>>>>>
>>>>> +/*
>>>>> + * The DMA API client is passing in a scatterlist which could describe
>>>>> + * any old buffer layout, but the IOMMU API requires everything to be
>>>>> + * aligned to IOMMU pages. Hence the need for this complicated bit of
>>>>> + * impedance-matching, to be able to hand off a suitably-aligned list,
>>>>> + * but still preserve the original offsets and sizes for the caller.
>>>>> + */
>>>>> +int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
>>>>> +   int nents, int prot)
>>>>> +{
>>>>> +   struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
>>>>> +   struct iova_domain *iovad = domain->iova_cookie;
>>>>> +   struct iova *iova;
>>>>> +   struct scatterlist *s, *prev = NULL;
>>>>> +   dma_addr_t dma_addr;
>>>>> +   size_t iova_len = 0;
>>>>> +   int i;
>>>>> +
>>>>> +   /*
>>>>> +* Work out how much IOVA space we need, and align the segments
>>>>> to
>>>>> +* IOVA granules for the IOMMU driver to handle. With some clever
>>>>> +* trickery we can modify the list in-place, but reversibly, by
>>>>> +* hiding the original data in the as-yet-unused DMA fields.
>>>>> +*/
>>>>> +   for_each_sg(sg, s, nents, i) {
>>>>> +   size_t s_offset = iova_offset(iovad, s->offset);
>>>>> +   size_t s_length = s->length;
>>>>> +
>>>>> +   sg_dma_address(s) = s->offset;
>>>>> +   sg_dma_len(s) = s_length;
>>>>> +   s->offset -= s_offset;
>>>>> +   s_length = iova_align(iovad, s_length + s_offset);
>>>>> +   s->length = s_length;
>>>>> +
>>>>> +   /*
>>>>> +* The simple way to avoid the rare case of a segment
>>>>> +* crossing the boundary mask is to pad the previous one
>>>>> +* to end at a naturally-aligned IOVA for this one's
>>>>> size,
>>>>> +* at the cost of potentially over-allocating a little.
>>>>> +*/
>>>>> +   if (prev) {
>>>>> +   size_t pad_len = roundup_pow_of_two(s_length);
>>>>> +
>>>>> +   pad_len = (pad_len - iova_len) & (pad_len - 1);
>>>>> +   prev->length += pad_len;
>>>>
>>>>
>>>>
>>>> Hi Robin,
>>>> While our v4l2 testing, It seems that we met a problem here.
>>>> Here we update prev->length again, Do we need update
>>>> sg_dma_len(prev) again too?
>>>>
>>>> Some function like vb2_dc_get_contiguous_size[1] always get
>>>> sg_dma_len(s) to compare instead of s->length. so it may break
>>>> unexpectedly while sg_dma_len(s) is not same with s->length.
>>>
>>>
>>>
>>> This is just tweaking the faked-up length that we hand off to iommu_map_sg()
>>> (see also the iova_align() above), to trick it into bumping this segment up
>>> to a suitable starting IOVA. The real length at this point is stashed in
>>> sg_dma_len(s), and will be copied back into s->length in __finalise_sg(), so
>>> both will hold the same true length once we return to the caller.
>>>
>>> Yes, it does mean that if you have a list where the segment lengths are page
>>> aligned but not monotonically decreasing, e.g. {64k, 16k, 64k}, then you'll
>>> still end up with a 

Re: [PATCH v6 1/3] iommu: Implement common IOMMU ops for DMA mapping

2015-10-29 Thread Daniel Kurtz
+linux-media & VIDEOBUF2 FRAMEWORK maintainers since this is about the
v4l2-contig's usage of the DMA API.

Hi Robin,

On Tue, Oct 27, 2015 at 12:55 AM, Robin Murphy  wrote:
> On 26/10/15 13:44, Yong Wu wrote:
>>
>> On Thu, 2015-10-01 at 20:13 +0100, Robin Murphy wrote:
>> [...]
>>>
>>> +/*
>>> + * The DMA API client is passing in a scatterlist which could describe
>>> + * any old buffer layout, but the IOMMU API requires everything to be
>>> + * aligned to IOMMU pages. Hence the need for this complicated bit of
>>> + * impedance-matching, to be able to hand off a suitably-aligned list,
>>> + * but still preserve the original offsets and sizes for the caller.
>>> + */
>>> +int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
>>> +   int nents, int prot)
>>> +{
>>> +   struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
>>> +   struct iova_domain *iovad = domain->iova_cookie;
>>> +   struct iova *iova;
>>> +   struct scatterlist *s, *prev = NULL;
>>> +   dma_addr_t dma_addr;
>>> +   size_t iova_len = 0;
>>> +   int i;
>>> +
>>> +   /*
>>> +* Work out how much IOVA space we need, and align the segments
>>> to
>>> +* IOVA granules for the IOMMU driver to handle. With some clever
>>> +* trickery we can modify the list in-place, but reversibly, by
>>> +* hiding the original data in the as-yet-unused DMA fields.
>>> +*/
>>> +   for_each_sg(sg, s, nents, i) {
>>> +   size_t s_offset = iova_offset(iovad, s->offset);
>>> +   size_t s_length = s->length;
>>> +
>>> +   sg_dma_address(s) = s->offset;
>>> +   sg_dma_len(s) = s_length;
>>> +   s->offset -= s_offset;
>>> +   s_length = iova_align(iovad, s_length + s_offset);
>>> +   s->length = s_length;
>>> +
>>> +   /*
>>> +* The simple way to avoid the rare case of a segment
>>> +* crossing the boundary mask is to pad the previous one
>>> +* to end at a naturally-aligned IOVA for this one's
>>> size,
>>> +* at the cost of potentially over-allocating a little.
>>> +*/
>>> +   if (prev) {
>>> +   size_t pad_len = roundup_pow_of_two(s_length);
>>> +
>>> +   pad_len = (pad_len - iova_len) & (pad_len - 1);
>>> +   prev->length += pad_len;
>>
>>
>> Hi Robin,
>>While our v4l2 testing, It seems that we met a problem here.
>>Here we update prev->length again, Do we need update
>> sg_dma_len(prev) again too?
>>
>>Some function like vb2_dc_get_contiguous_size[1] always get
>> sg_dma_len(s) to compare instead of s->length. so it may break
>> unexpectedly while sg_dma_len(s) is not same with s->length.
>
>
> This is just tweaking the faked-up length that we hand off to iommu_map_sg()
> (see also the iova_align() above), to trick it into bumping this segment up
> to a suitable starting IOVA. The real length at this point is stashed in
> sg_dma_len(s), and will be copied back into s->length in __finalise_sg(), so
> both will hold the same true length once we return to the caller.
>
> Yes, it does mean that if you have a list where the segment lengths are page
> aligned but not monotonically decreasing, e.g. {64k, 16k, 64k}, then you'll
> still end up with a gap between the second and third segments, but that's
> fine because the DMA API offers no guarantees about what the resulting DMA
> addresses will be (consider the no-IOMMU case where they would each just be
> "mapped" to their physical address). If that breaks v4l, then it's probably
> v4l's DMA API use that needs looking at (again).

Hmm, I thought the DMA API maps a (possibly) non-contiguous set of
memory pages into a contiguous block in device memory address space.
This would allow passing a dma mapped buffer to device dma using just
a device address and length.
IIUC, the change above breaks this model by inserting gaps in how the
buffer is mapped to device memory, such that the buffer is no longer
contiguous in dma address space.

Here is the code in question from
drivers/media/v4l2-core/videobuf2-dma-contig.c :

static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt)
{
struct scatterlist *s;
dma_addr_t expected = sg_dma_address(sgt->sgl);
unsigned int i;
unsigned long size = 0;

for_each_sg(sgt->sgl, s, sgt->nents, i) {
if (sg_dma_address(s) != expected)
break;
expected = sg_dma_address(s) + sg_dma_len(s);
size += sg_dma_len(s);
}
return size;
}


static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, enum dma_data_direction dma_dir)
{
struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
struct frame_vector *vec;

Re: [PATCH v5 2/3] arm64: Add IOMMU dma_ops

2015-09-22 Thread Daniel Kurtz via iommu
Hi Robin,

On Sat, Aug 1, 2015 at 1:18 AM, Robin Murphy  wrote:
> Taking some inspiration from the arch/arm code, implement the
> arch-specific side of the DMA mapping ops using the new IOMMU-DMA layer.
>
> Unfortunately the device setup code has to start out as a big ugly mess
> in order to work usefully right now, as 'proper' operation depends on
> changes to device probe and DMA configuration ordering, IOMMU groups for
> platform devices, and default domain support in arm/arm64 IOMMU drivers.
> The workarounds here need only exist until that work is finished.
>
> Signed-off-by: Robin Murphy 
> ---

[snip]

> +static void __iommu_sync_sg_for_cpu(struct device *dev,
> +   struct scatterlist *sgl, int nelems,
> +   enum dma_data_direction dir)
> +{
> +   struct scatterlist *sg;
> +   int i;
> +
> +   if (is_device_dma_coherent(dev))
> +   return;
> +
> +   for_each_sg(sgl, sg, nelems, i)
> +   __dma_unmap_area(sg_virt(sg), sg->length, dir);
> +}

In an earlier review [0], Marek asked you to change the loop in
__iommu_sync_sg_for_cpu loop() to loop over the virtual areas when
invalidating/cleaning memory ranges.

[0] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/328232.html

However, this changed the meaning of the 'nelems' argument from what
was for arm_iommu_sync_sg_for_cpu() in arch/arm/mm/dma-mapping.c:
 "number of buffers to sync (returned from dma_map_sg)"
to:
 "number of virtual areas to sync (same as was passed to dma_map_sg)"

This has caused some confusion by callers of dma_sync_sg_for_device()
that must work for both arm & arm64 as illustrated by [1].
[1] https://lkml.org/lkml/2015/9/21/250

Based on the implementation of debug_dma_sync_sg_for_cpu() in
lib/dma-debug.c, I think the arm interpretation of nelems (returned
from dma_map_sg) is correct.

Therefore, I think we need an outer iteration over dma chunks, and an
inner iteration that calls __dma_map_area() over the set virtual areas
that correspond to that dma chunk, both here and for
__iommu_sync_sg_for_device().  This will be complicated by the fact
that iommu pages could actually be smaller than PAGE_SIZE, and offset
within a single physical page.  Also, as an optimization, we would
want to combine contiguous virtual areas into a single call to
__dma_unmap_area().

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


Re: [PATCH v2] CHROMIUM: iommu: rockchip: Make sure that page table state is coherent

2015-04-23 Thread Daniel Kurtz
On Mon, Apr 20, 2015 at 7:43 PM, Tomasz Figa tf...@chromium.org wrote:
 To flush created mappings, current mapping code relies on the fact that
 during unmap the driver zaps every IOVA being unmapped and that it is
 enough to zap a single IOVA of page table to remove the entire page
 table from IOMMU cache. Based on these assumptions the driver was made to
 simply zap the first IOVA of the mapping being created. This is enough
 to invalidate first page table, which could be shared with another
 mapping (and thus could be already present in IOMMU cache), but
 unfortunately it does not do anything about the last page table that
 could be shared with other mappings as well.

 Moreover, the flushing is performed before page table contents are
 actually modified, so there is a race between the CPU updating the page
 tables and hardware that could be possibly running at the same time and
 triggering IOMMU look-ups, which could bring back the page tables back
 to the cache.

 To fix both issues, this patch makes the mapping code zap first and last
 (if they are different) IOVAs of new mapping after the page table is
 updated.

 Signed-off-by: Tomasz Figa tf...@chromium.org
 Reviewed-by: Daniel Kurtz djku...@chromium.org
 Tested-by: Heiko Stuebner he...@sntech.de

You probably want to remove the CHROMIUM:  label in the subject.
Other than that, this is still:
Reviewed-by: Daniel Kurtz djku...@chromium.org

 ---
  drivers/iommu/rockchip-iommu.c | 23 +--
  1 file changed, 17 insertions(+), 6 deletions(-)

 diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
 index 4015560..31004c0 100644
 --- a/drivers/iommu/rockchip-iommu.c
 +++ b/drivers/iommu/rockchip-iommu.c
 @@ -551,6 +551,15 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain 
 *rk_domain,
 spin_unlock_irqrestore(rk_domain-iommus_lock, flags);
  }

 +static void rk_iommu_zap_iova_first_last(struct rk_iommu_domain *rk_domain,
 +dma_addr_t iova, size_t size)
 +{
 +   rk_iommu_zap_iova(rk_domain, iova, SPAGE_SIZE);
 +   if (size  SPAGE_SIZE)
 +   rk_iommu_zap_iova(rk_domain, iova + size - SPAGE_SIZE,
 +   SPAGE_SIZE);
 +}
 +
  static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
   dma_addr_t iova)
  {
 @@ -575,12 +584,6 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain 
 *rk_domain,
 rk_table_flush(page_table, NUM_PT_ENTRIES);
 rk_table_flush(dte_addr, 1);

 -   /*
 -* Zap the first iova of newly allocated page table so iommu evicts
 -* old cached value of new dte from the iotlb.
 -*/
 -   rk_iommu_zap_iova(rk_domain, iova, SPAGE_SIZE);
 -
  done:
 pt_phys = rk_dte_pt_address(dte);
 return (u32 *)phys_to_virt(pt_phys);
 @@ -630,6 +633,14 @@ static int rk_iommu_map_iova(struct rk_iommu_domain 
 *rk_domain, u32 *pte_addr,

 rk_table_flush(pte_addr, pte_count);

 +   /*
 +* Zap the first and last iova to evict from iotlb any previously
 +* mapped cachelines holding stale values for its dte and pte.
 +* We only zap the first and last iova, since only they could have
 +* dte or pte shared with an existing mapping.
 +*/
 +   rk_iommu_zap_iova_first_last(rk_domain, iova, size);
 +
 return 0;
  unwind:
 /* Unmap the range of iovas that we just mapped */
 --
 2.2.0.rc0.207.ga3a616c

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


Re: [PATCH 1/5] soc: mediatek: Add SMI driver

2015-03-09 Thread Daniel Kurtz
Hi Yong,

On Fri, Mar 6, 2015 at 6:37 PM,  yong...@mediatek.com wrote:
 From: Yong Wu yong...@mediatek.com

 This patch add SMI(Smart Multimedia Interface) driver. This driver
 is responsible to enable/disable iommu and control the clocks of each
 local arbiter.

High-level:
Is there more to the smi (or smi-larb) driver, or is it always just a
1:1 wrapper for a particular m4u consumer?
In other words, instead of a separate driver, is it possible to move
this functionality into the m4u driver and/or the m4u consumers
directly?


 Signed-off-by: Yong Wu yong...@mediatek.com
 ---
  drivers/soc/mediatek/Kconfig  |   7 ++
  drivers/soc/mediatek/Makefile |   1 +
  drivers/soc/mediatek/mt8173-smi.c | 143 
 ++
  include/linux/mtk-smi.h   |  40 +++
  4 files changed, 191 insertions(+)
  create mode 100644 drivers/soc/mediatek/mt8173-smi.c
  create mode 100644 include/linux/mtk-smi.h

 diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
 index 729f93e..27fb26c 100644
 --- a/drivers/soc/mediatek/Kconfig
 +++ b/drivers/soc/mediatek/Kconfig
 @@ -20,3 +20,10 @@ config MT8173_PMIC_WRAP
   PMIC wrapper is a proprietary hardware in MT8173 to make
   communication protocols to access PMIC device.
   This driver implement access protocols for MT8173.
 +
 +config MTK_SMI
 +bool
 +   help
 + Smi help enable/disable iommu in mt8173 and control the
 + clock of each local arbiter.
 + It should be true while MTK_IOMMU enable.
 diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
 index 9b5709b..cdfe95c 100644
 --- a/drivers/soc/mediatek/Makefile
 +++ b/drivers/soc/mediatek/Makefile
 @@ -1,2 +1,3 @@
  obj-$(CONFIG_MT8135_PMIC_WRAP) += mt8135-pmic-wrap.o
  obj-$(CONFIG_MT8173_PMIC_WRAP) += mt8173-pmic-wrap.o
 +obj-$(CONFIG_MTK_SMI)   += mt8173-smi.o
 diff --git a/drivers/soc/mediatek/mt8173-smi.c 
 b/drivers/soc/mediatek/mt8173-smi.c
 new file mode 100644
 index 000..4e3fab9
 --- /dev/null
 +++ b/drivers/soc/mediatek/mt8173-smi.c
 @@ -0,0 +1,143 @@
 +/*
 + * Copyright (c) 2014-2015 MediaTek Inc.
 + * Author: Yong Wu yong...@mediatek.com
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + */
 +#include linux/io.h
 +#include linux/interrupt.h
 +#include linux/platform_device.h
 +#include linux/clk.h
 +#include linux/err.h
 +#include linux/mm.h
 +
 +#define SMI_LARB_MMU_EN (0xf00)
 +#define F_SMI_MMU_EN(port)  (1  (port))
 +
 +struct mtk_smi_larb {
 +   void __iomem *larb_base;
 +   struct clk *larb_clk[3];/* each larb has 3 clk at most */
 +};
 +
 +static const char * const mtk_smi_clk_name[] = {
 +   larb_sub0, larb_sub1, larb_sub2
 +};

The order and meaning of these clocks do not seem particularly important.
It seems a bit awkward to use these arbitrary names just so we can use
devm_clk_get() to get a variably sized array of clocks from .dts.
Can we eliminate the clock-names property, and just use a single
.dts proprety that lists an array of clocks?
Then you would also get an explicit clock count, and can remove the
NULL checking when iterating.
An example of a clock list without names is:

Clock list in .dts:
  https://lkml.org/lkml/2014/11/17/115
Filling in the clocks from .dts:
  https://lkml.org/lkml/2014/11/17/114

Unfortunately, those patches never made it out of list discussion into
a maintainer tree.

 +
 +static const struct of_device_id mtk_smi_of_ids[] = {
 +   { .compatible = mediatek,mt8173-smi-larb,
 +   },
 +   {}
 +};

I find it a bit redundant to call the struct mtk_smi_larb, and then
to prepend larb_ to all of the fields.
In fact this whole driver is a bit confusing because it isn't clear if
this is an smi driver (of which only larb control has been
implemented) or is this an smi_larb driver (and potentially there
are other smi drivers).

Perhaps we can just call this an smi_larb driver, rename this file
to mt8173-smi-larb.c, and then doing something like:

struct mtk_smi_larb {
  void __iomem *base;
  struct clk *clk[3];/* each smi_larb has at most 3 clocks */
};

static const struct of_device_id mtk_smi_larb_of_ids[] = {
   { .compatible = mediatek,mt8173-smi-larb },
   {}
};


 +
 +int mtk_smi_larb_get(struct platform_device *plarbdev)

Is there any reason to use struct platform_device here instead of
just struct device?

 +{
 +   struct mtk_smi_larb *larbpriv = dev_get_drvdata(plarbdev-dev);
 +   int i, ret = 0;
 +
 +   for (i = 0; i  

[PATCH v7 1/3] iommu/rockchip: rk3288 iommu driver

2014-11-02 Thread Daniel Kurtz
The rk3288 has several iommus.  Each iommu belongs to a single master
device.  There is one device (ISP) that has two slave iommus, but that
case is not yet supported by this driver.

At subsys init, the iommu driver registers itself as the iommu driver for
the platform bus.  The master devices find their slave iommus using the
iommus field in their devicetree description.  Since each slave iommu
belongs to exactly one master, their is no additional data needed at probe
to associate a slave with its master.

An iommu device's power domain, clock and irq are all shared with its
master device, and the master device must be careful to attach from the
iommu only after powering and clocking it (and leave it powered and
clocked before detaching).  Because their is no guarantee what the status
of the iommu is at probe, and since the driver does not even know if the
device is powered, we delay requesting its irq until the master device
attaches, at which point we have a guarantee that the device is powered
and clocked and we can reset it and disable its interrupt mask.

An iommu_domain describes a virtual iova address space.  Each iommu_domain
has a corresponding page table that lists the mappings from iova to
physical address.

For the rk3288 iommu, the page table has two levels:
 The Level 1 directory_table has 1024 4-byte dte entries.
 Each dte points to a level 2 page_table.
 Each level 2 page_table has 1024 4-byte pte entries.
 Each pte points to a 4 KiB page of memory.

An iommu_domain is created when a dma_iommu_mapping is created via
arm_iommu_create_mapping.  Master devices can then attach themselves to
this mapping (or attach the mapping to themselves?) by calling
arm_iommu_attach_device().  This in turn instructs the iommu driver to
write the page table's physical address into the slave iommu's Directory
Table Entry (DTE) register.

In fact multiple master devices, each with their own slave iommu device,
can all attach to the same mapping.  The iommus for these devices will
share the same iommu_domain and therefore point to the same page table.
Thus, the iommu domain maintains a list of iommu devices which are
attached.  This driver relies on the iommu core to ensure that all devices
have detached before destroying a domain.

v6: - add .add/remove_device() callbacks.
- parse platform_device device tree nodes for iommus property
- store platform device pointer as group iommudata
- Check for existence of iommu group instead of relying on a
  dev_get_drvdata() to return NULL for a NULL device.

v7: - fixup some strings.
- In rk_iommu_disable_paging() # and % were reversed.

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
Reviewed-by: Grant Grundler grund...@chromium.org
Reviewed-by: Stéphane Marchesin marc...@chromium.org
Tested-by: Heiko Stuebner he...@sntech.de
---
 drivers/iommu/Kconfig  |   12 +
 drivers/iommu/Makefile |1 +
 drivers/iommu/rockchip-iommu.c | 1038 
 3 files changed, 1051 insertions(+)
 create mode 100644 drivers/iommu/rockchip-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd51122..d0a1261 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG
 
  Say N unless you know you need this.
 
+config ROCKCHIP_IOMMU
+   bool Rockchip IOMMU Support
+   depends on ARCH_ROCKCHIP
+   select IOMMU_API
+   select ARM_DMA_USE_IOMMU
+   help
+ Support for IOMMUs found on Rockchip rk32xx SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+ Say Y here if you are using a Rockchip SoC that includes an IOMMU
+ device.
+
 config TEGRA_IOMMU_GART
bool Tegra GART IOMMU Support
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 16edef7..3e47ef3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
new file mode 100644
index 000..b2023af
--- /dev/null
+++ b/drivers/iommu/rockchip-iommu.c
@@ -0,0 +1,1038 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include asm/cacheflush.h
+#include asm/pgtable.h
+#include linux/compiler.h
+#include linux/delay.h
+#include linux

Re: [PATCH v6 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-28 Thread Daniel Kurtz
Heiko,

Does this version work for you on 3.18-rc1?
On Oct 27, 2014 8:44 PM, Daniel Kurtz djku...@chromium.org wrote:

 The rk3288 has several iommus.  Each iommu belongs to a single master
 device.  There is one device (ISP) that has two slave iommus, but that
 case is not yet supported by this driver.

 At subsys init, the iommu driver registers itself as the iommu driver for
 the platform bus.  The master devices find their slave iommus using the
 iommus field in their devicetree description.  Since each slave iommu
 belongs to exactly one master, their is no additional data needed at probe
 to associate a slave with its master.

 An iommu device's power domain, clock and irq are all shared with its
 master device, and the master device must be careful to attach from the
 iommu only after powering and clocking it (and leave it powered and
 clocked before detaching).  Because their is no guarantee what the status
 of the iommu is at probe, and since the driver does not even know if the
 device is powered, we delay requesting its irq until the master device
 attaches, at which point we have a guarantee that the device is powered
 and clocked and we can reset it and disable its interrupt mask.

 An iommu_domain describes a virtual iova address space.  Each iommu_domain
 has a corresponding page table that lists the mappings from iova to
 physical address.

 For the rk3288 iommu, the page table has two levels:
  The Level 1 directory_table has 1024 4-byte dte entries.
  Each dte points to a level 2 page_table.
  Each level 2 page_table has 1024 4-byte pte entries.
  Each pte points to a 4 KiB page of memory.

 An iommu_domain is created when a dma_iommu_mapping is created via
 arm_iommu_create_mapping.  Master devices can then attach themselves to
 this mapping (or attach the mapping to themselves?) by calling
 arm_iommu_attach_device().  This in turn instructs the iommu driver to
 write the page table's physical address into the slave iommu's Directory
 Table Entry (DTE) register.

 In fact multiple master devices, each with their own slave iommu device,
 can all attach to the same mapping.  The iommus for these devices will
 share the same iommu_domain and therefore point to the same page table.
 Thus, the iommu domain maintains a list of iommu devices which are
 attached.  This driver relies on the iommu core to ensure that all devices
 have detached before destroying a domain.

 Changes in v6:
   - add .add/remove_device() callbacks.
   - parse platform_device device tree nodes for iommus property
   - store platform device pointer as group iommudata
   - Check for existence of iommu group instead of relying on a
 dev_get_drvdata() to return NULL for a NULL device.

 Signed-off-by: Daniel Kurtz djku...@chromium.org
 Signed-off-by: Simon Xue x...@rock-chips.com
 Reviewed-by: Grant Grundler grund...@chromium.org
 Reviewed-by: Stéphane Marchesin marc...@chromium.org
 ---
  drivers/iommu/Kconfig  |   12 +
  drivers/iommu/Makefile |1 +
  drivers/iommu/rockchip-iommu.c | 1038
 
  3 files changed, 1051 insertions(+)
  create mode 100644 drivers/iommu/rockchip-iommu.c

 diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
 index dd51122..d0a1261 100644
 --- a/drivers/iommu/Kconfig
 +++ b/drivers/iommu/Kconfig
 @@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG

   Say N unless you know you need this.

 +config ROCKCHIP_IOMMU
 +   bool Rockchip IOMMU Support
 +   depends on ARCH_ROCKCHIP
 +   select IOMMU_API
 +   select ARM_DMA_USE_IOMMU
 +   help
 + Support for IOMMUs found on Rockchip rk32xx SOCs.
 + These IOMMUs allow virtualization of the address space used by
 most
 + cores within the multimedia subsystem.
 + Say Y here if you are using a Rockchip SoC that includes an IOMMU
 + device.
 +
  config TEGRA_IOMMU_GART
 bool Tegra GART IOMMU Support
 depends on ARCH_TEGRA_2x_SOC
 diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
 index 16edef7..3e47ef3 100644
 --- a/drivers/iommu/Makefile
 +++ b/drivers/iommu/Makefile
 @@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o
 irq_remapping.o
  obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
  obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
  obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
 +obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
  obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
  obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
  obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 diff --git a/drivers/iommu/rockchip-iommu.c
 b/drivers/iommu/rockchip-iommu.c
 new file mode 100644
 index 000..61d6f87
 --- /dev/null
 +++ b/drivers/iommu/rockchip-iommu.c
 @@ -0,0 +1,1038 @@
 +/*
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +
 +#include asm

Re: [PATCH v5 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-27 Thread Daniel Kurtz
On Mon, Oct 27, 2014 at 4:32 AM, Heiko Stübner he...@sntech.de wrote:
 Hi Daniel,

 Am Freitag, 24. Oktober 2014, 15:33:47 schrieb Daniel Kurtz:

 [...]

 +static int rk_iommu_attach_device(struct iommu_domain *domain,
 +   struct device *dev)
 +{
 + struct rk_iommu *iommu = dev_get_drvdata(dev-archdata.iommu);

 Here I get a null-ptr dereference [0] when using the iommu driver with the
 pending drm changes.

That's what I get for testing against a heavily modified v3.14-based kernel...

In v3.14, dev_get_drvdata() would happily return NULL if dev=NULL.
This feature was removed in v3.15 by this patch:

commit d4332013919aa87dbdede67d677e4cf2cd32e898
Author: Jean Delvare jdelv...@suse.de
Date:   Mon Apr 14 12:57:43 2014 +0200
driver core: dev_get_drvdata: Don't check for NULL dev


 + struct rk_iommu_domain *rk_domain = domain-priv;
 + unsigned long flags;
 + int ret;
 + phys_addr_t dte_addr;
 +
 + /*
 +  * Allow 'virtual devices' (e.g., drm) to attach to domain.
 +  * Such a device has a NULL archdata.iommu.
 +  */
 + if (!iommu)

 When the comment is correct, the code should probably do something like
 the following?

 if (!dev-archdata.iommu)
 return 0;

 iommu = dev_get_drvdata(dev-archdata.iommu);


Yes, that looks reasonable.


 + return 0;
 +
 + ret = rk_iommu_enable_stall(iommu);
 + if (ret)
 + return ret;
 +
 + ret = rk_iommu_force_reset(iommu);
 + if (ret)
 + return ret;
 +
 + iommu-domain = domain;
 +
 + ret = devm_request_irq(dev, iommu-irq, rk_iommu_irq,
 +IRQF_SHARED, dev_name(dev), iommu);
 + if (ret)
 + return ret;
 +
 + dte_addr = virt_to_phys(rk_domain-dt);
 + rk_iommu_write(iommu, RK_MMU_DTE_ADDR, dte_addr);
 + rk_iommu_command(iommu, RK_MMU_CMD_ZAP_CACHE);
 + rk_iommu_write(iommu, RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
 +
 + ret = rk_iommu_enable_paging(iommu);
 + if (ret)
 + return ret;
 +
 + spin_lock_irqsave(rk_domain-iommus_lock, flags);
 + list_add_tail(iommu-node, rk_domain-iommus);
 + spin_unlock_irqrestore(rk_domain-iommus_lock, flags);
 +
 + dev_info(dev, Attached to iommu domain\n);
 +
 + rk_iommu_disable_stall(iommu);
 +
 + return 0;
 +}

 [...]

 +
 +static struct platform_driver rk_iommu_driver = {
 + .probe = rk_iommu_probe,
 + .remove = rk_iommu_remove,
 + .driver = {
 +.name = rk_iommu,
 +.owner = THIS_MODULE,
 +.of_match_table = of_match_ptr(rk_iommu_dt_ids),
 + },
 +};
 +
 +static int __init rk_iommu_init(void)
 +{
 + int ret;
 +
 + ret = bus_set_iommu(platform_bus_type, rk_iommu_ops);

 on 3.18-rc1 this fails with -ENODEV, as add_iommu_group() is missing the
 add_device callback in rk_iommu_ops, so the iommu driver actually never
 gets registered.

v3.18-rc1 has patch [0] which changes
bus_set_iommu()-iommu_bus_init() to propagate the return value of
add_iommu_group(), whereas it was ignored in v3.17.

[0] commit fb3e306515ba6a012364b698b8ca71c337424ed3
Author: Mark Salter msal...@redhat.com
Date:   Sun Sep 21 13:58:24 2014 -0400

iommu: Fix bus notifier breakage


This patch made it mandatory that iommu drivers provide an add_group
callback.   I'm not exactly sure why.  Iommu groups do not seem to be
a good fit for the rockchip iommus, since the iommus are all 1:1 with
their master device.

The exynos add_group() is a possibility, however, it causes an
iommu_group to be allocated for every single platform_device, even if
they do not use an iommu.  This seems very wasteful.  Instead we can
check the device's dt node for an iommus field to a phandle with a
#iommu-cells field.

Also, perhaps the add_device() is a good place to stick other generic
device initialization code, which we are currently sprinkling in the
drivers of rockchip iommu masters (drm/codec).  Other drivers do this:
 * shmobile: sets up the iommu mapping with arm_iommu_create_mapping()
/ arm_iommu_attach_device()
 * omap: use of_parse_phandle()/of_find_device_by_node() to set a
master device's dev-archdata.iommu.

Or, perhaps we can just ignore iommu groups entirely and use dummy functions:
 static int rk_iommu_add_device(struct device *dev) { return 0; }
 static void rk_iommu_remove_device(struct device *dev) { }

I'll investigate more.

-Dan


 I've stolen the generic add_device and remove_device callbacks from the
 exynos iommu driver which makes the rk one at least probe.

 Can't say how far it goes, as I'm still struggling with the floating display
 subsystem parts. My current diff against this version can be found in [1].

 Maybe the issue I had in attach_device also simply resulted from this one,
 not sure right now.


 Heiko

 + if (ret)
 + return ret;
 +
 + return platform_driver_register(rk_iommu_driver);
 +}
 +static void __exit rk_iommu_exit(void

[PATCH v6 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-27 Thread Daniel Kurtz
The rk3288 has several iommus.  Each iommu belongs to a single master
device.  There is one device (ISP) that has two slave iommus, but that
case is not yet supported by this driver.

At subsys init, the iommu driver registers itself as the iommu driver for
the platform bus.  The master devices find their slave iommus using the
iommus field in their devicetree description.  Since each slave iommu
belongs to exactly one master, their is no additional data needed at probe
to associate a slave with its master.

An iommu device's power domain, clock and irq are all shared with its
master device, and the master device must be careful to attach from the
iommu only after powering and clocking it (and leave it powered and
clocked before detaching).  Because their is no guarantee what the status
of the iommu is at probe, and since the driver does not even know if the
device is powered, we delay requesting its irq until the master device
attaches, at which point we have a guarantee that the device is powered
and clocked and we can reset it and disable its interrupt mask.

An iommu_domain describes a virtual iova address space.  Each iommu_domain
has a corresponding page table that lists the mappings from iova to
physical address.

For the rk3288 iommu, the page table has two levels:
 The Level 1 directory_table has 1024 4-byte dte entries.
 Each dte points to a level 2 page_table.
 Each level 2 page_table has 1024 4-byte pte entries.
 Each pte points to a 4 KiB page of memory.

An iommu_domain is created when a dma_iommu_mapping is created via
arm_iommu_create_mapping.  Master devices can then attach themselves to
this mapping (or attach the mapping to themselves?) by calling
arm_iommu_attach_device().  This in turn instructs the iommu driver to
write the page table's physical address into the slave iommu's Directory
Table Entry (DTE) register.

In fact multiple master devices, each with their own slave iommu device,
can all attach to the same mapping.  The iommus for these devices will
share the same iommu_domain and therefore point to the same page table.
Thus, the iommu domain maintains a list of iommu devices which are
attached.  This driver relies on the iommu core to ensure that all devices
have detached before destroying a domain.

Changes in v6:
  - add .add/remove_device() callbacks.
  - parse platform_device device tree nodes for iommus property
  - store platform device pointer as group iommudata
  - Check for existence of iommu group instead of relying on a
dev_get_drvdata() to return NULL for a NULL device.

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
Reviewed-by: Grant Grundler grund...@chromium.org
Reviewed-by: Stéphane Marchesin marc...@chromium.org
---
 drivers/iommu/Kconfig  |   12 +
 drivers/iommu/Makefile |1 +
 drivers/iommu/rockchip-iommu.c | 1038 
 3 files changed, 1051 insertions(+)
 create mode 100644 drivers/iommu/rockchip-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd51122..d0a1261 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG
 
  Say N unless you know you need this.
 
+config ROCKCHIP_IOMMU
+   bool Rockchip IOMMU Support
+   depends on ARCH_ROCKCHIP
+   select IOMMU_API
+   select ARM_DMA_USE_IOMMU
+   help
+ Support for IOMMUs found on Rockchip rk32xx SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+ Say Y here if you are using a Rockchip SoC that includes an IOMMU
+ device.
+
 config TEGRA_IOMMU_GART
bool Tegra GART IOMMU Support
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 16edef7..3e47ef3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
new file mode 100644
index 000..61d6f87
--- /dev/null
+++ b/drivers/iommu/rockchip-iommu.c
@@ -0,0 +1,1038 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include asm/cacheflush.h
+#include asm/pgtable.h
+#include linux/compiler.h
+#include linux/delay.h
+#include linux/device.h
+#include linux/errno.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/iommu.h
+#include linux

[PATCH v5 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-24 Thread Daniel Kurtz
The rk3288 has several iommus.  Each iommu belongs to a single master
device.  There is one device (ISP) that has two slave iommus, but that
case is not yet supported by this driver.

At subsys init, the iommu driver registers itself as the iommu driver for
the platform bus.  The master devices find their slave iommus using the
iommus field in their devicetree description.  Since each slave iommu
belongs to exactly one master, their is no additional data needed at probe
to associate a slave with its master.

An iommu device's power domain, clock and irq are all shared with its
master device, and the master device must be careful to attach from the
iommu only after powering and clocking it (and leave it powered and
clocked before detaching).  Because their is no guarantee what the status
of the iommu is at probe, and since the driver does not even know if the
device is powered, we delay requesting its irq until the master device
attaches, at which point we have a guarantee that the device is powered
and clocked and we can reset it and disable its interrupt mask.

An iommu_domain describes a virtual iova address space.  Each iommu_domain
has a corresponding page table that lists the mappings from iova to
physical address.

For the rk3288 iommu, the page table has two levels:
 The Level 1 directory_table has 1024 4-byte dte entries.
 Each dte points to a level 2 page_table.
 Each level 2 page_table has 1024 4-byte pte entries.
 Each pte points to a 4 KiB page of memory.

An iommu_domain is created when a dma_iommu_mapping is created via
arm_iommu_create_mapping.  Master devices can then attach themselves to
this mapping (or attach the mapping to themselves?) by calling
arm_iommu_attach_device().  This in turn instructs the iommu driver to
write the page table's physical address into the slave iommu's Directory
Table Entry (DTE) register.

In fact multiple master devices, each with their own slave iommu device,
can all attach to the same mapping.  The iommus for these devices will
share the same iommu_domain and therefore point to the same page table.
Thus, the iommu domain maintains a list of iommu devices which are
attached.  This driver relies on the iommu core to ensure that all devices
have detached before destroying a domain.

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
Reviewed-by: Grant Grundler grund...@chromium.org
Reviewed-by: Stéphane Marchesin marc...@chromium.org
---
 drivers/iommu/Kconfig  |  12 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/rockchip-iommu.c | 922 +
 3 files changed, 935 insertions(+)
 create mode 100644 drivers/iommu/rockchip-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd51122..d0a1261 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG
 
  Say N unless you know you need this.
 
+config ROCKCHIP_IOMMU
+   bool Rockchip IOMMU Support
+   depends on ARCH_ROCKCHIP
+   select IOMMU_API
+   select ARM_DMA_USE_IOMMU
+   help
+ Support for IOMMUs found on Rockchip rk32xx SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+ Say Y here if you are using a Rockchip SoC that includes an IOMMU
+ device.
+
 config TEGRA_IOMMU_GART
bool Tegra GART IOMMU Support
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 16edef7..3e47ef3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
new file mode 100644
index 000..56ffb76
--- /dev/null
+++ b/drivers/iommu/rockchip-iommu.c
@@ -0,0 +1,922 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include asm/cacheflush.h
+#include asm/pgtable.h
+#include linux/compiler.h
+#include linux/delay.h
+#include linux/device.h
+#include linux/errno.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/iommu.h
+#include linux/jiffies.h
+#include linux/list.h
+#include linux/mm.h
+#include linux/module.h
+#include linux/of.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux/spinlock.h
+
+/** MMU register offsets */
+#define RK_MMU_DTE_ADDR0x00/* Directory table address

Re: [PATCH 0/3] Rockchip IOMMU driver and devicetree bindings

2014-10-23 Thread Daniel Kurtz
On Wed, Oct 22, 2014 at 11:20 PM, Joerg Roedel j...@8bytes.org wrote:

 On Wed, Oct 01, 2014 at 06:20:40PM +0800, Daniel Kurtz wrote:
  Add a driver and devicetree bindings for the IOMMU found in Rockchip
 RK3288
  SoCs.
 
  Daniel Kurtz (3):
iommu/rockchip: rk3288 iommu driver
dt-bindings: iommu: Add documentation for rockchip iommu
ARM: dts: rk3288: add VOP iommu nodes
 
   .../devicetree/bindings/iommu/rockchip,iommu.txt   |  26 +
   arch/arm/boot/dts/rk3288.dtsi  |  18 +
   drivers/iommu/Kconfig  |  11 +
   drivers/iommu/Makefile |   1 +
   drivers/iommu/rockchip-iommu.c | 924
 +
   5 files changed, 980 insertions(+)
   create mode 100644
 Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
   create mode 100644 drivers/iommu/rockchip-iommu.c

 Please make sure you also get Acks for the DT bindings. With that and
 the issue I mentioned in the other email fixed, I will apply these
 patches?


Hi Joerg,

Thanks for your reviews.
Can you help me get these DT bindings Acked?
AFAICT, the DT maintainers are CC'ed on this patch, I'm not sure what else
to do.

Thanks,
-Daniel




 Joerg


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

Re: [PATCH 0/3] Rockchip IOMMU driver and devicetree bindings

2014-10-23 Thread Daniel Kurtz
On Wed, Oct 22, 2014 at 11:20 PM, Joerg Roedel j...@8bytes.org wrote:
 On Wed, Oct 01, 2014 at 06:20:40PM +0800, Daniel Kurtz wrote:
 Add a driver and devicetree bindings for the IOMMU found in Rockchip RK3288
 SoCs.

 Daniel Kurtz (3):
   iommu/rockchip: rk3288 iommu driver
   dt-bindings: iommu: Add documentation for rockchip iommu
   ARM: dts: rk3288: add VOP iommu nodes

  .../devicetree/bindings/iommu/rockchip,iommu.txt   |  26 +
  arch/arm/boot/dts/rk3288.dtsi  |  18 +
  drivers/iommu/Kconfig  |  11 +
  drivers/iommu/Makefile |   1 +
  drivers/iommu/rockchip-iommu.c | 924 
 +
  5 files changed, 980 insertions(+)
  create mode 100644 
 Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
  create mode 100644 drivers/iommu/rockchip-iommu.c

 Please make sure you also get Acks for the DT bindings. With that and
 the issue I mentioned in the other email fixed, I will apply these
 patches?


 Joerg

Hi Joerg,

Thanks for your reviews.
Can you help get these DT bindings Acked?
AFAICT, the DT maintainers are CC'ed on this patch, I'm not sure what
else to do.

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


Re: [PATCH v5 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-16 Thread Daniel Kurtz
On Tue, Oct 14, 2014 at 4:02 PM, Daniel Kurtz djku...@chromium.org wrote:
 The rk3288 has several iommus.  Each iommu belongs to a single master
 device.  There is one device (ISP) that has two slave iommus, but that
 case is not yet supported by this driver.

 At subsys init, the iommu driver registers itself as the iommu driver for
 the platform bus.  The master devices find their slave iommus using the
 iommus field in their devicetree description.  Since each slave iommu
 belongs to exactly one master, their is no additional data needed at probe
 to associate a slave with its master.

 An iommu device's power domain, clock and irq are all shared with its
 master device, and the master device must be careful to attach from the
 iommu only after powering and clocking it (and leave it powered and
 clocked before detaching).  Because their is no guarantee what the status
 of the iommu is at probe, and since the driver does not even know if the
 device is powered, we delay requesting its irq until the master device
 attaches, at which point we have a guarantee that the device is powered
 and clocked and we can reset it and disable its interrupt mask.

 An iommu_domain describes a virtual iova address space.  Each iommu_domain
 has a corresponding page table that lists the mappings from iova to
 physical address.

 For the rk3288 iommu, the page table has two levels:
  The Level 1 directory_table has 1024 4-byte dte entries.
  Each dte points to a level 2 page_table.
  Each level 2 page_table has 1024 4-byte pte entries.
  Each pte points to a 4 KiB page of memory.

 An iommu_domain is created when a dma_iommu_mapping is created via
 arm_iommu_create_mapping.  Master devices can then attach themselves to
 this mapping (or attach the mapping to themselves?) by calling
 arm_iommu_attach_device().  This in turn instructs the iommu driver to
 write the page table's physical address into the slave iommu's Directory
 Table Entry (DTE) register.

 In fact multiple master devices, each with their own slave iommu device,
 can all attach to the same mapping.  The iommus for these devices will
 share the same iommu_domain and therefore point to the same page table.
 Thus, the iommu domain maintains a list of iommu devices which are
 attached.  This driver relies on the iommu core to ensure that all devices
 have detached before destroying a domain.

 Signed-off-by: Daniel Kurtz djku...@chromium.org
 Signed-off-by: Simon Xue x...@rock-chips.com
 Reviewed-by: Grant Grundler grund...@chromium.org
 Reviewed-by: Stéphane Marchesin marc...@chromium.org

Gentle ping.

Any more feedback on the rockchip iommu driver?

Thanks,
-Daniel

 ---
  drivers/iommu/Kconfig  |  12 +
  drivers/iommu/Makefile |   1 +
  drivers/iommu/rockchip-iommu.c | 924 
 +
  3 files changed, 937 insertions(+)
  create mode 100644 drivers/iommu/rockchip-iommu.c

 diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
 index dd51122..d0a1261 100644
 --- a/drivers/iommu/Kconfig
 +++ b/drivers/iommu/Kconfig
 @@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG

   Say N unless you know you need this.

 +config ROCKCHIP_IOMMU
 +   bool Rockchip IOMMU Support
 +   depends on ARCH_ROCKCHIP
 +   select IOMMU_API
 +   select ARM_DMA_USE_IOMMU
 +   help
 + Support for IOMMUs found on Rockchip rk32xx SOCs.
 + These IOMMUs allow virtualization of the address space used by most
 + cores within the multimedia subsystem.
 + Say Y here if you are using a Rockchip SoC that includes an IOMMU
 + device.
 +
  config TEGRA_IOMMU_GART
 bool Tegra GART IOMMU Support
 depends on ARCH_TEGRA_2x_SOC
 diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
 index 16edef7..3e47ef3 100644
 --- a/drivers/iommu/Makefile
 +++ b/drivers/iommu/Makefile
 @@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
 irq_remapping.o
  obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
  obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
  obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
 +obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
  obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
  obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
  obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
 new file mode 100644
 index 000..08e50fc
 --- /dev/null
 +++ b/drivers/iommu/rockchip-iommu.c
 @@ -0,0 +1,924 @@
 +/*
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +
 +#include asm/cacheflush.h
 +#include asm/pgtable.h
 +#include linux/compiler.h
 +#include linux/delay.h
 +#include linux/device.h
 +#include linux/errno.h
 +#include linux/interrupt.h
 +#include linux/io.h
 +#include linux/iommu.h
 +#include linux/jiffies.h
 +#include linux/list.h

[PATCH v4 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-14 Thread Daniel Kurtz
The rk3288 has several iommus.  Each iommu belongs to a single master
device.  There is one device (ISP) that has two slave iommus, but that
case is not yet supported by this driver.

At subsys init, the iommu driver registers itself as the iommu driver for
the platform bus.  The master devices find their slave iommus using the
iommus field in their devicetree description.  Since each slave iommu
belongs to exactly one master, their is no additional data needed at probe
to associate a slave with its master.

An iommu device's power domain, clock and irq are all shared with its
master device, and the master device must be careful to attach from the
iommu only after powering and clocking it (and leave it powered and
clocked before detaching).  Because their is no guarantee what the status
of the iommu is at probe, and since the driver does not even know if the
device is powered, we delay requesting its irq until the master device
attaches, at which point we have a guarantee that the device is powered
and clocked and we can reset it and disable its interrupt mask.

An iommu_domain describes a virtual iova address space.  Each iommu_domain
has a corresponding page table that lists the mappings from iova to
physical address.

For the rk3288 iommu, the page table has two levels:
 The Level 1 directory_table has 1024 4-byte dte entries.
 Each dte points to a level 2 page_table.
 Each level 2 page_table has 1024 4-byte pte entries.
 Each pte points to a 4 KiB page of memory.

An iommu_domain is created when a dma_iommu_mapping is created via
arm_iommu_create_mapping.  Master devices can then attach themselves to
this mapping (or attach the mapping to themselves?) by calling
arm_iommu_attach_device().  This in turn instructs the iommu driver to
write the page table's physical address into the slave iommu's Directory
Table Entry (DTE) register.

In fact multiple master devices, each with their own slave iommu device,
can all attach to the same mapping.  The iommus for these devices will
share the same iommu_domain and therefore point to the same page table.
Thus, the iommu domain maintains a list of iommu devices which are
attached.  This driver relies on the iommu core to ensure that all devices
have detached before destroying a domain.

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
Reviewed-by: Grant Grundler grund...@chromium.org
Reviewed-by: Stéphane Marchesin marc...@chromium.org
---
 drivers/iommu/Kconfig  |  12 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/rockchip-iommu.c | 924 +
 3 files changed, 937 insertions(+)
 create mode 100644 drivers/iommu/rockchip-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd51122..d0a1261 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG
 
  Say N unless you know you need this.
 
+config ROCKCHIP_IOMMU
+   bool Rockchip IOMMU Support
+   depends on ARCH_ROCKCHIP
+   select IOMMU_API
+   select ARM_DMA_USE_IOMMU
+   help
+ Support for IOMMUs found on Rockchip rk32xx SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+ Say Y here if you are using a Rockchip SoC that includes an IOMMU
+ device.
+
 config TEGRA_IOMMU_GART
bool Tegra GART IOMMU Support
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 16edef7..3e47ef3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
new file mode 100644
index 000..08e50fc
--- /dev/null
+++ b/drivers/iommu/rockchip-iommu.c
@@ -0,0 +1,924 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include asm/cacheflush.h
+#include asm/pgtable.h
+#include linux/compiler.h
+#include linux/delay.h
+#include linux/device.h
+#include linux/errno.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/iommu.h
+#include linux/jiffies.h
+#include linux/list.h
+#include linux/mm.h
+#include linux/module.h
+#include linux/of.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux/spinlock.h
+
+/** MMU register offsets */
+#define RK_MMU_DTE_ADDR0x00/* Directory table address

[PATCH v5 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-14 Thread Daniel Kurtz
The rk3288 has several iommus.  Each iommu belongs to a single master
device.  There is one device (ISP) that has two slave iommus, but that
case is not yet supported by this driver.

At subsys init, the iommu driver registers itself as the iommu driver for
the platform bus.  The master devices find their slave iommus using the
iommus field in their devicetree description.  Since each slave iommu
belongs to exactly one master, their is no additional data needed at probe
to associate a slave with its master.

An iommu device's power domain, clock and irq are all shared with its
master device, and the master device must be careful to attach from the
iommu only after powering and clocking it (and leave it powered and
clocked before detaching).  Because their is no guarantee what the status
of the iommu is at probe, and since the driver does not even know if the
device is powered, we delay requesting its irq until the master device
attaches, at which point we have a guarantee that the device is powered
and clocked and we can reset it and disable its interrupt mask.

An iommu_domain describes a virtual iova address space.  Each iommu_domain
has a corresponding page table that lists the mappings from iova to
physical address.

For the rk3288 iommu, the page table has two levels:
 The Level 1 directory_table has 1024 4-byte dte entries.
 Each dte points to a level 2 page_table.
 Each level 2 page_table has 1024 4-byte pte entries.
 Each pte points to a 4 KiB page of memory.

An iommu_domain is created when a dma_iommu_mapping is created via
arm_iommu_create_mapping.  Master devices can then attach themselves to
this mapping (or attach the mapping to themselves?) by calling
arm_iommu_attach_device().  This in turn instructs the iommu driver to
write the page table's physical address into the slave iommu's Directory
Table Entry (DTE) register.

In fact multiple master devices, each with their own slave iommu device,
can all attach to the same mapping.  The iommus for these devices will
share the same iommu_domain and therefore point to the same page table.
Thus, the iommu domain maintains a list of iommu devices which are
attached.  This driver relies on the iommu core to ensure that all devices
have detached before destroying a domain.

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
Reviewed-by: Grant Grundler grund...@chromium.org
Reviewed-by: Stéphane Marchesin marc...@chromium.org
---
 drivers/iommu/Kconfig  |  12 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/rockchip-iommu.c | 924 +
 3 files changed, 937 insertions(+)
 create mode 100644 drivers/iommu/rockchip-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd51122..d0a1261 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG
 
  Say N unless you know you need this.
 
+config ROCKCHIP_IOMMU
+   bool Rockchip IOMMU Support
+   depends on ARCH_ROCKCHIP
+   select IOMMU_API
+   select ARM_DMA_USE_IOMMU
+   help
+ Support for IOMMUs found on Rockchip rk32xx SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+ Say Y here if you are using a Rockchip SoC that includes an IOMMU
+ device.
+
 config TEGRA_IOMMU_GART
bool Tegra GART IOMMU Support
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 16edef7..3e47ef3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
new file mode 100644
index 000..08e50fc
--- /dev/null
+++ b/drivers/iommu/rockchip-iommu.c
@@ -0,0 +1,924 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include asm/cacheflush.h
+#include asm/pgtable.h
+#include linux/compiler.h
+#include linux/delay.h
+#include linux/device.h
+#include linux/errno.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/iommu.h
+#include linux/jiffies.h
+#include linux/list.h
+#include linux/mm.h
+#include linux/module.h
+#include linux/of.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux/spinlock.h
+
+/** MMU register offsets */
+#define RK_MMU_DTE_ADDR0x00/* Directory table address

[PATCH v3 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-10 Thread Daniel Kurtz
The rk3288 has several iommus.  Each iommu belongs to a single master
device.  There is one device (ISP) that has two slave iommus, but that
case is not yet supported by this driver.

At subsys init, the iommu driver registers itself as the iommu driver for
the platform bus.  The master devices find their slave iommus using the
iommus field in their devicetree description.  Since each slave iommu
belongs to exactly one master, their is no additional data needed at probe
to associate a slave with its master.

An iommu device's power domain, clock and irq are all shared with its
master device, and the master device must be careful to attach from the
iommu only after powering and clocking it (and leave it powered and
clocked before detaching).  Because their is no guarantee what the status
of the iommu is at probe, and since the driver does not even know if the
device is powered, we delay requesting its irq until the master device
attaches, at which point we have a guarantee that the device is powered
and clocked and we can reset it and disable its interrupt mask.

An iommu_domain describes a virtual iova address space.  Each iommu_domain
has a corresponding page table that lists the mappings from iova to
physical address.

For the rk3288 iommu, the page table has two levels:
 The Level 1 directory_table has 1024 4-byte dte entries.
 Each dte points to a level 2 page_table.
 Each level 2 page_table has 1024 4-byte pte entries.
 Each pte points to a 4 KiB page of memory.

An iommu_domain is created when a dma_iommu_mapping is created via
arm_iommu_create_mapping.  Master devices can then attach themselves to
this mapping (or attach the mapping to themselves?) by calling
arm_iommu_attach_device().  This in turn instructs the iommu driver to
write the page table's physical address into the slave iommu's Directory
Table Entry (DTE) register.

In fact multiple master devices, each with their own slave iommu device,
can all attach to the same mapping.  The iommus for these devices will
share the same iommu_domain and therefore point to the same page table.
Thus, the iommu domain maintains a list of iommu devices which are
attached.  This driver relies on the iommu core to ensure that all devices
have detached before destroying a domain.

Changes in v2:
 - Allocate page tables using GFP_DMA32
 - Reorder structs to put spinlocks together
 - Reword comment in map/unmap about  4MB mappings

Changes in v3:
 - select ARM_DMA_USE_IOMMU

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
Reviewed-by: Grant Grundler grund...@chromium.org
Reviewed-by: Stéphane Marchesin marc...@chromium.org
---
 drivers/iommu/Kconfig  |  12 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/rockchip-iommu.c | 924 +
 3 files changed, 937 insertions(+)
 create mode 100644 drivers/iommu/rockchip-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd51122..d0a1261 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -152,6 +152,18 @@ config OMAP_IOMMU_DEBUG
 
  Say N unless you know you need this.
 
+config ROCKCHIP_IOMMU
+   bool Rockchip IOMMU Support
+   depends on ARCH_ROCKCHIP
+   select IOMMU_API
+   select ARM_DMA_USE_IOMMU
+   help
+ Support for IOMMUs found on Rockchip rk32xx SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+ Say Y here if you are using a Rockchip SoC that includes an IOMMU
+ device.
+
 config TEGRA_IOMMU_GART
bool Tegra GART IOMMU Support
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 16edef7..3e47ef3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
new file mode 100644
index 000..08e50fc
--- /dev/null
+++ b/drivers/iommu/rockchip-iommu.c
@@ -0,0 +1,924 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include asm/cacheflush.h
+#include asm/pgtable.h
+#include linux/compiler.h
+#include linux/delay.h
+#include linux/device.h
+#include linux/errno.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/iommu.h
+#include linux/jiffies.h
+#include linux/list.h
+#include linux/mm.h
+#include linux/module.h
+#include linux/of.h

[PATCH v2 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-07 Thread Daniel Kurtz
The rk3288 has several iommus.  Each iommu belongs to a single master
device.  There is one device (ISP) that has two slave iommus, but that
case is not yet supported by this driver.

At subsys init, the iommu driver registers itself as the iommu driver for
the platform bus.  The master devices find their slave iommus using the
iommus field in their devicetree description.  Since each slave iommu
belongs to exactly one master, their is no additional data needed at probe
to associate a slave with its master.

An iommu device's power domain, clock and irq are all shared with its
master device, and the master device must be careful to attach from the
iommu only after powering and clocking it (and leave it powered and
clocked before detaching).  Because their is no guarantee what the status
of the iommu is at probe, and since the driver does not even know if the
device is powered, we delay requesting its irq until the master device
attaches, at which point we have a guarantee that the device is powered
and clocked and we can reset it and disable its interrupt mask.

An iommu_domain describes a virtual iova address space.  Each iommu_domain
has a corresponding page table that lists the mappings from iova to
physical address.

For the rk3288 iommu, the page table has two levels:
 The Level 1 directory_table has 1024 4-byte dte entries.
 Each dte points to a level 2 page_table.
 Each level 2 page_table has 1024 4-byte pte entries.
 Each pte points to a 4 KiB page of memory.

An iommu_domain is created when a dma_iommu_mapping is created via
arm_iommu_create_mapping.  Master devices can then attach themselves to
this mapping (or attach the mapping to themselves?) by calling
arm_iommu_attach_device().  This in turn instructs the iommu driver to
write the page table's physical address into the slave iommu's Directory
Table Entry (DTE) register.

In fact multiple master devices, each with their own slave iommu device,
can all attach to the same mapping.  The iommus for these devices will
share the same iommu_domain and therefore point to the same page table.
Thus, the iommu domain maintains a list of iommu devices which are
attached.  This driver relies on the iommu core to ensure that all devices
have detached before destroying a domain.

Changes in v2:
 - Allocate page tables using GFP_DMA32
 - Reorder structs to put spinlocks together
 - Reword comment in map/unmap about  4MB mappings

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
Reviewed-by: Grant Grundler grund...@chromium.org
Reviewed-by: Stéphane Marchesin marc...@chromium.org
---
 drivers/iommu/Kconfig  |  11 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/rockchip-iommu.c | 924 +
 3 files changed, 936 insertions(+)
 create mode 100644 drivers/iommu/rockchip-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd51122..b80454c 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -152,6 +152,17 @@ config OMAP_IOMMU_DEBUG
 
  Say N unless you know you need this.
 
+config ROCKCHIP_IOMMU
+   bool Rockchip IOMMU Support
+   depends on ARCH_ROCKCHIP
+   select IOMMU_API
+   help
+ Support for IOMMUs found on Rockchip rk32xx SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+ Say Y here if you are using a Rockchip SoC that includes an IOMMU
+ device.
+
 config TEGRA_IOMMU_GART
bool Tegra GART IOMMU Support
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 16edef7..3e47ef3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
new file mode 100644
index 000..08e50fc
--- /dev/null
+++ b/drivers/iommu/rockchip-iommu.c
@@ -0,0 +1,924 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include asm/cacheflush.h
+#include asm/pgtable.h
+#include linux/compiler.h
+#include linux/delay.h
+#include linux/device.h
+#include linux/errno.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/iommu.h
+#include linux/jiffies.h
+#include linux/list.h
+#include linux/mm.h
+#include linux/module.h
+#include linux/of.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux

[PATCH 2/3] dt-bindings: iommu: Add documentation for rockchip iommu

2014-10-02 Thread Daniel Kurtz
Add binding documentation for Rockchip IOMMU.

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
---
 .../devicetree/bindings/iommu/rockchip,iommu.txt   | 26 ++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/rockchip,iommu.txt

diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt 
b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
new file mode 100644
index 000..810e058
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
@@ -0,0 +1,26 @@
+Rockchip IOMMU
+==
+
+A Rockchip DRM iommu translates io virtual addresses to physical addresses for
+its master device.  Each slave device is bound to a single master device, and
+shares its clocks, power domain and irq.
+
+Required properties:
+- compatible  : Should be rockchip,iommu
+- reg : Address space for the configuration registers
+- interrupts  : Interrupt specifier for the IOMMU instance
+- interrupt-names : Interrupt name for the IOMMU instance
+- #iommu-cells: Should be 0.  This indicates the iommu is a
+single-master device, and needs no additional information
+to associate with its master device.  See:
+Documentation/devicetree/bindings/iommu/iommu.txt
+
+Example:
+
+   vopl_mmu: iommu@0xff940300 {
+   compatible = rockchip,iommu;
+   reg = 0xff940300 0x100;
+   interrupts = GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = vopl_mmu;
+   #iommu-cells = 0;
+   };
-- 
2.1.0.rc2.206.gedb03e5

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


[PATCH 1/3] iommu/rockchip: rk3288 iommu driver

2014-10-02 Thread Daniel Kurtz
The rk3288 has several iommus.  Each iommu belongs to a single master
device.  There is one device (ISP) that has two slave iommus, but that
case is not yet supported by this driver.

At subsys init, the iommu driver registers itself as the iommu driver for
the platform bus.  The master devices find their slave iommus using the
iommus field in their devicetree description.  Since each slave iommu
belongs to exactly one master, their is no additional data needed at probe
to associate a slave with its master.

An iommu device's power domain, clock and irq are all shared with its
master device, and the master device must be careful to attach from the
iommu only after powering and clocking it (and leave it powered and
clocked before detaching).  Because their is no guarantee what the status
of the iommu is at probe, and since the driver does not even know if the
device is powered, we delay requesting its irq until the master device
attaches, at which point we have a guarantee that the device is powered
and clocked and we can reset it and disable its interrupt mask.

An iommu_domain describes a virtual iova address space.  Each iommu_domain
has a corresponding page table that lists the mappings from iova to
physical address.

For the rk3288 iommu, the page table has two levels:
 The Level 1 directory_table has 1024 4-byte dte entries.
 Each dte points to a level 2 page_table.
 Each level 2 page_table has 1024 4-byte pte entries.
 Each pte points to a 4 KiB page of memory.

An iommu_domain is created when a dma_iommu_mapping is created via
arm_iommu_create_mapping.  Master devices can then attach themselves to
this mapping (or attach the mapping to themselves?) by calling
arm_iommu_attach_device().  This in turn instructs the iommu driver to
write the page table's physical address into the slave iommu's Directory
Table Entry (DTE) register.

In fact multiple master devices, each with their own slave iommu device,
can all attach to the same mapping.  The iommus for these devices will
share the same iommu_domain and therefore point to the same page table.
Thus, the iommu domain maintains a list of iommu devices which are
attached.  This driver relies on the iommu core to ensure that all devices
have detached before destroying a domain.

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
---
 drivers/iommu/Kconfig  |  11 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/rockchip-iommu.c | 924 +
 3 files changed, 936 insertions(+)
 create mode 100644 drivers/iommu/rockchip-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dd51122..b80454c 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -152,6 +152,17 @@ config OMAP_IOMMU_DEBUG
 
  Say N unless you know you need this.
 
+config ROCKCHIP_IOMMU
+   bool Rockchip IOMMU Support
+   depends on ARCH_ROCKCHIP
+   select IOMMU_API
+   help
+ Support for IOMMUs found on Rockchip rk32xx SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+ Say Y here if you are using a Rockchip SoC that includes an IOMMU
+ device.
+
 config TEGRA_IOMMU_GART
bool Tegra GART IOMMU Support
depends on ARCH_TEGRA_2x_SOC
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 16edef7..3e47ef3 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o 
irq_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
new file mode 100644
index 000..4116df1
--- /dev/null
+++ b/drivers/iommu/rockchip-iommu.c
@@ -0,0 +1,924 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include asm/cacheflush.h
+#include asm/pgtable.h
+#include linux/compiler.h
+#include linux/delay.h
+#include linux/device.h
+#include linux/errno.h
+#include linux/interrupt.h
+#include linux/io.h
+#include linux/iommu.h
+#include linux/jiffies.h
+#include linux/list.h
+#include linux/mm.h
+#include linux/module.h
+#include linux/of.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux/spinlock.h
+
+/** MMU register offsets */
+#define RK_MMU_DTE_ADDR0x00/* Directory table address */
+#define RK_MMU_STATUS  0x04
+#define RK_MMU_COMMAND 0x08
+#define RK_MMU_PAGE_FAULT_ADDR 0x0C/* IOVA of last page fault

[PATCH 3/3] ARM: dts: rk3288: add VOP iommu nodes

2014-10-02 Thread Daniel Kurtz
Add device nodes for the VOP iommus.
Device nodes for other iommus will be added in later patches.

The iommu nodes use the #iommu-cells property as described in:
  Documentation/devicetree/bindings/iommu/iommu.txt

Signed-off-by: Daniel Kurtz djku...@chromium.org
Signed-off-by: Simon Xue x...@rock-chips.com
---
 arch/arm/boot/dts/rk3288.dtsi | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 5950b0a..cbc92fa 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -271,6 +271,24 @@
status = disabled;
};
 
+   vopb_mmu: iommu@0xff930300 {
+   compatible = rockchip,iommu;
+   reg = 0xff930300 0x100;
+   interrupts = GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = vopb_mmu;
+   #iommu-cells = 0;
+   status = disabled;
+   };
+
+   vopl_mmu: iommu@0xff940300 {
+   compatible = rockchip,iommu;
+   reg = 0xff940300 0x100;
+   interrupts = GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = vopl_mmu;
+   #iommu-cells = 0;
+   status = disabled;
+   };
+
gic: interrupt-controller@ffc01000 {
compatible = arm,gic-400;
interrupt-controller;
-- 
2.1.0.rc2.206.gedb03e5

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