RE: [PATCH 0/7 v7] Support for fsl-mc bus and its devices in SMMU
> -Original Message- > From: Will Deacon [mailto:will.dea...@arm.com] > Sent: Wednesday, September 12, 2018 10:29 PM > To: Nipun Gupta > Cc: j...@8bytes.org; robin.mur...@arm.com; robh...@kernel.org; > r...@kernel.org; mark.rutl...@arm.com; catalin.mari...@arm.com; > gre...@linuxfoundation.org; Laurentiu Tudor ; > bhelg...@google.com; h...@lst.de; m.szyprow...@samsung.com; > shawn...@kernel.org; frowand.l...@gmail.com; iommu@lists.linux- > foundation.org; linux-ker...@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Leo Li > Subject: Re: [PATCH 0/7 v7] Support for fsl-mc bus and its devices in SMMU > > Hi Nipun, > > On Mon, Sep 10, 2018 at 07:19:14PM +0530, Nipun Gupta wrote: > > This patchset defines IOMMU DT binding for fsl-mc bus and adds > > support in SMMU for fsl-mc bus. > > > > These patches > > - Define property 'iommu-map' for fsl-mc bus (patch 1) > > - Integrates the fsl-mc bus with the SMMU using this > > IOMMU binding (patch 2,3,4) > > - Adds the dma configuration support for fsl-mc bus (patch 5, 6) > > - Updates the fsl-mc device node with iommu/dma related changes (patch 7) > > It looks like you have all the Acks in place for this series now, so I > assume it's going to go via Joerg directly. Is that right? This is what I am expecting :) > Will >
[PATCH 7/7 v7] arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc
fsl-mc bus support the new iommu-map property. Comply to this binding for fsl_mc bus. Signed-off-by: Nipun Gupta Reviewed-by: Laurentiu Tudor --- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 137ef4d..3d5e049 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -184,6 +184,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + dma-ranges = <0x0 0x0 0x0 0x0 0x1 0x>; clockgen: clocking@130 { compatible = "fsl,ls2080a-clockgen"; @@ -357,6 +358,8 @@ reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; + iommu-map = <0 &smmu 0 0>; /* This is fixed-up by u-boot */ + dma-coherent; #address-cells = <3>; #size-cells = <1>; @@ -460,6 +463,9 @@ compatible = "arm,mmu-500"; reg = <0 0x500 0 0x80>; #global-interrupts = <12>; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; + dma-coherent; interrupts = <0 13 4>, /* global secure fault */ <0 14 4>, /* combined secure interrupt */ <0 15 4>, /* global non-secure fault */ @@ -502,7 +508,6 @@ <0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>, <0 208 4>, <0 209 4>; - mmu-masters = <&fsl_mc 0x300 0>; }; dspi: dspi@210 { -- 1.9.1
[PATCH 6/7 v7] bus/fsl-mc: set coherent dma mask for devices on fsl-mc bus
of_dma_configure() API expects coherent_dma_mask to be correctly set in the devices. This patch does the needful. Signed-off-by: Nipun Gupta Reviewed-by: Robin Murphy --- drivers/bus/fsl-mc/fsl-mc-bus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index fa43c7d..624828b 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -627,6 +627,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, mc_dev->icid = parent_mc_dev->icid; mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; mc_dev->dev.dma_mask = &mc_dev->dma_mask; + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; dev_set_msi_domain(&mc_dev->dev, dev_get_msi_domain(&parent_mc_dev->dev)); } -- 1.9.1
[PATCH 5/7 v7] bus/fsl-mc: support dma configure for devices on fsl-mc bus
This patch adds support of dma configuration for devices on fsl-mc bus using 'dma_configure' callback for busses. Also, directly calling arch_setup_dma_ops is removed from the fsl-mc bus. Signed-off-by: Nipun Gupta Reviewed-by: Laurentiu Tudor Reviewed-by: Robin Murphy --- drivers/bus/fsl-mc/fsl-mc-bus.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 5d8266c..fa43c7d 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -127,6 +127,16 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int fsl_mc_dma_configure(struct device *dev) +{ + struct device *dma_dev = dev; + + while (dev_is_fsl_mc(dma_dev)) + dma_dev = dma_dev->parent; + + return of_dma_configure(dev, dma_dev->of_node, 0); +} + static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -148,6 +158,7 @@ struct bus_type fsl_mc_bus_type = { .name = "fsl-mc", .match = fsl_mc_bus_match, .uevent = fsl_mc_bus_uevent, + .dma_configure = fsl_mc_dma_configure, .dev_groups = fsl_mc_dev_groups, }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); @@ -633,10 +644,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, goto error_cleanup_dev; } - /* Objects are coherent, unless 'no shareability' flag set. */ - if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true); - /* * The device-specific probe callback will get invoked by device_add() */ -- 1.9.1
[PATCH 4/7 v7] iommu/arm-smmu: Add support for the fsl-mc bus
Implement bus specific support for the fsl-mc bus including registering arm_smmu_ops and bus specific device add operations. Signed-off-by: Nipun Gupta Reviewed-by: Robin Murphy --- drivers/iommu/arm-smmu.c | 7 +++ drivers/iommu/iommu.c| 13 + include/linux/fsl/mc.h | 8 include/linux/iommu.h| 2 ++ 4 files changed, 30 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index f7a96bc..a011bb6 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -52,6 +52,7 @@ #include #include +#include #include "io-pgtable.h" #include "arm-smmu-regs.h" @@ -1459,6 +1460,8 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) if (dev_is_pci(dev)) group = pci_device_group(dev); + else if (dev_is_fsl_mc(dev)) + group = fsl_mc_device_group(dev); else group = generic_device_group(dev); @@ -2037,6 +2040,10 @@ static void arm_smmu_bus_init(void) bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } #endif +#ifdef CONFIG_FSL_MC_BUS + if (!iommu_present(&fsl_mc_bus_type)) + bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops); +#endif } static int arm_smmu_device_probe(struct platform_device *pdev) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d227b86..df2f49e 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include static struct kset *iommu_group_kset; @@ -988,6 +989,18 @@ struct iommu_group *pci_device_group(struct device *dev) return iommu_group_alloc(); } +/* Get the IOMMU group for device on fsl-mc bus */ +struct iommu_group *fsl_mc_device_group(struct device *dev) +{ + struct device *cont_dev = fsl_mc_cont_dev(dev); + struct iommu_group *group; + + group = iommu_group_get(cont_dev); + if (!group) + group = iommu_group_alloc(); + return group; +} + /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index f27cb14..dddaca1 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -351,6 +351,14 @@ struct fsl_mc_io { #define dev_is_fsl_mc(_dev) (0) #endif +/* Macro to check if a device is a container device */ +#define fsl_mc_is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & \ + FSL_MC_IS_DPRC) + +/* Macro to get the container device of a MC device */ +#define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \ + (_dev) : (_dev)->parent) + /* * module_fsl_mc_driver() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 7447b0b..209891d 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -389,6 +389,8 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +/* FSL-MC device grouping function */ +struct iommu_group *fsl_mc_device_group(struct device *dev); /** * struct iommu_fwspec - per-device IOMMU instance data -- 1.9.1
[PATCH 3/7 v7] iommu/of: support iommu configuration for fsl-mc devices
With of_pci_map_rid available for all the busses, use the function for configuration of devices on fsl-mc bus Signed-off-by: Nipun Gupta Reviewed-by: Robin Murphy --- drivers/iommu/of_iommu.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 811e160..284474d 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -24,6 +24,7 @@ #include #include #include +#include #define NO_IOMMU 1 @@ -159,6 +160,23 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) return err; } +static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, + struct device_node *master_np) +{ + struct of_phandle_args iommu_spec = { .args_count = 1 }; + int err; + + err = of_map_rid(master_np, mc_dev->icid, "iommu-map", +"iommu-map-mask", &iommu_spec.np, +iommu_spec.args); + if (err) + return err == -ENODEV ? NO_IOMMU : err; + + err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); + of_node_put(iommu_spec.np); + return err; +} + const struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { @@ -190,6 +208,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, err = pci_for_each_dma_alias(to_pci_dev(dev), of_pci_iommu_init, &info); + } else if (dev_is_fsl_mc(dev)) { + err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); } else { struct of_phandle_args iommu_spec; int idx = 0; -- 1.9.1
[PATCH 2/7 v7] iommu/of: make of_pci_map_rid() available for other devices too
iommu-map property is also used by devices with fsl-mc. This patch moves the of_pci_map_rid to generic location, so that it can be used by other busses too. 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no functional change done in the API. Signed-off-by: Nipun Gupta Reviewed-by: Rob Herring Reviewed-by: Robin Murphy Acked-by: Bjorn Helgaas --- drivers/iommu/of_iommu.c | 5 +-- drivers/of/base.c| 102 +++ drivers/of/irq.c | 5 +-- drivers/pci/of.c | 101 -- include/linux/of.h | 11 + include/linux/of_pci.h | 10 - 6 files changed, 117 insertions(+), 117 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..811e160 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -149,9 +149,8 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_pci_map_rid(info->np, alias, "iommu-map", -"iommu-map-mask", &iommu_spec.np, -iommu_spec.args); + err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", +&iommu_spec.np, iommu_spec.args); if (err) return err == -ENODEV ? NO_IOMMU : err; diff --git a/drivers/of/base.c b/drivers/of/base.c index 848f549..c7aac81 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1995,3 +1995,105 @@ int of_find_last_cache_level(unsigned int cpu) return cache_level; } + +/** + * of_map_rid - Translate a requester ID through a downstream mapping. + * @np: root complex device node. + * @rid: device requester ID to map. + * @map_name: property name of the map to use. + * @map_mask_name: optional property name of the mask to use. + * @target: optional pointer to a target device node. + * @id_out: optional pointer to receive the translated ID. + * + * Given a device requester ID, look up the appropriate implementation-defined + * platform ID and/or the target device which receives transactions on that + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or + * @id_out may be NULL if only the other is required. If @target points to + * a non-NULL device node pointer, only entries targeting that node will be + * matched; if it points to a NULL value, it will receive the device node of + * the first matching target phandle, with a reference held. + * + * Return: 0 on success or a standard error code on failure. + */ +int of_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + u32 map_mask, masked_rid; + int map_len; + const __be32 *map = NULL; + + if (!np || !map_name || (!target && !id_out)) + return -EINVAL; + + map = of_get_property(np, map_name, &map_len); + if (!map) { + if (target) + return -ENODEV; + /* Otherwise, no map implies no translation */ + *id_out = rid; + return 0; + } + + if (!map_len || map_len % (4 * sizeof(*map))) { + pr_err("%pOF: Error: Bad %s length: %d\n", np, + map_name, map_len); + return -EINVAL; + } + + /* The default is to select all bits. */ + map_mask = 0x; + + /* +* Can be overridden by "{iommu,msi}-map-mask" property. +* If of_property_read_u32() fails, the default is used. +*/ + if (map_mask_name) + of_property_read_u32(np, map_mask_name, &map_mask); + + masked_rid = map_mask & rid; + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { + struct device_node *phandle_node; + u32 rid_base = be32_to_cpup(map + 0); + u32 phandle = be32_to_cpup(map + 1); + u32 out_base = be32_to_cpup(map + 2); + u32 rid_len = be32_to_cpup(map + 3); + + if (rid_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, + map_mask, rid_base); + return -EFAULT; + } + + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + continue; + + phandle_node = of_find_node_by_phandle(phandle); + if (!phandle_node) + return -ENODEV; + + if (target) { +
[PATCH 1/7 v7] Documentation: fsl-mc: add iommu-map device-tree binding for fsl-mc bus
The existing IOMMU bindings cannot be used to specify the relationship between fsl-mc devices and IOMMUs. This patch adds a generic binding for mapping fsl-mc devices to IOMMUs, using iommu-map property. Signed-off-by: Nipun Gupta Reviewed-by: Rob Herring Acked-by: Robin Murphy --- .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 ++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt index 6611a7c..01fdc33 100644 --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt @@ -9,6 +9,25 @@ blocks that can be used to create functional hardware objects/devices such as network interfaces, crypto accelerator instances, L2 switches, etc. +For an overview of the DPAA2 architecture and fsl-mc bus see: +Documentation/networking/dpaa2/overview.rst + +As described in the above overview, all DPAA2 objects in a DPRC share the +same hardware "isolation context" and a 10-bit value called an ICID +(isolation context id) is expressed by the hardware to identify +the requester. + +The generic 'iommus' property is insufficient to describe the relationship +between ICIDs and IOMMUs, so an iommu-map property is used to define +the set of possible ICIDs under a root DPRC and how they map to +an IOMMU. + +For generic IOMMU bindings, see +Documentation/devicetree/bindings/iommu/iommu.txt. + +For arm-smmu binding, see: +Documentation/devicetree/bindings/iommu/arm,smmu.txt. + Required properties: - compatible @@ -88,14 +107,34 @@ Sub-nodes: Value type: Definition: Specifies the phandle to the PHY device node associated with the this dpmac. +Optional properties: + +- iommu-map: Maps an ICID to an IOMMU and associated iommu-specifier + data. + + The property is an arbitrary number of tuples of + (icid-base,iommu,iommu-base,length). + + Any ICID i in the interval [icid-base, icid-base + length) is + associated with the listed IOMMU, with the iommu-specifier + (i - icid-base + iommu-base). Example: +smmu: iommu@500 { + compatible = "arm,mmu-500"; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; + ... +}; + fsl_mc: fsl-mc@80c00 { compatible = "fsl,qoriq-mc"; reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; +/* define map for ICIDs 23-64 */ +iommu-map = <23 &smmu 23 41>; #address-cells = <3>; #size-cells = <1>; -- 1.9.1
[PATCH 0/7 v7] Support for fsl-mc bus and its devices in SMMU
This patchset defines IOMMU DT binding for fsl-mc bus and adds support in SMMU for fsl-mc bus. These patches - Define property 'iommu-map' for fsl-mc bus (patch 1) - Integrates the fsl-mc bus with the SMMU using this IOMMU binding (patch 2,3,4) - Adds the dma configuration support for fsl-mc bus (patch 5, 6) - Updates the fsl-mc device node with iommu/dma related changes (patch 7) Changes in v2: - use iommu-map property for fsl-mc bus - rebase over patchset https://patchwork.kernel.org/patch/10317337/ and make corresponding changes for dma configuration of devices on fsl-mc bus Changes in v3: - move of_map_rid in drivers/of/address.c Changes in v4: - move of_map_rid in drivers/of/base.c Changes in v5: - break patch 5 in two separate patches (now patch 5/7 and patch 6/7) - add changelog text in patch 3/7 and patch 5/7 - typo fix Changes in v6: - Updated fsl_mc_device_group() API to be more rational - Added dma-coherent property in the LS2 smmu device node - Minor fixes in the device-tree documentation Changes in v7: - Rebased over linux 4.19 Nipun Gupta (7): Documentation: fsl-mc: add iommu-map device-tree binding for fsl-mc bus iommu/of: make of_pci_map_rid() available for other devices too iommu/of: support iommu configuration for fsl-mc devices iommu/arm-smmu: Add support for the fsl-mc bus bus: fsl-mc: support dma configure for devices on fsl-mc bus bus: fsl-mc: set coherent dma mask for devices on fsl-mc bus arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 7 +- drivers/bus/fsl-mc/fsl-mc-bus.c| 16 +++- drivers/iommu/arm-smmu.c | 7 ++ drivers/iommu/iommu.c | 13 +++ drivers/iommu/of_iommu.c | 25 - drivers/of/base.c | 102 + drivers/of/irq.c | 5 +- drivers/pci/of.c | 101 include/linux/fsl/mc.h | 8 ++ include/linux/iommu.h | 2 + include/linux/of.h | 11 +++ include/linux/of_pci.h | 10 -- 13 files changed, 224 insertions(+), 122 deletions(-) -- 1.9.1
RE: [PATCH 0/7 v6] Support for fsl-mc bus and its devices in SMMU
Hi Joerg/Robin, Can you please let me know when these patches will be applied onto the tree. Is there anything else pending from my side. Thanks, Nipun > -Original Message- > From: Nipun Gupta > Sent: Monday, July 9, 2018 4:48 PM > To: robin.mur...@arm.com; will.dea...@arm.com; robh...@kernel.org; > r...@kernel.org; mark.rutl...@arm.com; catalin.mari...@arm.com; > gre...@linuxfoundation.org; Laurentiu Tudor ; > bhelg...@google.com; h...@lst.de > Cc: j...@8bytes.org; m.szyprow...@samsung.com; shawn...@kernel.org; > frowand.l...@gmail.com; io...@lists.linux-foundation.org; linux- > ker...@vger.kernel.org; devicet...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Leo Li ; Nipun Gupta > > Subject: [PATCH 0/7 v6] Support for fsl-mc bus and its devices in SMMU > > This patchset defines IOMMU DT binding for fsl-mc bus and adds > support in SMMU for fsl-mc bus. > > The patch series is based on top of dma-mapping tree (for-next branch): > http://git.infradead.org/users/hch/dma-mapping.git > > These patches > - Define property 'iommu-map' for fsl-mc bus (patch 1) > - Integrates the fsl-mc bus with the SMMU using this > IOMMU binding (patch 2,3,4) > - Adds the dma configuration support for fsl-mc bus (patch 5, 6) > - Updates the fsl-mc device node with iommu/dma related changes (patch 7) > > Changes in v2: > - use iommu-map property for fsl-mc bus > - rebase over patchset https://patchwork.kernel.org/patch/10317337/ > and make corresponding changes for dma configuration of devices on > fsl-mc bus > > Changes in v3: > - move of_map_rid in drivers/of/address.c > > Changes in v4: > - move of_map_rid in drivers/of/base.c > > Changes in v5: > - break patch 5 in two separate patches (now patch 5/7 and patch 6/7) > - add changelog text in patch 3/7 and patch 5/7 > - typo fix > > Changes in v6: > - Updated fsl_mc_device_group() API to be more rational > - Added dma-coherent property in the LS2 smmu device node > - Minor fixes in the device-tree documentation > > Nipun Gupta (7): > Documentation: fsl-mc: add iommu-map device-tree binding for fsl-mc > bus > iommu/of: make of_pci_map_rid() available for other devices too > iommu/of: support iommu configuration for fsl-mc devices > iommu/arm-smmu: Add support for the fsl-mc bus > bus: fsl-mc: support dma configure for devices on fsl-mc bus > bus: fsl-mc: set coherent dma mask for devices on fsl-mc bus > arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc > > .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 > arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 7 +- > drivers/bus/fsl-mc/fsl-mc-bus.c| 16 +++- > drivers/iommu/arm-smmu.c | 7 ++ > drivers/iommu/iommu.c | 13 +++ > drivers/iommu/of_iommu.c | 25 - > drivers/of/base.c | 102 > + > drivers/of/irq.c | 5 +- > drivers/pci/of.c | 101 > include/linux/fsl/mc.h | 8 ++ > include/linux/iommu.h | 2 + > include/linux/of.h | 11 +++ > include/linux/of_pci.h | 10 -- > 13 files changed, 224 insertions(+), 122 deletions(-) > > -- > 1.9.1
[PATCH 7/7 v6] arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc
fsl-mc bus support the new iommu-map property. Comply to this binding for fsl_mc bus. Signed-off-by: Nipun Gupta Reviewed-by: Laurentiu Tudor --- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 137ef4d..3d5e049 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -184,6 +184,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + dma-ranges = <0x0 0x0 0x0 0x0 0x1 0x>; clockgen: clocking@130 { compatible = "fsl,ls2080a-clockgen"; @@ -357,6 +358,8 @@ reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; + iommu-map = <0 &smmu 0 0>; /* This is fixed-up by u-boot */ + dma-coherent; #address-cells = <3>; #size-cells = <1>; @@ -460,6 +463,9 @@ compatible = "arm,mmu-500"; reg = <0 0x500 0 0x80>; #global-interrupts = <12>; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; + dma-coherent; interrupts = <0 13 4>, /* global secure fault */ <0 14 4>, /* combined secure interrupt */ <0 15 4>, /* global non-secure fault */ @@ -502,7 +508,6 @@ <0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>, <0 208 4>, <0 209 4>; - mmu-masters = <&fsl_mc 0x300 0>; }; dspi: dspi@210 { -- 1.9.1
[PATCH 6/7 v6] bus/fsl-mc: set coherent dma mask for devices on fsl-mc bus
of_dma_configure() API expects coherent_dma_mask to be correctly set in the devices. This patch does the needful. Signed-off-by: Nipun Gupta Reviewed-by: Robin Murphy --- drivers/bus/fsl-mc/fsl-mc-bus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index fa43c7d..624828b 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -627,6 +627,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, mc_dev->icid = parent_mc_dev->icid; mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; mc_dev->dev.dma_mask = &mc_dev->dma_mask; + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; dev_set_msi_domain(&mc_dev->dev, dev_get_msi_domain(&parent_mc_dev->dev)); } -- 1.9.1
[PATCH 5/7 v6] bus/fsl-mc: support dma configure for devices on fsl-mc bus
This patch adds support of dma configuration for devices on fsl-mc bus using 'dma_configure' callback for busses. Also, directly calling arch_setup_dma_ops is removed from the fsl-mc bus. Signed-off-by: Nipun Gupta Reviewed-by: Laurentiu Tudor --- drivers/bus/fsl-mc/fsl-mc-bus.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 5d8266c..fa43c7d 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -127,6 +127,16 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int fsl_mc_dma_configure(struct device *dev) +{ + struct device *dma_dev = dev; + + while (dev_is_fsl_mc(dma_dev)) + dma_dev = dma_dev->parent; + + return of_dma_configure(dev, dma_dev->of_node, 0); +} + static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -148,6 +158,7 @@ struct bus_type fsl_mc_bus_type = { .name = "fsl-mc", .match = fsl_mc_bus_match, .uevent = fsl_mc_bus_uevent, + .dma_configure = fsl_mc_dma_configure, .dev_groups = fsl_mc_dev_groups, }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); @@ -633,10 +644,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, goto error_cleanup_dev; } - /* Objects are coherent, unless 'no shareability' flag set. */ - if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true); - /* * The device-specific probe callback will get invoked by device_add() */ -- 1.9.1
[PATCH 4/7 v6] iommu/arm-smmu: Add support for the fsl-mc bus
Implement bus specific support for the fsl-mc bus including registering arm_smmu_ops and bus specific device add operations. Signed-off-by: Nipun Gupta --- drivers/iommu/arm-smmu.c | 7 +++ drivers/iommu/iommu.c| 13 + include/linux/fsl/mc.h | 8 include/linux/iommu.h| 2 ++ 4 files changed, 30 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index f7a96bc..a011bb6 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -52,6 +52,7 @@ #include #include +#include #include "io-pgtable.h" #include "arm-smmu-regs.h" @@ -1459,6 +1460,8 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) if (dev_is_pci(dev)) group = pci_device_group(dev); + else if (dev_is_fsl_mc(dev)) + group = fsl_mc_device_group(dev); else group = generic_device_group(dev); @@ -2037,6 +2040,10 @@ static void arm_smmu_bus_init(void) bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } #endif +#ifdef CONFIG_FSL_MC_BUS + if (!iommu_present(&fsl_mc_bus_type)) + bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops); +#endif } static int arm_smmu_device_probe(struct platform_device *pdev) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d227b86..df2f49e 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include static struct kset *iommu_group_kset; @@ -988,6 +989,18 @@ struct iommu_group *pci_device_group(struct device *dev) return iommu_group_alloc(); } +/* Get the IOMMU group for device on fsl-mc bus */ +struct iommu_group *fsl_mc_device_group(struct device *dev) +{ + struct device *cont_dev = fsl_mc_cont_dev(dev); + struct iommu_group *group; + + group = iommu_group_get(cont_dev); + if (!group) + group = iommu_group_alloc(); + return group; +} + /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index f27cb14..dddaca1 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -351,6 +351,14 @@ struct fsl_mc_io { #define dev_is_fsl_mc(_dev) (0) #endif +/* Macro to check if a device is a container device */ +#define fsl_mc_is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & \ + FSL_MC_IS_DPRC) + +/* Macro to get the container device of a MC device */ +#define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \ + (_dev) : (_dev)->parent) + /* * module_fsl_mc_driver() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 7447b0b..209891d 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -389,6 +389,8 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +/* FSL-MC device grouping function */ +struct iommu_group *fsl_mc_device_group(struct device *dev); /** * struct iommu_fwspec - per-device IOMMU instance data -- 1.9.1
[PATCH 3/7 v6] iommu/of: support iommu configuration for fsl-mc devices
With of_pci_map_rid available for all the busses, use the function for configuration of devices on fsl-mc bus Signed-off-by: Nipun Gupta Reviewed-by: Robin Murphy --- drivers/iommu/of_iommu.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 811e160..284474d 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -24,6 +24,7 @@ #include #include #include +#include #define NO_IOMMU 1 @@ -159,6 +160,23 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) return err; } +static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, + struct device_node *master_np) +{ + struct of_phandle_args iommu_spec = { .args_count = 1 }; + int err; + + err = of_map_rid(master_np, mc_dev->icid, "iommu-map", +"iommu-map-mask", &iommu_spec.np, +iommu_spec.args); + if (err) + return err == -ENODEV ? NO_IOMMU : err; + + err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); + of_node_put(iommu_spec.np); + return err; +} + const struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { @@ -190,6 +208,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, err = pci_for_each_dma_alias(to_pci_dev(dev), of_pci_iommu_init, &info); + } else if (dev_is_fsl_mc(dev)) { + err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); } else { struct of_phandle_args iommu_spec; int idx = 0; -- 1.9.1
[PATCH 2/7 v6] iommu/of: make of_pci_map_rid() available for other devices too
iommu-map property is also used by devices with fsl-mc. This patch moves the of_pci_map_rid to generic location, so that it can be used by other busses too. 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no functional change done in the API. Signed-off-by: Nipun Gupta Reviewed-by: Rob Herring Reviewed-by: Robin Murphy Acked-by: Bjorn Helgaas --- drivers/iommu/of_iommu.c | 5 +-- drivers/of/base.c| 102 +++ drivers/of/irq.c | 5 +-- drivers/pci/of.c | 101 -- include/linux/of.h | 11 + include/linux/of_pci.h | 10 - 6 files changed, 117 insertions(+), 117 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..811e160 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -149,9 +149,8 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_pci_map_rid(info->np, alias, "iommu-map", -"iommu-map-mask", &iommu_spec.np, -iommu_spec.args); + err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", +&iommu_spec.np, iommu_spec.args); if (err) return err == -ENODEV ? NO_IOMMU : err; diff --git a/drivers/of/base.c b/drivers/of/base.c index 848f549..c7aac81 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1995,3 +1995,105 @@ int of_find_last_cache_level(unsigned int cpu) return cache_level; } + +/** + * of_map_rid - Translate a requester ID through a downstream mapping. + * @np: root complex device node. + * @rid: device requester ID to map. + * @map_name: property name of the map to use. + * @map_mask_name: optional property name of the mask to use. + * @target: optional pointer to a target device node. + * @id_out: optional pointer to receive the translated ID. + * + * Given a device requester ID, look up the appropriate implementation-defined + * platform ID and/or the target device which receives transactions on that + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or + * @id_out may be NULL if only the other is required. If @target points to + * a non-NULL device node pointer, only entries targeting that node will be + * matched; if it points to a NULL value, it will receive the device node of + * the first matching target phandle, with a reference held. + * + * Return: 0 on success or a standard error code on failure. + */ +int of_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + u32 map_mask, masked_rid; + int map_len; + const __be32 *map = NULL; + + if (!np || !map_name || (!target && !id_out)) + return -EINVAL; + + map = of_get_property(np, map_name, &map_len); + if (!map) { + if (target) + return -ENODEV; + /* Otherwise, no map implies no translation */ + *id_out = rid; + return 0; + } + + if (!map_len || map_len % (4 * sizeof(*map))) { + pr_err("%pOF: Error: Bad %s length: %d\n", np, + map_name, map_len); + return -EINVAL; + } + + /* The default is to select all bits. */ + map_mask = 0x; + + /* +* Can be overridden by "{iommu,msi}-map-mask" property. +* If of_property_read_u32() fails, the default is used. +*/ + if (map_mask_name) + of_property_read_u32(np, map_mask_name, &map_mask); + + masked_rid = map_mask & rid; + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { + struct device_node *phandle_node; + u32 rid_base = be32_to_cpup(map + 0); + u32 phandle = be32_to_cpup(map + 1); + u32 out_base = be32_to_cpup(map + 2); + u32 rid_len = be32_to_cpup(map + 3); + + if (rid_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, + map_mask, rid_base); + return -EFAULT; + } + + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + continue; + + phandle_node = of_find_node_by_phandle(phandle); + if (!phandle_node) + return -ENODEV; + + if (target) { +
[PATCH 1/7 v6] Documentation: fsl-mc: add iommu-map device-tree binding for fsl-mc bus
The existing IOMMU bindings cannot be used to specify the relationship between fsl-mc devices and IOMMUs. This patch adds a generic binding for mapping fsl-mc devices to IOMMUs, using iommu-map property. Signed-off-by: Nipun Gupta Reviewed-by: Rob Herring --- .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 ++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt index 6611a7c..01fdc33 100644 --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt @@ -9,6 +9,25 @@ blocks that can be used to create functional hardware objects/devices such as network interfaces, crypto accelerator instances, L2 switches, etc. +For an overview of the DPAA2 architecture and fsl-mc bus see: +Documentation/networking/dpaa2/overview.rst + +As described in the above overview, all DPAA2 objects in a DPRC share the +same hardware "isolation context" and a 10-bit value called an ICID +(isolation context id) is expressed by the hardware to identify +the requester. + +The generic 'iommus' property is insufficient to describe the relationship +between ICIDs and IOMMUs, so an iommu-map property is used to define +the set of possible ICIDs under a root DPRC and how they map to +an IOMMU. + +For generic IOMMU bindings, see +Documentation/devicetree/bindings/iommu/iommu.txt. + +For arm-smmu binding, see: +Documentation/devicetree/bindings/iommu/arm,smmu.txt. + Required properties: - compatible @@ -88,14 +107,34 @@ Sub-nodes: Value type: Definition: Specifies the phandle to the PHY device node associated with the this dpmac. +Optional properties: + +- iommu-map: Maps an ICID to an IOMMU and associated iommu-specifier + data. + + The property is an arbitrary number of tuples of + (icid-base,iommu,iommu-base,length). + + Any ICID i in the interval [icid-base, icid-base + length) is + associated with the listed IOMMU, with the iommu-specifier + (i - icid-base + iommu-base). Example: +smmu: iommu@500 { + compatible = "arm,mmu-500"; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; + ... +}; + fsl_mc: fsl-mc@80c00 { compatible = "fsl,qoriq-mc"; reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; +/* define map for ICIDs 23-64 */ +iommu-map = <23 &smmu 23 41>; #address-cells = <3>; #size-cells = <1>; -- 1.9.1
[PATCH 0/7 v6] Support for fsl-mc bus and its devices in SMMU
This patchset defines IOMMU DT binding for fsl-mc bus and adds support in SMMU for fsl-mc bus. The patch series is based on top of dma-mapping tree (for-next branch): http://git.infradead.org/users/hch/dma-mapping.git These patches - Define property 'iommu-map' for fsl-mc bus (patch 1) - Integrates the fsl-mc bus with the SMMU using this IOMMU binding (patch 2,3,4) - Adds the dma configuration support for fsl-mc bus (patch 5, 6) - Updates the fsl-mc device node with iommu/dma related changes (patch 7) Changes in v2: - use iommu-map property for fsl-mc bus - rebase over patchset https://patchwork.kernel.org/patch/10317337/ and make corresponding changes for dma configuration of devices on fsl-mc bus Changes in v3: - move of_map_rid in drivers/of/address.c Changes in v4: - move of_map_rid in drivers/of/base.c Changes in v5: - break patch 5 in two separate patches (now patch 5/7 and patch 6/7) - add changelog text in patch 3/7 and patch 5/7 - typo fix Changes in v6: - Updated fsl_mc_device_group() API to be more rational - Added dma-coherent property in the LS2 smmu device node - Minor fixes in the device-tree documentation Nipun Gupta (7): Documentation: fsl-mc: add iommu-map device-tree binding for fsl-mc bus iommu/of: make of_pci_map_rid() available for other devices too iommu/of: support iommu configuration for fsl-mc devices iommu/arm-smmu: Add support for the fsl-mc bus bus: fsl-mc: support dma configure for devices on fsl-mc bus bus: fsl-mc: set coherent dma mask for devices on fsl-mc bus arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 7 +- drivers/bus/fsl-mc/fsl-mc-bus.c| 16 +++- drivers/iommu/arm-smmu.c | 7 ++ drivers/iommu/iommu.c | 13 +++ drivers/iommu/of_iommu.c | 25 - drivers/of/base.c | 102 + drivers/of/irq.c | 5 +- drivers/pci/of.c | 101 include/linux/fsl/mc.h | 8 ++ include/linux/iommu.h | 2 + include/linux/of.h | 11 +++ include/linux/of_pci.h | 10 -- 13 files changed, 224 insertions(+), 122 deletions(-) -- 1.9.1
RE: [PATCH 7/7 v5] arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc
> -Original Message- > From: Robin Murphy [mailto:robin.mur...@arm.com] > Sent: Tuesday, July 3, 2018 10:06 PM > To: Nipun Gupta ; will.dea...@arm.com; > robh...@kernel.org; r...@kernel.org; mark.rutl...@arm.com; > catalin.mari...@arm.com; gre...@linuxfoundation.org; Laurentiu Tudor > ; bhelg...@google.com > Cc: h...@lst.de; j...@8bytes.org; m.szyprow...@samsung.com; > shawn...@kernel.org; frowand.l...@gmail.com; iommu@lists.linux- > foundation.org; linux-ker...@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Leo Li > Subject: Re: [PATCH 7/7 v5] arm64: dts: ls208xa: comply with the iommu map > binding for fsl_mc > > On 20/05/18 14:49, Nipun Gupta wrote: > > fsl-mc bus support the new iommu-map property. Comply to this binding > > for fsl_mc bus. > > > > Signed-off-by: Nipun Gupta > > Reviewed-by: Laurentiu Tudor > > --- > > arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- > > 1 file changed, 5 insertions(+), 1 deletion(-) > > > > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi > b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi > > index 137ef4d..6010505 100644 > > --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi > > +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi > > @@ -184,6 +184,7 @@ > > #address-cells = <2>; > > #size-cells = <2>; > > ranges; > > + dma-ranges = <0x0 0x0 0x0 0x0 0x1 0x>; > > > > clockgen: clocking@130 { > > compatible = "fsl,ls2080a-clockgen"; > > @@ -357,6 +358,8 @@ > > reg = <0x0008 0x0c00 0 0x40>,/* MC portal > base */ > > <0x 0x0834 0 0x4>; /* MC > control reg */ > > msi-parent = <&its>; > > + iommu-map = <0 &smmu 0 0>; /* This is fixed-up by > u-boot */ > > + dma-coherent; > > #address-cells = <3>; > > #size-cells = <1>; > > > > @@ -460,6 +463,8 @@ > > compatible = "arm,mmu-500"; > > reg = <0 0x500 0 0x80>; > > #global-interrupts = <12>; > > + #iommu-cells = <1>; > > + stream-match-mask = <0x7C00>; > > interrupts = <0 13 4>, /* global secure fault */ > > <0 14 4>, /* combined secure interrupt */ > > <0 15 4>, /* global non-secure fault */ > > @@ -502,7 +507,6 @@ > > <0 204 4>, <0 205 4>, > > <0 206 4>, <0 207 4>, > > <0 208 4>, <0 209 4>; > > - mmu-masters = <&fsl_mc 0x300 0>; > > Since we're in here, is the SMMU itself also coherent? If it is, you > probably want to say so and avoid the overhead of pointlessly cleaning > cache lines on every page table update. Yes, dma-coherent property is also required here. I missed it somehow. Thanks for pointing this. Regards, Nipun > > Robin. > > > }; > > > > dspi: dspi@210 { > >
RE: [PATCH 5/7 v5] bus: fsl-mc: support dma configure for devices on fsl-mc bus
> -Original Message- > From: Robin Murphy [mailto:robin.mur...@arm.com] > Sent: Tuesday, July 3, 2018 9:44 PM > To: Nipun Gupta ; will.dea...@arm.com; > robh...@kernel.org; r...@kernel.org; mark.rutl...@arm.com; > catalin.mari...@arm.com; gre...@linuxfoundation.org; Laurentiu Tudor > ; bhelg...@google.com > Cc: h...@lst.de; j...@8bytes.org; m.szyprow...@samsung.com; > shawn...@kernel.org; frowand.l...@gmail.com; iommu@lists.linux- > foundation.org; linux-ker...@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Leo Li > Subject: Re: [PATCH 5/7 v5] bus: fsl-mc: support dma configure for devices > on fsl-mc bus > > On 20/05/18 14:49, Nipun Gupta wrote: > > This patch adds support of dma configuration for devices on fsl-mc > > bus using 'dma_configure' callback for busses. Also, directly calling > > arch_setup_dma_ops is removed from the fsl-mc bus. > > Looks like this is the final arch_setup_dma_ops offender, yay! > > > Signed-off-by: Nipun Gupta > > Reviewed-by: Laurentiu Tudor > > --- > > drivers/bus/fsl-mc/fsl-mc-bus.c | 15 +++ > > 1 file changed, 11 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc- > bus.c > > index 5d8266c..fa43c7d 100644 > > --- a/drivers/bus/fsl-mc/fsl-mc-bus.c > > +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c > > @@ -127,6 +127,16 @@ static int fsl_mc_bus_uevent(struct device *dev, > struct kobj_uevent_env *env) > > return 0; > > } > > > > +static int fsl_mc_dma_configure(struct device *dev) > > +{ > > + struct device *dma_dev = dev; > > + > > + while (dev_is_fsl_mc(dma_dev)) > > + dma_dev = dma_dev->parent; > > + > > + return of_dma_configure(dev, dma_dev->of_node, 0); > > +} > > + > > static ssize_t modalias_show(struct device *dev, struct device_attribute > *attr, > > char *buf) > > { > > @@ -148,6 +158,7 @@ struct bus_type fsl_mc_bus_type = { > > .name = "fsl-mc", > > .match = fsl_mc_bus_match, > > .uevent = fsl_mc_bus_uevent, > > + .dma_configure = fsl_mc_dma_configure, > > .dev_groups = fsl_mc_dev_groups, > > }; > > EXPORT_SYMBOL_GPL(fsl_mc_bus_type); > > @@ -633,10 +644,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc > *obj_desc, > > goto error_cleanup_dev; > > } > > > > - /* Objects are coherent, unless 'no shareability' flag set. */ > > - if (!(obj_desc->flags & > FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) > > Although it seems we do end up without any handling of this > "non-coherent object behind coherent MC" case, and I'm not sure how > easily that could be accommodated by generic code... :/ How important is > the quirk? We have all the devices as coherent in our SoC's now :) So this is fine. We have internally discussed it. Regards, Nipun > > Robin. > > > - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true); > > - > > /* > > * The device-specific probe callback will get invoked by device_add() > > */ > >
RE: [PATCH 1/7 v5] Docs: dt: add fsl-mc iommu-map device-tree binding
> -Original Message- > From: Robin Murphy [mailto:robin.mur...@arm.com] > Sent: Tuesday, July 3, 2018 8:10 PM > To: Nipun Gupta ; will.dea...@arm.com; > robh...@kernel.org; r...@kernel.org; mark.rutl...@arm.com; > catalin.mari...@arm.com; gre...@linuxfoundation.org; Laurentiu Tudor > ; bhelg...@google.com > Cc: h...@lst.de; j...@8bytes.org; m.szyprow...@samsung.com; > shawn...@kernel.org; frowand.l...@gmail.com; iommu@lists.linux- > foundation.org; linux-ker...@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Leo Li > Subject: Re: [PATCH 1/7 v5] Docs: dt: add fsl-mc iommu-map device-tree > binding > > On 20/05/18 14:49, Nipun Gupta wrote: > > The existing IOMMU bindings cannot be used to specify the relationship > > between fsl-mc devices and IOMMUs. This patch adds a generic binding for > > mapping fsl-mc devices to IOMMUs, using iommu-map property. > > > > Signed-off-by: Nipun Gupta > > Reviewed-by: Rob Herring > > --- > > .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 > ++ > > 1 file changed, 39 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > index 6611a7c..8cbed4f 100644 > > --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > @@ -9,6 +9,25 @@ blocks that can be used to create functional hardware > objects/devices > > such as network interfaces, crypto accelerator instances, L2 switches, > > etc. > > > > +For an overview of the DPAA2 architecture and fsl-mc bus see: > > +drivers/staging/fsl-mc/README.txt > > Nit: Looks like that's Documentation/networking/dpaa2/overview.rst now. > > > + > > +As described in the above overview, all DPAA2 objects in a DPRC share the > > +same hardware "isolation context" and a 10-bit value called an ICID > > +(isolation context id) is expressed by the hardware to identify > > +the requester. > > + > > +The generic 'iommus' property is insufficient to describe the relationship > > +between ICIDs and IOMMUs, so an iommu-map property is used to > define > > +the set of possible ICIDs under a root DPRC and how they map to > > +an IOMMU. > > + > > +For generic IOMMU bindings, see > > +Documentation/devicetree/bindings/iommu/iommu.txt. > > + > > +For arm-smmu binding, see: > > +Documentation/devicetree/bindings/iommu/arm,smmu.txt. > > + > > Required properties: > > > > - compatible > > @@ -88,14 +107,34 @@ Sub-nodes: > > Value type: > > Definition: Specifies the phandle to the PHY device node > > associated > > with the this dpmac. > > +Optional properties: > > + > > +- iommu-map: Maps an ICID to an IOMMU and associated iommu- > specifier > > + data. > > + > > + The property is an arbitrary number of tuples of > > + (icid-base,iommu,iommu-base,length). > > + > > + Any ICID i in the interval [icid-base, icid-base + length) is > > + associated with the listed IOMMU, with the iommu-specifier > > + (i - icid-base + iommu-base). > > > > Example: > > > > +smmu: iommu@500 { > > + compatible = "arm,mmu-500"; > > + #iommu-cells = <2>; > > This should be 1 if stream-match-mask is present. Bad example is bad :) Agree :). Ill update it. > > Robin. > > > + stream-match-mask = <0x7C00>; > > + ... > > +}; > > + > > fsl_mc: fsl-mc@80c00 { > > compatible = "fsl,qoriq-mc"; > > reg = <0x0008 0x0c00 0 0x40>,/* MC portal > > base */ > > <0x 0x0834 0 0x4>; /* MC control > > reg */ > > msi-parent = <&its>; > > +/* define map for ICIDs 23-64 */ > > +iommu-map = <23 &smmu 23 41>; > > #address-cells = <3>; > > #size-cells = <1>; > > > >
RE: [PATCH 0/7 v5] Support for fsl-mc bus and its devices in SMMU
Thanks Joro, I will be sending it by mid of next week. Regards, Nipun > -Original Message- > From: j...@8bytes.org [mailto:j...@8bytes.org] > Sent: Friday, July 6, 2018 4:43 PM > To: Nipun Gupta > Cc: robin.mur...@arm.com; will.dea...@arm.com; > gre...@linuxfoundation.org; h...@lst.de; m.szyprow...@samsung.com; > shawn...@kernel.org; frowand.l...@gmail.com; iommu@lists.linux- > foundation.org; linux-ker...@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Leo Li > Subject: Re: [PATCH 0/7 v5] Support for fsl-mc bus and its devices in SMMU > > Hi Nipun, > > On Thu, Jun 21, 2018 at 03:59:27AM +, Nipun Gupta wrote: > > Will this patch-set be taken for the next kernel release (and via which > > tree)? > > I can take this through IOMMU tree if nobody objects. Please work out > the last remaining comment on patch 7 with Robin and then re-send with > all Acks and Reviewed-by: tags included. > > Oh, and please use 'iommu/of:' prefix instead of 'iommu: of:' and follow > that sheme for the other patches/prefixes as well. > > Thanks, > > Joerg
RE: [PATCH 0/7 v5] Support for fsl-mc bus and its devices in SMMU
Hi Robin/Greg k-h, Will this patch-set be taken for the next kernel release (and via which tree)? Thanks, Nipun > -Original Message- > From: Nipun Gupta > Sent: Sunday, May 20, 2018 7:20 PM > To: robin.mur...@arm.com; will.dea...@arm.com; robh...@kernel.org; > r...@kernel.org; mark.rutl...@arm.com; catalin.mari...@arm.com; > gre...@linuxfoundation.org; Laurentiu Tudor ; > bhelg...@google.com > Cc: h...@lst.de; j...@8bytes.org; m.szyprow...@samsung.com; > shawn...@kernel.org; frowand.l...@gmail.com; iommu@lists.linux- > foundation.org; linux-ker...@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Leo Li ; Nipun Gupta > > Subject: [PATCH 0/7 v5] Support for fsl-mc bus and its devices in SMMU > > This patchset defines IOMMU DT binding for fsl-mc bus and adds > support in SMMU for fsl-mc bus. > > The patch series is based on top of dma-mapping tree (for-next branch): > http://git.infradead.org/users/hch/dma-mapping.git > > These patches > - Define property 'iommu-map' for fsl-mc bus (patch 1) > - Integrates the fsl-mc bus with the SMMU using this > IOMMU binding (patch 2,3,4) > - Adds the dma configuration support for fsl-mc bus (patch 5, 6) > - Updates the fsl-mc device node with iommu/dma related changes (patch 7) > > Changes in v2: > - use iommu-map property for fsl-mc bus > - rebase over patchset https://patchwork.kernel.org/patch/10317337/ > and make corresponding changes for dma configuration of devices on > fsl-mc bus > > Changes in v3: > - move of_map_rid in drivers/of/address.c > > Changes in v4: > - move of_map_rid in drivers/of/base.c > > Changes in v5: > - break patch 5 in two separate patches (now patch 5/7 and patch 6/7) > - add changelog text in patch 3/7 and patch 5/7 > - typo fix > > Nipun Gupta (7): > Docs: dt: add fsl-mc iommu-map device-tree binding > iommu: of: make of_pci_map_rid() available for other devices too > iommu: support iommu configuration for fsl-mc devices > iommu: arm-smmu: Add support for the fsl-mc bus > bus: fsl-mc: support dma configure for devices on fsl-mc bus > bus: fsl-mc: set coherent dma mask for devices on fsl-mc bus > arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc > > .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 > arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- > drivers/bus/fsl-mc/fsl-mc-bus.c| 16 +++- > drivers/iommu/arm-smmu.c | 7 ++ > drivers/iommu/iommu.c | 21 + > drivers/iommu/of_iommu.c | 25 - > drivers/of/base.c | 102 > + > drivers/of/irq.c | 5 +- > drivers/pci/of.c | 101 > include/linux/fsl/mc.h | 8 ++ > include/linux/iommu.h | 2 + > include/linux/of.h | 11 +++ > include/linux/of_pci.h | 10 -- > 13 files changed, 231 insertions(+), 122 deletions(-) > > -- > 1.9.1
[PATCH 7/7 v5] arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc
fsl-mc bus support the new iommu-map property. Comply to this binding for fsl_mc bus. Signed-off-by: Nipun Gupta Reviewed-by: Laurentiu Tudor --- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 137ef4d..6010505 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -184,6 +184,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + dma-ranges = <0x0 0x0 0x0 0x0 0x1 0x>; clockgen: clocking@130 { compatible = "fsl,ls2080a-clockgen"; @@ -357,6 +358,8 @@ reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; + iommu-map = <0 &smmu 0 0>; /* This is fixed-up by u-boot */ + dma-coherent; #address-cells = <3>; #size-cells = <1>; @@ -460,6 +463,8 @@ compatible = "arm,mmu-500"; reg = <0 0x500 0 0x80>; #global-interrupts = <12>; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; interrupts = <0 13 4>, /* global secure fault */ <0 14 4>, /* combined secure interrupt */ <0 15 4>, /* global non-secure fault */ @@ -502,7 +507,6 @@ <0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>, <0 208 4>, <0 209 4>; - mmu-masters = <&fsl_mc 0x300 0>; }; dspi: dspi@210 { -- 1.9.1
[PATCH 6/7 v5] bus: fsl-mc: set coherent dma mask for devices on fsl-mc bus
of_dma_configure() API expects coherent_dma_mask to be correctly set in the devices. This patch does the needful. Signed-off-by: Nipun Gupta --- drivers/bus/fsl-mc/fsl-mc-bus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index fa43c7d..624828b 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -627,6 +627,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, mc_dev->icid = parent_mc_dev->icid; mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; mc_dev->dev.dma_mask = &mc_dev->dma_mask; + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; dev_set_msi_domain(&mc_dev->dev, dev_get_msi_domain(&parent_mc_dev->dev)); } -- 1.9.1
[PATCH 5/7 v5] bus: fsl-mc: support dma configure for devices on fsl-mc bus
This patch adds support of dma configuration for devices on fsl-mc bus using 'dma_configure' callback for busses. Also, directly calling arch_setup_dma_ops is removed from the fsl-mc bus. Signed-off-by: Nipun Gupta Reviewed-by: Laurentiu Tudor --- drivers/bus/fsl-mc/fsl-mc-bus.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 5d8266c..fa43c7d 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -127,6 +127,16 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int fsl_mc_dma_configure(struct device *dev) +{ + struct device *dma_dev = dev; + + while (dev_is_fsl_mc(dma_dev)) + dma_dev = dma_dev->parent; + + return of_dma_configure(dev, dma_dev->of_node, 0); +} + static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -148,6 +158,7 @@ struct bus_type fsl_mc_bus_type = { .name = "fsl-mc", .match = fsl_mc_bus_match, .uevent = fsl_mc_bus_uevent, + .dma_configure = fsl_mc_dma_configure, .dev_groups = fsl_mc_dev_groups, }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); @@ -633,10 +644,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, goto error_cleanup_dev; } - /* Objects are coherent, unless 'no shareability' flag set. */ - if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true); - /* * The device-specific probe callback will get invoked by device_add() */ -- 1.9.1
[PATCH 4/7 v5] iommu: arm-smmu: Add support for the fsl-mc bus
Implement bus specific support for the fsl-mc bus including registering arm_smmu_ops and bus specific device add operations. Signed-off-by: Nipun Gupta --- drivers/iommu/arm-smmu.c | 7 +++ drivers/iommu/iommu.c| 21 + include/linux/fsl/mc.h | 8 include/linux/iommu.h| 2 ++ 4 files changed, 38 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69e7c60..e1d5090 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -52,6 +52,7 @@ #include #include +#include #include "io-pgtable.h" #include "arm-smmu-regs.h" @@ -1459,6 +1460,8 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) if (dev_is_pci(dev)) group = pci_device_group(dev); + else if (dev_is_fsl_mc(dev)) + group = fsl_mc_device_group(dev); else group = generic_device_group(dev); @@ -2037,6 +2040,10 @@ static void arm_smmu_bus_init(void) bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } #endif +#ifdef CONFIG_FSL_MC_BUS + if (!iommu_present(&fsl_mc_bus_type)) + bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops); +#endif } static int arm_smmu_device_probe(struct platform_device *pdev) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d2aa2320..6d4ce35 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include static struct kset *iommu_group_kset; @@ -987,6 +988,26 @@ struct iommu_group *pci_device_group(struct device *dev) return iommu_group_alloc(); } +/* Get the IOMMU group for device on fsl-mc bus */ +struct iommu_group *fsl_mc_device_group(struct device *dev) +{ + struct device *cont_dev = fsl_mc_cont_dev(dev); + struct iommu_group *group; + + /* Container device is responsible for creating the iommu group */ + if (fsl_mc_is_cont_dev(dev)) { + group = iommu_group_alloc(); + if (IS_ERR(group)) + return NULL; + } else { + get_device(cont_dev); + group = iommu_group_get(cont_dev); + put_device(cont_dev); + } + + return group; +} + /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index f27cb14..dddaca1 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -351,6 +351,14 @@ struct fsl_mc_io { #define dev_is_fsl_mc(_dev) (0) #endif +/* Macro to check if a device is a container device */ +#define fsl_mc_is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & \ + FSL_MC_IS_DPRC) + +/* Macro to get the container device of a MC device */ +#define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \ + (_dev) : (_dev)->parent) + /* * module_fsl_mc_driver() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19938ee..2981200 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -389,6 +389,8 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +/* FSL-MC device grouping function */ +struct iommu_group *fsl_mc_device_group(struct device *dev); /** * struct iommu_fwspec - per-device IOMMU instance data -- 1.9.1
[PATCH 3/7 v5] iommu: support iommu configuration for fsl-mc devices
With of_pci_map_rid available for all the busses, use the function for configuration of devices on fsl-mc bus Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 811e160..284474d 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -24,6 +24,7 @@ #include #include #include +#include #define NO_IOMMU 1 @@ -159,6 +160,23 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) return err; } +static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, + struct device_node *master_np) +{ + struct of_phandle_args iommu_spec = { .args_count = 1 }; + int err; + + err = of_map_rid(master_np, mc_dev->icid, "iommu-map", +"iommu-map-mask", &iommu_spec.np, +iommu_spec.args); + if (err) + return err == -ENODEV ? NO_IOMMU : err; + + err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); + of_node_put(iommu_spec.np); + return err; +} + const struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { @@ -190,6 +208,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, err = pci_for_each_dma_alias(to_pci_dev(dev), of_pci_iommu_init, &info); + } else if (dev_is_fsl_mc(dev)) { + err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); } else { struct of_phandle_args iommu_spec; int idx = 0; -- 1.9.1
[PATCH 2/7 v5] iommu: of: make of_pci_map_rid() available for other devices too
iommu-map property is also used by devices with fsl-mc. This patch moves the of_pci_map_rid to generic location, so that it can be used by other busses too. 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no functional change done in the API. Signed-off-by: Nipun Gupta Reviewed-by: Rob Herring Acked-by: Bjorn Helgaas --- drivers/iommu/of_iommu.c | 5 +-- drivers/of/base.c| 102 +++ drivers/of/irq.c | 5 +-- drivers/pci/of.c | 101 -- include/linux/of.h | 11 + include/linux/of_pci.h | 10 - 6 files changed, 117 insertions(+), 117 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..811e160 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -149,9 +149,8 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_pci_map_rid(info->np, alias, "iommu-map", -"iommu-map-mask", &iommu_spec.np, -iommu_spec.args); + err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", +&iommu_spec.np, iommu_spec.args); if (err) return err == -ENODEV ? NO_IOMMU : err; diff --git a/drivers/of/base.c b/drivers/of/base.c index 848f549..c7aac81 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1995,3 +1995,105 @@ int of_find_last_cache_level(unsigned int cpu) return cache_level; } + +/** + * of_map_rid - Translate a requester ID through a downstream mapping. + * @np: root complex device node. + * @rid: device requester ID to map. + * @map_name: property name of the map to use. + * @map_mask_name: optional property name of the mask to use. + * @target: optional pointer to a target device node. + * @id_out: optional pointer to receive the translated ID. + * + * Given a device requester ID, look up the appropriate implementation-defined + * platform ID and/or the target device which receives transactions on that + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or + * @id_out may be NULL if only the other is required. If @target points to + * a non-NULL device node pointer, only entries targeting that node will be + * matched; if it points to a NULL value, it will receive the device node of + * the first matching target phandle, with a reference held. + * + * Return: 0 on success or a standard error code on failure. + */ +int of_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + u32 map_mask, masked_rid; + int map_len; + const __be32 *map = NULL; + + if (!np || !map_name || (!target && !id_out)) + return -EINVAL; + + map = of_get_property(np, map_name, &map_len); + if (!map) { + if (target) + return -ENODEV; + /* Otherwise, no map implies no translation */ + *id_out = rid; + return 0; + } + + if (!map_len || map_len % (4 * sizeof(*map))) { + pr_err("%pOF: Error: Bad %s length: %d\n", np, + map_name, map_len); + return -EINVAL; + } + + /* The default is to select all bits. */ + map_mask = 0x; + + /* +* Can be overridden by "{iommu,msi}-map-mask" property. +* If of_property_read_u32() fails, the default is used. +*/ + if (map_mask_name) + of_property_read_u32(np, map_mask_name, &map_mask); + + masked_rid = map_mask & rid; + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { + struct device_node *phandle_node; + u32 rid_base = be32_to_cpup(map + 0); + u32 phandle = be32_to_cpup(map + 1); + u32 out_base = be32_to_cpup(map + 2); + u32 rid_len = be32_to_cpup(map + 3); + + if (rid_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, + map_mask, rid_base); + return -EFAULT; + } + + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + continue; + + phandle_node = of_find_node_by_phandle(phandle); + if (!phandle_node) + return -ENODEV; + + if (target) { + if (*target) +
[PATCH 1/7 v5] Docs: dt: add fsl-mc iommu-map device-tree binding
The existing IOMMU bindings cannot be used to specify the relationship between fsl-mc devices and IOMMUs. This patch adds a generic binding for mapping fsl-mc devices to IOMMUs, using iommu-map property. Signed-off-by: Nipun Gupta Reviewed-by: Rob Herring --- .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 ++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt index 6611a7c..8cbed4f 100644 --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt @@ -9,6 +9,25 @@ blocks that can be used to create functional hardware objects/devices such as network interfaces, crypto accelerator instances, L2 switches, etc. +For an overview of the DPAA2 architecture and fsl-mc bus see: +drivers/staging/fsl-mc/README.txt + +As described in the above overview, all DPAA2 objects in a DPRC share the +same hardware "isolation context" and a 10-bit value called an ICID +(isolation context id) is expressed by the hardware to identify +the requester. + +The generic 'iommus' property is insufficient to describe the relationship +between ICIDs and IOMMUs, so an iommu-map property is used to define +the set of possible ICIDs under a root DPRC and how they map to +an IOMMU. + +For generic IOMMU bindings, see +Documentation/devicetree/bindings/iommu/iommu.txt. + +For arm-smmu binding, see: +Documentation/devicetree/bindings/iommu/arm,smmu.txt. + Required properties: - compatible @@ -88,14 +107,34 @@ Sub-nodes: Value type: Definition: Specifies the phandle to the PHY device node associated with the this dpmac. +Optional properties: + +- iommu-map: Maps an ICID to an IOMMU and associated iommu-specifier + data. + + The property is an arbitrary number of tuples of + (icid-base,iommu,iommu-base,length). + + Any ICID i in the interval [icid-base, icid-base + length) is + associated with the listed IOMMU, with the iommu-specifier + (i - icid-base + iommu-base). Example: +smmu: iommu@500 { + compatible = "arm,mmu-500"; + #iommu-cells = <2>; + stream-match-mask = <0x7C00>; + ... +}; + fsl_mc: fsl-mc@80c00 { compatible = "fsl,qoriq-mc"; reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; +/* define map for ICIDs 23-64 */ +iommu-map = <23 &smmu 23 41>; #address-cells = <3>; #size-cells = <1>; -- 1.9.1
[PATCH 0/7 v5] Support for fsl-mc bus and its devices in SMMU
This patchset defines IOMMU DT binding for fsl-mc bus and adds support in SMMU for fsl-mc bus. The patch series is based on top of dma-mapping tree (for-next branch): http://git.infradead.org/users/hch/dma-mapping.git These patches - Define property 'iommu-map' for fsl-mc bus (patch 1) - Integrates the fsl-mc bus with the SMMU using this IOMMU binding (patch 2,3,4) - Adds the dma configuration support for fsl-mc bus (patch 5, 6) - Updates the fsl-mc device node with iommu/dma related changes (patch 7) Changes in v2: - use iommu-map property for fsl-mc bus - rebase over patchset https://patchwork.kernel.org/patch/10317337/ and make corresponding changes for dma configuration of devices on fsl-mc bus Changes in v3: - move of_map_rid in drivers/of/address.c Changes in v4: - move of_map_rid in drivers/of/base.c Changes in v5: - break patch 5 in two separate patches (now patch 5/7 and patch 6/7) - add changelog text in patch 3/7 and patch 5/7 - typo fix Nipun Gupta (7): Docs: dt: add fsl-mc iommu-map device-tree binding iommu: of: make of_pci_map_rid() available for other devices too iommu: support iommu configuration for fsl-mc devices iommu: arm-smmu: Add support for the fsl-mc bus bus: fsl-mc: support dma configure for devices on fsl-mc bus bus: fsl-mc: set coherent dma mask for devices on fsl-mc bus arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- drivers/bus/fsl-mc/fsl-mc-bus.c| 16 +++- drivers/iommu/arm-smmu.c | 7 ++ drivers/iommu/iommu.c | 21 + drivers/iommu/of_iommu.c | 25 - drivers/of/base.c | 102 + drivers/of/irq.c | 5 +- drivers/pci/of.c | 101 include/linux/fsl/mc.h | 8 ++ include/linux/iommu.h | 2 + include/linux/of.h | 11 +++ include/linux/of_pci.h | 10 -- 13 files changed, 231 insertions(+), 122 deletions(-) -- 1.9.1
RE: [PATCH 5/6 v3] bus: fsl-mc: supoprt dma configure for devices on fsl-mc bus
> -Original Message- > From: Laurentiu Tudor > Sent: Monday, May 14, 2018 7:10 PM > To: Nipun Gupta ; robin.mur...@arm.com; > will.dea...@arm.com; mark.rutl...@arm.com; catalin.mari...@arm.com > Cc: h...@lst.de; gre...@linuxfoundation.org; j...@8bytes.org; > robh...@kernel.org; m.szyprow...@samsung.com; shawn...@kernel.org; > frowand.l...@gmail.com; bhelg...@google.com; iommu@lists.linux- > foundation.org; linux-ker...@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Leo Li > Subject: Re: [PATCH 5/6 v3] bus: fsl-mc: supoprt dma configure for devices > on fsl-mc bus > > Hi Nipun, > > On 04/27/2018 01:27 PM, Nipun Gupta wrote: > > Signed-off-by: Nipun Gupta > > --- > > drivers/bus/fsl-mc/fsl-mc-bus.c | 16 > > 1 file changed, 12 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc- > bus.c > > index 5d8266c..624828b 100644 > > --- a/drivers/bus/fsl-mc/fsl-mc-bus.c > > +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c > > @@ -127,6 +127,16 @@ static int fsl_mc_bus_uevent(struct device *dev, > struct kobj_uevent_env *env) > > return 0; > > } > > > > +static int fsl_mc_dma_configure(struct device *dev) > > +{ > > + struct device *dma_dev = dev; > > + > > + while (dev_is_fsl_mc(dma_dev)) > > + dma_dev = dma_dev->parent; > > + > > + return of_dma_configure(dev, dma_dev->of_node, 0); > > +} > > + > > static ssize_t modalias_show(struct device *dev, struct device_attribute > *attr, > > char *buf) > > { > > @@ -148,6 +158,7 @@ struct bus_type fsl_mc_bus_type = { > > .name = "fsl-mc", > > .match = fsl_mc_bus_match, > > .uevent = fsl_mc_bus_uevent, > > + .dma_configure = fsl_mc_dma_configure, > > .dev_groups = fsl_mc_dev_groups, > > }; > > EXPORT_SYMBOL_GPL(fsl_mc_bus_type); > > @@ -616,6 +627,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc > *obj_desc, > > mc_dev->icid = parent_mc_dev->icid; > > mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; > > mc_dev->dev.dma_mask = &mc_dev->dma_mask; > > + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; > > This change seems a bit unrelated to the patch subject. I wonder if it > makes sense to split it it in a distinct patch. Okay. I will spin a v5 after splitting this patch and adding changelog (Greg's comment), fixing typo (Bjorn's comment). Regards, Nipun > > --- > Best Regards, Laurentiu
[PATCH v4 6/6] arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc
fsl-mc bus support the new iommu-map property. Comply to this binding for fsl_mc bus. Signed-off-by: Nipun Gupta --- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 137ef4d..6010505 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -184,6 +184,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + dma-ranges = <0x0 0x0 0x0 0x0 0x1 0x>; clockgen: clocking@130 { compatible = "fsl,ls2080a-clockgen"; @@ -357,6 +358,8 @@ reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; + iommu-map = <0 &smmu 0 0>; /* This is fixed-up by u-boot */ + dma-coherent; #address-cells = <3>; #size-cells = <1>; @@ -460,6 +463,8 @@ compatible = "arm,mmu-500"; reg = <0 0x500 0 0x80>; #global-interrupts = <12>; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; interrupts = <0 13 4>, /* global secure fault */ <0 14 4>, /* combined secure interrupt */ <0 15 4>, /* global non-secure fault */ @@ -502,7 +507,6 @@ <0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>, <0 208 4>, <0 209 4>; - mmu-masters = <&fsl_mc 0x300 0>; }; dspi: dspi@210 { -- 1.9.1
[PATCH v4 5/6] bus: fsl-mc: supoprt dma configure for devices on fsl-mc bus
Signed-off-by: Nipun Gupta --- drivers/bus/fsl-mc/fsl-mc-bus.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 5d8266c..624828b 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -127,6 +127,16 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int fsl_mc_dma_configure(struct device *dev) +{ + struct device *dma_dev = dev; + + while (dev_is_fsl_mc(dma_dev)) + dma_dev = dma_dev->parent; + + return of_dma_configure(dev, dma_dev->of_node, 0); +} + static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -148,6 +158,7 @@ struct bus_type fsl_mc_bus_type = { .name = "fsl-mc", .match = fsl_mc_bus_match, .uevent = fsl_mc_bus_uevent, + .dma_configure = fsl_mc_dma_configure, .dev_groups = fsl_mc_dev_groups, }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); @@ -616,6 +627,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, mc_dev->icid = parent_mc_dev->icid; mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; mc_dev->dev.dma_mask = &mc_dev->dma_mask; + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; dev_set_msi_domain(&mc_dev->dev, dev_get_msi_domain(&parent_mc_dev->dev)); } @@ -633,10 +645,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, goto error_cleanup_dev; } - /* Objects are coherent, unless 'no shareability' flag set. */ - if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true); - /* * The device-specific probe callback will get invoked by device_add() */ -- 1.9.1
[PATCH v4 4/6] iommu: arm-smmu: Add support for the fsl-mc bus
Implement bus specific support for the fsl-mc bus including registering arm_smmu_ops and bus specific device add operations. Signed-off-by: Nipun Gupta --- drivers/iommu/arm-smmu.c | 7 +++ drivers/iommu/iommu.c| 21 + include/linux/fsl/mc.h | 8 include/linux/iommu.h| 2 ++ 4 files changed, 38 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69e7c60..e1d5090 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -52,6 +52,7 @@ #include #include +#include #include "io-pgtable.h" #include "arm-smmu-regs.h" @@ -1459,6 +1460,8 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) if (dev_is_pci(dev)) group = pci_device_group(dev); + else if (dev_is_fsl_mc(dev)) + group = fsl_mc_device_group(dev); else group = generic_device_group(dev); @@ -2037,6 +2040,10 @@ static void arm_smmu_bus_init(void) bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } #endif +#ifdef CONFIG_FSL_MC_BUS + if (!iommu_present(&fsl_mc_bus_type)) + bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops); +#endif } static int arm_smmu_device_probe(struct platform_device *pdev) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d2aa2320..6d4ce35 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include static struct kset *iommu_group_kset; @@ -987,6 +988,26 @@ struct iommu_group *pci_device_group(struct device *dev) return iommu_group_alloc(); } +/* Get the IOMMU group for device on fsl-mc bus */ +struct iommu_group *fsl_mc_device_group(struct device *dev) +{ + struct device *cont_dev = fsl_mc_cont_dev(dev); + struct iommu_group *group; + + /* Container device is responsible for creating the iommu group */ + if (fsl_mc_is_cont_dev(dev)) { + group = iommu_group_alloc(); + if (IS_ERR(group)) + return NULL; + } else { + get_device(cont_dev); + group = iommu_group_get(cont_dev); + put_device(cont_dev); + } + + return group; +} + /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index f27cb14..dddaca1 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -351,6 +351,14 @@ struct fsl_mc_io { #define dev_is_fsl_mc(_dev) (0) #endif +/* Macro to check if a device is a container device */ +#define fsl_mc_is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & \ + FSL_MC_IS_DPRC) + +/* Macro to get the container device of a MC device */ +#define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \ + (_dev) : (_dev)->parent) + /* * module_fsl_mc_driver() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19938ee..2981200 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -389,6 +389,8 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +/* FSL-MC device grouping function */ +struct iommu_group *fsl_mc_device_group(struct device *dev); /** * struct iommu_fwspec - per-device IOMMU instance data -- 1.9.1
[PATCH v4 3/6] iommu: support iommu configuration for fsl-mc devices
Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 811e160..284474d 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -24,6 +24,7 @@ #include #include #include +#include #define NO_IOMMU 1 @@ -159,6 +160,23 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) return err; } +static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, + struct device_node *master_np) +{ + struct of_phandle_args iommu_spec = { .args_count = 1 }; + int err; + + err = of_map_rid(master_np, mc_dev->icid, "iommu-map", +"iommu-map-mask", &iommu_spec.np, +iommu_spec.args); + if (err) + return err == -ENODEV ? NO_IOMMU : err; + + err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); + of_node_put(iommu_spec.np); + return err; +} + const struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { @@ -190,6 +208,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, err = pci_for_each_dma_alias(to_pci_dev(dev), of_pci_iommu_init, &info); + } else if (dev_is_fsl_mc(dev)) { + err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); } else { struct of_phandle_args iommu_spec; int idx = 0; -- 1.9.1
[PATCH v4 2/6] iommu: of: make of_pci_map_rid() available for other devices too
iommu-map property is also used by devices with fsl-mc. This patch moves the of_pci_map_rid to generic location, so that it can be used by other busses too. 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no functional change done in the API. Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 5 +-- drivers/of/base.c| 102 +++ drivers/of/irq.c | 5 +-- drivers/pci/of.c | 101 -- include/linux/of.h | 11 + include/linux/of_pci.h | 10 - 6 files changed, 117 insertions(+), 117 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..811e160 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -149,9 +149,8 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_pci_map_rid(info->np, alias, "iommu-map", -"iommu-map-mask", &iommu_spec.np, -iommu_spec.args); + err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", +&iommu_spec.np, iommu_spec.args); if (err) return err == -ENODEV ? NO_IOMMU : err; diff --git a/drivers/of/base.c b/drivers/of/base.c index 848f549..c7aac81 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1995,3 +1995,105 @@ int of_find_last_cache_level(unsigned int cpu) return cache_level; } + +/** + * of_map_rid - Translate a requester ID through a downstream mapping. + * @np: root complex device node. + * @rid: device requester ID to map. + * @map_name: property name of the map to use. + * @map_mask_name: optional property name of the mask to use. + * @target: optional pointer to a target device node. + * @id_out: optional pointer to receive the translated ID. + * + * Given a device requester ID, look up the appropriate implementation-defined + * platform ID and/or the target device which receives transactions on that + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or + * @id_out may be NULL if only the other is required. If @target points to + * a non-NULL device node pointer, only entries targeting that node will be + * matched; if it points to a NULL value, it will receive the device node of + * the first matching target phandle, with a reference held. + * + * Return: 0 on success or a standard error code on failure. + */ +int of_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + u32 map_mask, masked_rid; + int map_len; + const __be32 *map = NULL; + + if (!np || !map_name || (!target && !id_out)) + return -EINVAL; + + map = of_get_property(np, map_name, &map_len); + if (!map) { + if (target) + return -ENODEV; + /* Otherwise, no map implies no translation */ + *id_out = rid; + return 0; + } + + if (!map_len || map_len % (4 * sizeof(*map))) { + pr_err("%pOF: Error: Bad %s length: %d\n", np, + map_name, map_len); + return -EINVAL; + } + + /* The default is to select all bits. */ + map_mask = 0x; + + /* +* Can be overridden by "{iommu,msi}-map-mask" property. +* If of_property_read_u32() fails, the default is used. +*/ + if (map_mask_name) + of_property_read_u32(np, map_mask_name, &map_mask); + + masked_rid = map_mask & rid; + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { + struct device_node *phandle_node; + u32 rid_base = be32_to_cpup(map + 0); + u32 phandle = be32_to_cpup(map + 1); + u32 out_base = be32_to_cpup(map + 2); + u32 rid_len = be32_to_cpup(map + 3); + + if (rid_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, + map_mask, rid_base); + return -EFAULT; + } + + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + continue; + + phandle_node = of_find_node_by_phandle(phandle); + if (!phandle_node) + return -ENODEV; + + if (target) { + if (*target) + of_node_
[PATCH v4 1/6] Docs: dt: add fsl-mc iommu-map device-tree binding
The existing IOMMU bindings cannot be used to specify the relationship between fsl-mc devices and IOMMUs. This patch adds a generic binding for mapping fsl-mc devices to IOMMUs, using iommu-map property. Signed-off-by: Nipun Gupta Reviewed-by: Rob Herring --- .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 ++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt index 6611a7c..8cbed4f 100644 --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt @@ -9,6 +9,25 @@ blocks that can be used to create functional hardware objects/devices such as network interfaces, crypto accelerator instances, L2 switches, etc. +For an overview of the DPAA2 architecture and fsl-mc bus see: +drivers/staging/fsl-mc/README.txt + +As described in the above overview, all DPAA2 objects in a DPRC share the +same hardware "isolation context" and a 10-bit value called an ICID +(isolation context id) is expressed by the hardware to identify +the requester. + +The generic 'iommus' property is insufficient to describe the relationship +between ICIDs and IOMMUs, so an iommu-map property is used to define +the set of possible ICIDs under a root DPRC and how they map to +an IOMMU. + +For generic IOMMU bindings, see +Documentation/devicetree/bindings/iommu/iommu.txt. + +For arm-smmu binding, see: +Documentation/devicetree/bindings/iommu/arm,smmu.txt. + Required properties: - compatible @@ -88,14 +107,34 @@ Sub-nodes: Value type: Definition: Specifies the phandle to the PHY device node associated with the this dpmac. +Optional properties: + +- iommu-map: Maps an ICID to an IOMMU and associated iommu-specifier + data. + + The property is an arbitrary number of tuples of + (icid-base,iommu,iommu-base,length). + + Any ICID i in the interval [icid-base, icid-base + length) is + associated with the listed IOMMU, with the iommu-specifier + (i - icid-base + iommu-base). Example: +smmu: iommu@500 { + compatible = "arm,mmu-500"; + #iommu-cells = <2>; + stream-match-mask = <0x7C00>; + ... +}; + fsl_mc: fsl-mc@80c00 { compatible = "fsl,qoriq-mc"; reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; +/* define map for ICIDs 23-64 */ +iommu-map = <23 &smmu 23 41>; #address-cells = <3>; #size-cells = <1>; -- 1.9.1
[PATCH v4 0/6] Support for fsl-mc bus and its devices in SMMU
This patchset defines IOMMU DT binding for fsl-mc bus and adds support in SMMU for fsl-mc bus. This patch series is dependent on patset: https://patchwork.kernel.org/patch/10317337/ These patches - Define property 'iommu-map' for fsl-mc bus (patch 1) - Integrates the fsl-mc bus with the SMMU using this IOMMU binding (patch 2,3,4) - Adds the dma configuration support for fsl-mc bus (patch 5) - Updates the fsl-mc device node with iommu/dma related changes (patch6) Changes in v2: - use iommu-map property for fsl-mc bus - rebase over patchset https://patchwork.kernel.org/patch/10317337/ and make corresponding changes for dma configuration of devices on fsl-mc bus Changes in v3: - move of_map_rid in drivers/of/address.c Changes in v4: - move of_map_rid in drivers/of/base.c Nipun Gupta (6): Docs: dt: add fsl-mc iommu-map device-tree binding iommu: of: make of_pci_map_rid() available for other devices too iommu: support iommu configuration for fsl-mc devices iommu: arm-smmu: Add support for the fsl-mc bus bus: fsl-mc: supoprt dma configure for devices on fsl-mc bus arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- drivers/bus/fsl-mc/fsl-mc-bus.c| 16 +++- drivers/iommu/arm-smmu.c | 7 ++ drivers/iommu/iommu.c | 21 + drivers/iommu/of_iommu.c | 25 - drivers/of/base.c | 102 + drivers/of/irq.c | 5 +- drivers/pci/of.c | 101 include/linux/fsl/mc.h | 8 ++ include/linux/iommu.h | 2 + include/linux/of.h | 11 +++ include/linux/of_pci.h | 10 -- 13 files changed, 231 insertions(+), 122 deletions(-) -- 1.9.1
RE: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
> -Original Message- > From: Rob Herring [mailto:r...@kernel.org] > Sent: Friday, April 27, 2018 10:46 PM > To: Nipun Gupta > Cc: robin.mur...@arm.com; will.dea...@arm.com; mark.rutl...@arm.com; > catalin.mari...@arm.com; h...@lst.de; gre...@linuxfoundation.org; > j...@8bytes.org; m.szyprow...@samsung.com; shawn...@kernel.org; > frowand.l...@gmail.com; bhelg...@google.com; iommu@lists.linux- > foundation.org; linux-ker...@vger.kernel.org; devicet...@vger.kernel.org; > linux-arm-ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; linux- > p...@vger.kernel.org; Bharat Bhushan ; > stuyo...@gmail.com; Laurentiu Tudor ; Leo Li > > Subject: Re: [PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for > other devices too > > On Fri, Apr 27, 2018 at 03:57:02PM +0530, Nipun Gupta wrote: > > iommu-map property is also used by devices with fsl-mc. This > > patch moves the of_pci_map_rid to generic location, so that it > > can be used by other busses too. > > > > 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no > > functional change done in the API. > > > > Signed-off-by: Nipun Gupta > > --- > > drivers/iommu/of_iommu.c | 6 +-- > > drivers/of/address.c | 102 > + > > drivers/of/irq.c | 7 ++-- > > drivers/pci/of.c | 101 > > > > include/linux/of_address.h | 11 + > > include/linux/of_pci.h | 10 - > > 6 files changed, 120 insertions(+), 117 deletions(-) > > of/address.c isn't really the best fit either, though I don't have a > better suggestion. > > I'm guessing this breaks on Sparc which doesn't build of/address.c. > I guess move it to base.c and of.h if that is the case. Sure, that makes sense. Thank you for the suggestion !! I'll spin off new version with this change. Regards, Nipun > > Rob
[PATCH 6/6 v3] arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc
fsl-mc bus support the new iommu-map property. Comply to this binding for fsl_mc bus. Signed-off-by: Nipun Gupta --- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 137ef4d..6010505 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -184,6 +184,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + dma-ranges = <0x0 0x0 0x0 0x0 0x1 0x>; clockgen: clocking@130 { compatible = "fsl,ls2080a-clockgen"; @@ -357,6 +358,8 @@ reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; + iommu-map = <0 &smmu 0 0>; /* This is fixed-up by u-boot */ + dma-coherent; #address-cells = <3>; #size-cells = <1>; @@ -460,6 +463,8 @@ compatible = "arm,mmu-500"; reg = <0 0x500 0 0x80>; #global-interrupts = <12>; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; interrupts = <0 13 4>, /* global secure fault */ <0 14 4>, /* combined secure interrupt */ <0 15 4>, /* global non-secure fault */ @@ -502,7 +507,6 @@ <0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>, <0 208 4>, <0 209 4>; - mmu-masters = <&fsl_mc 0x300 0>; }; dspi: dspi@210 { -- 1.9.1
[PATCH 5/6 v3] bus: fsl-mc: supoprt dma configure for devices on fsl-mc bus
Signed-off-by: Nipun Gupta --- drivers/bus/fsl-mc/fsl-mc-bus.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 5d8266c..624828b 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -127,6 +127,16 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int fsl_mc_dma_configure(struct device *dev) +{ + struct device *dma_dev = dev; + + while (dev_is_fsl_mc(dma_dev)) + dma_dev = dma_dev->parent; + + return of_dma_configure(dev, dma_dev->of_node, 0); +} + static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -148,6 +158,7 @@ struct bus_type fsl_mc_bus_type = { .name = "fsl-mc", .match = fsl_mc_bus_match, .uevent = fsl_mc_bus_uevent, + .dma_configure = fsl_mc_dma_configure, .dev_groups = fsl_mc_dev_groups, }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); @@ -616,6 +627,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, mc_dev->icid = parent_mc_dev->icid; mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; mc_dev->dev.dma_mask = &mc_dev->dma_mask; + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; dev_set_msi_domain(&mc_dev->dev, dev_get_msi_domain(&parent_mc_dev->dev)); } @@ -633,10 +645,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, goto error_cleanup_dev; } - /* Objects are coherent, unless 'no shareability' flag set. */ - if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true); - /* * The device-specific probe callback will get invoked by device_add() */ -- 1.9.1
[PATCH 4/6 v3] iommu: arm-smmu: Add support for the fsl-mc bus
Implement bus specific support for the fsl-mc bus including registering arm_smmu_ops and bus specific device add operations. Signed-off-by: Nipun Gupta --- drivers/iommu/arm-smmu.c | 7 +++ drivers/iommu/iommu.c| 21 + include/linux/fsl/mc.h | 8 include/linux/iommu.h| 2 ++ 4 files changed, 38 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69e7c60..e1d5090 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -52,6 +52,7 @@ #include #include +#include #include "io-pgtable.h" #include "arm-smmu-regs.h" @@ -1459,6 +1460,8 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) if (dev_is_pci(dev)) group = pci_device_group(dev); + else if (dev_is_fsl_mc(dev)) + group = fsl_mc_device_group(dev); else group = generic_device_group(dev); @@ -2037,6 +2040,10 @@ static void arm_smmu_bus_init(void) bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } #endif +#ifdef CONFIG_FSL_MC_BUS + if (!iommu_present(&fsl_mc_bus_type)) + bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops); +#endif } static int arm_smmu_device_probe(struct platform_device *pdev) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d2aa2320..6d4ce35 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include static struct kset *iommu_group_kset; @@ -987,6 +988,26 @@ struct iommu_group *pci_device_group(struct device *dev) return iommu_group_alloc(); } +/* Get the IOMMU group for device on fsl-mc bus */ +struct iommu_group *fsl_mc_device_group(struct device *dev) +{ + struct device *cont_dev = fsl_mc_cont_dev(dev); + struct iommu_group *group; + + /* Container device is responsible for creating the iommu group */ + if (fsl_mc_is_cont_dev(dev)) { + group = iommu_group_alloc(); + if (IS_ERR(group)) + return NULL; + } else { + get_device(cont_dev); + group = iommu_group_get(cont_dev); + put_device(cont_dev); + } + + return group; +} + /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index f27cb14..dddaca1 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -351,6 +351,14 @@ struct fsl_mc_io { #define dev_is_fsl_mc(_dev) (0) #endif +/* Macro to check if a device is a container device */ +#define fsl_mc_is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & \ + FSL_MC_IS_DPRC) + +/* Macro to get the container device of a MC device */ +#define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \ + (_dev) : (_dev)->parent) + /* * module_fsl_mc_driver() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19938ee..2981200 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -389,6 +389,8 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +/* FSL-MC device grouping function */ +struct iommu_group *fsl_mc_device_group(struct device *dev); /** * struct iommu_fwspec - per-device IOMMU instance data -- 1.9.1
[PATCH 3/6 v3] iommu: support iommu configuration for fsl-mc devices
Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index ea9ecef..3687882 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -25,6 +25,7 @@ #include #include #include +#include #define NO_IOMMU 1 @@ -160,6 +161,23 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) return err; } +static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, + struct device_node *master_np) +{ + struct of_phandle_args iommu_spec = { .args_count = 1 }; + int err; + + err = of_map_rid(master_np, mc_dev->icid, "iommu-map", +"iommu-map-mask", &iommu_spec.np, +iommu_spec.args); + if (err) + return err == -ENODEV ? NO_IOMMU : err; + + err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); + of_node_put(iommu_spec.np); + return err; +} + const struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { @@ -191,6 +209,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, err = pci_for_each_dma_alias(to_pci_dev(dev), of_pci_iommu_init, &info); + } else if (dev_is_fsl_mc(dev)) { + err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); } else { struct of_phandle_args iommu_spec; int idx = 0; -- 1.9.1
[PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
iommu-map property is also used by devices with fsl-mc. This patch moves the of_pci_map_rid to generic location, so that it can be used by other busses too. 'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no functional change done in the API. Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 6 +-- drivers/of/address.c | 102 + drivers/of/irq.c | 7 ++-- drivers/pci/of.c | 101 include/linux/of_address.h | 11 + include/linux/of_pci.h | 10 - 6 files changed, 120 insertions(+), 117 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..ea9ecef 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -149,9 +150,8 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_pci_map_rid(info->np, alias, "iommu-map", -"iommu-map-mask", &iommu_spec.np, -iommu_spec.args); + err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", +&iommu_spec.np, iommu_spec.args); if (err) return err == -ENODEV ? NO_IOMMU : err; diff --git a/drivers/of/address.c b/drivers/of/address.c index 5334991..4163f24 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -985,3 +985,105 @@ bool of_dma_is_coherent(struct device_node *np) return false; } EXPORT_SYMBOL_GPL(of_dma_is_coherent); + +/** + * of_map_rid - Translate a requester ID through a downstream mapping. + * @np: root complex device node. + * @rid: device requester ID to map. + * @map_name: property name of the map to use. + * @map_mask_name: optional property name of the mask to use. + * @target: optional pointer to a target device node. + * @id_out: optional pointer to receive the translated ID. + * + * Given a device requester ID, look up the appropriate implementation-defined + * platform ID and/or the target device which receives transactions on that + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or + * @id_out may be NULL if only the other is required. If @target points to + * a non-NULL device node pointer, only entries targeting that node will be + * matched; if it points to a NULL value, it will receive the device node of + * the first matching target phandle, with a reference held. + * + * Return: 0 on success or a standard error code on failure. + */ +int of_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + u32 map_mask, masked_rid; + int map_len; + const __be32 *map = NULL; + + if (!np || !map_name || (!target && !id_out)) + return -EINVAL; + + map = of_get_property(np, map_name, &map_len); + if (!map) { + if (target) + return -ENODEV; + /* Otherwise, no map implies no translation */ + *id_out = rid; + return 0; + } + + if (!map_len || map_len % (4 * sizeof(*map))) { + pr_err("%pOF: Error: Bad %s length: %d\n", np, + map_name, map_len); + return -EINVAL; + } + + /* The default is to select all bits. */ + map_mask = 0x; + + /* +* Can be overridden by "{iommu,msi}-map-mask" property. +* If of_property_read_u32() fails, the default is used. +*/ + if (map_mask_name) + of_property_read_u32(np, map_mask_name, &map_mask); + + masked_rid = map_mask & rid; + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { + struct device_node *phandle_node; + u32 rid_base = be32_to_cpup(map + 0); + u32 phandle = be32_to_cpup(map + 1); + u32 out_base = be32_to_cpup(map + 2); + u32 rid_len = be32_to_cpup(map + 3); + + if (rid_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, + map_mask, rid_base); + return -EFAULT; + } + + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + continue; + + phandle_node = of_find_node_by_phandle(phandle); + if (!phandle_node) + return -ENODEV;
[PATCH 1/6 v3] Docs: dt: add fsl-mc iommu-map device-tree binding
The existing IOMMU bindings cannot be used to specify the relationship between fsl-mc devices and IOMMUs. This patch adds a generic binding for mapping fsl-mc devices to IOMMUs, using iommu-map property. Signed-off-by: Nipun Gupta --- .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 ++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt index 6611a7c..8cbed4f 100644 --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt @@ -9,6 +9,25 @@ blocks that can be used to create functional hardware objects/devices such as network interfaces, crypto accelerator instances, L2 switches, etc. +For an overview of the DPAA2 architecture and fsl-mc bus see: +drivers/staging/fsl-mc/README.txt + +As described in the above overview, all DPAA2 objects in a DPRC share the +same hardware "isolation context" and a 10-bit value called an ICID +(isolation context id) is expressed by the hardware to identify +the requester. + +The generic 'iommus' property is insufficient to describe the relationship +between ICIDs and IOMMUs, so an iommu-map property is used to define +the set of possible ICIDs under a root DPRC and how they map to +an IOMMU. + +For generic IOMMU bindings, see +Documentation/devicetree/bindings/iommu/iommu.txt. + +For arm-smmu binding, see: +Documentation/devicetree/bindings/iommu/arm,smmu.txt. + Required properties: - compatible @@ -88,14 +107,34 @@ Sub-nodes: Value type: Definition: Specifies the phandle to the PHY device node associated with the this dpmac. +Optional properties: + +- iommu-map: Maps an ICID to an IOMMU and associated iommu-specifier + data. + + The property is an arbitrary number of tuples of + (icid-base,iommu,iommu-base,length). + + Any ICID i in the interval [icid-base, icid-base + length) is + associated with the listed IOMMU, with the iommu-specifier + (i - icid-base + iommu-base). Example: +smmu: iommu@500 { + compatible = "arm,mmu-500"; + #iommu-cells = <2>; + stream-match-mask = <0x7C00>; + ... +}; + fsl_mc: fsl-mc@80c00 { compatible = "fsl,qoriq-mc"; reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; +/* define map for ICIDs 23-64 */ +iommu-map = <23 &smmu 23 41>; #address-cells = <3>; #size-cells = <1>; -- 1.9.1
[PATCH 0/6 v3] Support for fsl-mc bus and its devices in SMMU
This patchset defines IOMMU DT binding for fsl-mc bus and adds support in SMMU for fsl-mc bus. This patch series is dependent on patset: https://patchwork.kernel.org/patch/10317337/ These patches - Define property 'iommu-map' for fsl-mc bus (patch 1) - Integrates the fsl-mc bus with the SMMU using this IOMMU binding (patch 2,3,4) - Adds the dma configuration support for fsl-mc bus (patch 5) - Updates the fsl-mc device node with iommu/dma related changes (patch6) Changes in v2: - use iommu-map property for fsl-mc bus - rebase over patchset https://patchwork.kernel.org/patch/10317337/ and make corresponding changes for dma configuration of devices on fsl-mc bus Changes in v3: - move of_map_rid in drivers/of/address.c Nipun Gupta (6): Docs: dt: add fsl-mc iommu-map device-tree binding iommu: of: make of_pci_map_rid() available for other devices too iommu: support iommu configuration for fsl-mc devices iommu: arm-smmu: Add support for the fsl-mc bus bus: fsl-mc: supoprt dma configure for devices on fsl-mc bus arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- drivers/bus/fsl-mc/fsl-mc-bus.c| 16 +++- drivers/iommu/arm-smmu.c | 7 ++ drivers/iommu/iommu.c | 21 + drivers/iommu/of_iommu.c | 26 +- drivers/of/address.c | 102 + drivers/of/irq.c | 7 +- drivers/pci/of.c | 101 include/linux/fsl/mc.h | 8 ++ include/linux/iommu.h | 2 + include/linux/of_address.h | 11 +++ include/linux/of_pci.h | 10 -- 13 files changed, 234 insertions(+), 122 deletions(-) -- 1.9.1
RE: [PATCH 2/6 v2] iommu: of: make of_pci_map_rid() available for other devices too
> -Original Message- > From: Robin Murphy [mailto:robin.mur...@arm.com] > Sent: Tuesday, April 17, 2018 10:23 PM > To: Nipun Gupta ; robh...@kernel.org; > frowand.l...@gmail.com > Cc: will.dea...@arm.com; mark.rutl...@arm.com; catalin.mari...@arm.com; > h...@lst.de; gre...@linuxfoundation.org; j...@8bytes.org; > m.szyprow...@samsung.com; shawn...@kernel.org; bhelg...@google.com; > io...@lists.linux-foundation.org; linux-ker...@vger.kernel.org; > devicet...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; linuxppc- > d...@lists.ozlabs.org; linux-...@vger.kernel.org; Bharat Bhushan > ; stuyo...@gmail.com; Laurentiu Tudor > ; Leo Li > Subject: Re: [PATCH 2/6 v2] iommu: of: make of_pci_map_rid() available for > other devices too > > On 17/04/18 11:21, Nipun Gupta wrote: > > iommu-map property is also used by devices with fsl-mc. This patch > > moves the of_pci_map_rid to generic location, so that it can be used > > by other busses too. > > > > Signed-off-by: Nipun Gupta > > --- > > drivers/iommu/of_iommu.c | 106 > > +-- > > Doesn't this break "msi-parent" parsing for !CONFIG_OF_IOMMU? I guess you > don't want fsl-mc to have to depend on PCI, but this looks like a step in the > wrong direction. Thanks for pointing out. Agree, this will break "msi-parent" parsing for !CONFIG_OF_IOMMU case. > > I'm not entirely sure where of_map_rid() fits best, but from a quick look > around > the least-worst option might be drivers/of/of_address.c, unless Rob and Frank > have a better idea of where generic DT-based ID translation routines could > live? > > > drivers/of/irq.c | 6 +-- > > drivers/pci/of.c | 101 > > > > include/linux/of_iommu.h | 11 + > > include/linux/of_pci.h | 10 - > > 5 files changed, 117 insertions(+), 117 deletions(-) > > [...] > > struct of_pci_iommu_alias_info { > > struct device *dev; > > struct device_node *np; > > @@ -149,9 +249,9 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 > alias, void *data) > > struct of_phandle_args iommu_spec = { .args_count = 1 }; > > int err; > > > > - err = of_pci_map_rid(info->np, alias, "iommu-map", > > -"iommu-map-mask", &iommu_spec.np, > > -iommu_spec.args); > > + err = of_map_rid(info->np, alias, "iommu-map", > > +"iommu-map-mask", &iommu_spec.np, > > +iommu_spec.args); > > Super-nit: Apparently I missed rewrapping this to 2 lines in d87beb749281, > but if > it's being touched again, that would be nice ;) Sure.. I'll take care of this in the next version :) Regards, Nipun
[PATCH 6/6 v2] arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc
Fsl-mc bus now support the iommu-map property. Comply to this binding for fsl_mc bus. This patch also updates the dts w.r.t. the DMA configuration. Signed-off-by: Nipun Gupta --- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index f3a40af..1b1c5eb 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -135,6 +135,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + dma-ranges = <0x0 0x0 0x0 0x0 0x1 0x>; clockgen: clocking@130 { compatible = "fsl,ls2080a-clockgen"; @@ -357,6 +358,8 @@ reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; + iommu-map = <0 &smmu 0 0>; /* This is fixed-up by u-boot */ + dma-coherent; #address-cells = <3>; #size-cells = <1>; @@ -460,6 +463,8 @@ compatible = "arm,mmu-500"; reg = <0 0x500 0 0x80>; #global-interrupts = <12>; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; interrupts = <0 13 4>, /* global secure fault */ <0 14 4>, /* combined secure interrupt */ <0 15 4>, /* global non-secure fault */ @@ -502,7 +507,6 @@ <0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>, <0 208 4>, <0 209 4>; - mmu-masters = <&fsl_mc 0x300 0>; }; dspi: dspi@210 { -- 1.9.1
[PATCH 5/6 v2] bus: fsl-mc: supoprt dma configure for devices on fsl-mc bus
Signed-off-by: Nipun Gupta --- drivers/bus/fsl-mc/fsl-mc-bus.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 5d8266c..624828b 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -127,6 +127,16 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } +static int fsl_mc_dma_configure(struct device *dev) +{ + struct device *dma_dev = dev; + + while (dev_is_fsl_mc(dma_dev)) + dma_dev = dma_dev->parent; + + return of_dma_configure(dev, dma_dev->of_node, 0); +} + static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -148,6 +158,7 @@ struct bus_type fsl_mc_bus_type = { .name = "fsl-mc", .match = fsl_mc_bus_match, .uevent = fsl_mc_bus_uevent, + .dma_configure = fsl_mc_dma_configure, .dev_groups = fsl_mc_dev_groups, }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); @@ -616,6 +627,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, mc_dev->icid = parent_mc_dev->icid; mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; mc_dev->dev.dma_mask = &mc_dev->dma_mask; + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; dev_set_msi_domain(&mc_dev->dev, dev_get_msi_domain(&parent_mc_dev->dev)); } @@ -633,10 +645,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, goto error_cleanup_dev; } - /* Objects are coherent, unless 'no shareability' flag set. */ - if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true); - /* * The device-specific probe callback will get invoked by device_add() */ -- 1.9.1
[PATCH 4/6 v2] iommu: arm-smmu: Add support for the fsl-mc bus
Implement bus specific support for the fsl-mc bus including registering arm_smmu_ops and bus specific device add operations. Signed-off-by: Nipun Gupta --- drivers/iommu/arm-smmu.c | 7 +++ drivers/iommu/iommu.c| 21 + include/linux/fsl/mc.h | 8 include/linux/iommu.h| 2 ++ 4 files changed, 38 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69e7c60..e1d5090 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -52,6 +52,7 @@ #include #include +#include #include "io-pgtable.h" #include "arm-smmu-regs.h" @@ -1459,6 +1460,8 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) if (dev_is_pci(dev)) group = pci_device_group(dev); + else if (dev_is_fsl_mc(dev)) + group = fsl_mc_device_group(dev); else group = generic_device_group(dev); @@ -2037,6 +2040,10 @@ static void arm_smmu_bus_init(void) bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } #endif +#ifdef CONFIG_FSL_MC_BUS + if (!iommu_present(&fsl_mc_bus_type)) + bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops); +#endif } static int arm_smmu_device_probe(struct platform_device *pdev) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 69fef99..fbeebb2 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include static struct kset *iommu_group_kset; @@ -987,6 +988,26 @@ struct iommu_group *pci_device_group(struct device *dev) return iommu_group_alloc(); } +/* Get the IOMMU group for device on fsl-mc bus */ +struct iommu_group *fsl_mc_device_group(struct device *dev) +{ + struct device *cont_dev = fsl_mc_cont_dev(dev); + struct iommu_group *group; + + /* Container device is responsible for creating the iommu group */ + if (fsl_mc_is_cont_dev(dev)) { + group = iommu_group_alloc(); + if (IS_ERR(group)) + return NULL; + } else { + get_device(cont_dev); + group = iommu_group_get(cont_dev); + put_device(cont_dev); + } + + return group; +} + /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index f27cb14..dddaca1 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -351,6 +351,14 @@ struct fsl_mc_io { #define dev_is_fsl_mc(_dev) (0) #endif +/* Macro to check if a device is a container device */ +#define fsl_mc_is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & \ + FSL_MC_IS_DPRC) + +/* Macro to get the container device of a MC device */ +#define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \ + (_dev) : (_dev)->parent) + /* * module_fsl_mc_driver() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 41b8c57..00a460b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -389,6 +389,8 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +/* FSL-MC device grouping function */ +struct iommu_group *fsl_mc_device_group(struct device *dev); /** * struct iommu_fwspec - per-device IOMMU instance data -- 1.9.1
[PATCH 3/6 v2] iommu: support iommu configuration for fsl-mc devices
Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 4e7712f..af4fc3b 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -24,6 +24,7 @@ #include #include #include +#include #define NO_IOMMU 1 @@ -260,6 +261,23 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) return err; } +static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, + struct device_node *master_np) +{ + struct of_phandle_args iommu_spec = { .args_count = 1 }; + int err; + + err = of_map_rid(master_np, mc_dev->icid, "iommu-map", +"iommu-map-mask", &iommu_spec.np, +iommu_spec.args); + if (err) + return err == -ENODEV ? NO_IOMMU : err; + + err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); + of_node_put(iommu_spec.np); + return err; +} + const struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { @@ -291,6 +309,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, err = pci_for_each_dma_alias(to_pci_dev(dev), of_pci_iommu_init, &info); + } else if (dev_is_fsl_mc(dev)) { + err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); } else { struct of_phandle_args iommu_spec; int idx = 0; -- 1.9.1
[PATCH 2/6 v2] iommu: of: make of_pci_map_rid() available for other devices too
iommu-map property is also used by devices with fsl-mc. This patch moves the of_pci_map_rid to generic location, so that it can be used by other busses too. Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 106 +-- drivers/of/irq.c | 6 +-- drivers/pci/of.c | 101 include/linux/of_iommu.h | 11 + include/linux/of_pci.h | 10 - 5 files changed, 117 insertions(+), 117 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..4e7712f 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -138,6 +138,106 @@ static int of_iommu_xlate(struct device *dev, return ops->of_xlate(dev, iommu_spec); } +/** + * of_map_rid - Translate a requester ID through a downstream mapping. + * @np: root complex device node. + * @rid: device requester ID to map. + * @map_name: property name of the map to use. + * @map_mask_name: optional property name of the mask to use. + * @target: optional pointer to a target device node. + * @id_out: optional pointer to receive the translated ID. + * + * Given a device requester ID, look up the appropriate implementation-defined + * platform ID and/or the target device which receives transactions on that + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or + * @id_out may be NULL if only the other is required. If @target points to + * a non-NULL device node pointer, only entries targeting that node will be + * matched; if it points to a NULL value, it will receive the device node of + * the first matching target phandle, with a reference held. + * + * Return: 0 on success or a standard error code on failure. + */ +int of_map_rid(struct device_node *np, u32 rid, + const char *map_name, const char *map_mask_name, + struct device_node **target, u32 *id_out) +{ + u32 map_mask, masked_rid; + int map_len; + const __be32 *map = NULL; + + if (!np || !map_name || (!target && !id_out)) + return -EINVAL; + + map = of_get_property(np, map_name, &map_len); + if (!map) { + if (target) + return -ENODEV; + /* Otherwise, no map implies no translation */ + *id_out = rid; + return 0; + } + + if (!map_len || map_len % (4 * sizeof(*map))) { + pr_err("%pOF: Error: Bad %s length: %d\n", np, + map_name, map_len); + return -EINVAL; + } + + /* The default is to select all bits. */ + map_mask = 0x; + + /* +* Can be overridden by "{iommu,msi}-map-mask" property. +*/ + if (map_mask_name) + of_property_read_u32(np, map_mask_name, &map_mask); + + masked_rid = map_mask & rid; + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { + struct device_node *phandle_node; + u32 rid_base = be32_to_cpup(map + 0); + u32 phandle = be32_to_cpup(map + 1); + u32 out_base = be32_to_cpup(map + 2); + u32 rid_len = be32_to_cpup(map + 3); + + if (rid_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, + map_mask, rid_base); + return -EFAULT; + } + + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + continue; + + phandle_node = of_find_node_by_phandle(phandle); + if (!phandle_node) + return -ENODEV; + + if (target) { + if (*target) + of_node_put(phandle_node); + else + *target = phandle_node; + + if (*target != phandle_node) + continue; + } + + if (id_out) + *id_out = masked_rid - rid_base + out_base; + + pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n", + np, map_name, map_mask, rid_base, out_base, + rid_len, rid, masked_rid - rid_base + out_base); + return 0; + } + + pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n", + np, map_name, rid, target && *target ? *target : NULL); + return -EFAULT; +} + struct of_pci_iommu_alias_info { struct device *dev; struct device_node *np; @@ -149,9 +249,9 @@ static int of_pci_i
[PATCH 1/6 v2] Docs: dt: add fsl-mc iommu-map device-tree binding
The existing IOMMU bindings cannot be used to specify the relationship between fsl-mc devices and IOMMUs. This patch adds a generic binding for mapping fsl-mc devices to IOMMUs, using iommu-map property. Signed-off-by: Nipun Gupta --- .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 ++ 1 file changed, 39 insertions(+) diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt index 6611a7c..8cbed4f 100644 --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt @@ -9,6 +9,25 @@ blocks that can be used to create functional hardware objects/devices such as network interfaces, crypto accelerator instances, L2 switches, etc. +For an overview of the DPAA2 architecture and fsl-mc bus see: +drivers/staging/fsl-mc/README.txt + +As described in the above overview, all DPAA2 objects in a DPRC share the +same hardware "isolation context" and a 10-bit value called an ICID +(isolation context id) is expressed by the hardware to identify +the requester. + +The generic 'iommus' property is insufficient to describe the relationship +between ICIDs and IOMMUs, so an iommu-map property is used to define +the set of possible ICIDs under a root DPRC and how they map to +an IOMMU. + +For generic IOMMU bindings, see +Documentation/devicetree/bindings/iommu/iommu.txt. + +For arm-smmu binding, see: +Documentation/devicetree/bindings/iommu/arm,smmu.txt. + Required properties: - compatible @@ -88,14 +107,34 @@ Sub-nodes: Value type: Definition: Specifies the phandle to the PHY device node associated with the this dpmac. +Optional properties: + +- iommu-map: Maps an ICID to an IOMMU and associated iommu-specifier + data. + + The property is an arbitrary number of tuples of + (icid-base,iommu,iommu-base,length). + + Any ICID i in the interval [icid-base, icid-base + length) is + associated with the listed IOMMU, with the iommu-specifier + (i - icid-base + iommu-base). Example: +smmu: iommu@500 { + compatible = "arm,mmu-500"; + #iommu-cells = <2>; + stream-match-mask = <0x7C00>; + ... +}; + fsl_mc: fsl-mc@80c00 { compatible = "fsl,qoriq-mc"; reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; +/* define map for ICIDs 23-64 */ +iommu-map = <23 &smmu 23 41>; #address-cells = <3>; #size-cells = <1>; -- 1.9.1
[PATCH 0/6 v2] Support for fsl-mc bus and its devices in SMMU
This patchset defines IOMMU DT binding for fsl-mc bus and adds support in SMMU for fsl-mc bus. This patch series is dependent on patset: https://patchwork.kernel.org/patch/10317337/ These patches - Define property 'iommu-map' for fsl-mc bus (patch 1) - Integrates the fsl-mc bus with the SMMU using this IOMMU binding (patch 2,3,4) - Adds the dma configuration support for fsl-mc bus (patch 5) - Updates the fsl-mc device node with iommu/dma related changes (patch6) Nipun Gupta (6): Docs: dt: add fsl-mc iommu-map device-tree binding iommu: of: make of_pci_map_rid() available for other devices too iommu: support iommu configuration for fsl-mc devices iommu: arm-smmu: Add support for the fsl-mc bus bus: fsl-mc: supoprt dma configure for devices on fsl-mc bus arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc Changes in v2: - use iommu-map property for fsl-mc bus - rebase over patchset https://patchwork.kernel.org/patch/10317337/ and make corresponding changes for dma configuration of devices on fsl-mc bus .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 39 +++ arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- drivers/bus/fsl-mc/fsl-mc-bus.c| 16 ++- drivers/iommu/arm-smmu.c | 7 ++ drivers/iommu/iommu.c | 21 drivers/iommu/of_iommu.c | 126 - drivers/of/irq.c | 6 +- drivers/pci/of.c | 101 - include/linux/fsl/mc.h | 8 ++ include/linux/iommu.h | 2 + include/linux/of_iommu.h | 11 ++ include/linux/of_pci.h | 10 -- 12 files changed, 231 insertions(+), 122 deletions(-) -- 1.9.1
RE: [PATCH 5/6] dma-mapping: support fsl-mc bus
> -Original Message- > From: Christoph Hellwig [mailto:h...@lst.de] > Sent: Thursday, March 08, 2018 13:11 > > On Tue, Mar 06, 2018 at 04:41:56AM +0000, Nipun Gupta wrote: > > Sorry for asking a trivial question - looking into dma_configure() I see > > that > > PCI is used in the start and the end of the API. > > In the end part pci_put_host_bridge_device() is called. > > So are two bus callbacks something like 'dma_config_start' & > 'dma_config_end' > > will be required where the former one will return "dma_dev"? > > I'd just use dma_configure as the callback. This would be a decent stuff. > > Currently the of_dma_configure and acpi_dma_configure are only used > for PCI anyway, as no one else sets a non-NULL dma dev. My understanding is that even the platform bus uses the of_dma_configure and probably acpi_dma_configure too. So platform bus may also need the callback implemented. Please correct me if my understanding is wrong. I will submit the patch with 'dma_configure' callback implemented for the busses shortly. > For fsl-mc I suspect only of_dma_configure is relevanet, so just call that > directly. > If at some point we get enough busses with either OF or ACPI we could > create a helper called from ->dma_configure for that. Totally agree with this. Thanks, Nipun
RE: [PATCH 1/6] Docs: dt: add fsl-mc iommu-parent device-tree binding
Hi Rob, > -Original Message- > From: Rob Herring [mailto:r...@kernel.org] > Sent: Thursday, March 08, 2018 4:10 > To: Nipun Gupta > Cc: will.dea...@arm.com; robin.mur...@arm.com; mark.rutl...@arm.com; > catalin.mari...@arm.com; devicet...@vger.kernel.org; stuyo...@gmail.com; > Bharat Bhushan ; gre...@linuxfoundation.org; > j...@8bytes.org; linuxppc-dev@lists.ozlabs.org; linux-ker...@vger.kernel.org; > Leo Li ; io...@lists.linux-foundation.org; Laurentiu > Tudor ; shawn...@kernel.org; h...@lst.de; linux- > arm-ker...@lists.infradead.org; m.szyprow...@samsung.com > Subject: Re: [PATCH 1/6] Docs: dt: add fsl-mc iommu-parent device-tree binding > > On Mon, Mar 05, 2018 at 07:59:21PM +0530, Nipun Gupta wrote: > > The existing IOMMU bindings cannot be used to specify the relationship > > between fsl-mc devices and IOMMUs. This patch adds a binding for > > mapping fsl-mc devices to IOMMUs, using a new iommu-parent property. > > > > Signed-off-by: Nipun Gupta > > --- > > .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 31 > ++ > > 1 file changed, 31 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > index 6611a7c..011c7d6 100644 > > --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > @@ -9,6 +9,24 @@ blocks that can be used to create functional hardware > objects/devices > > such as network interfaces, crypto accelerator instances, L2 switches, > > etc. > > > > +For an overview of the DPAA2 architecture and fsl-mc bus see: > > +drivers/staging/fsl-mc/README.txt > > + > > +As described in the above overview, all DPAA2 objects in a DPRC share the > > +same hardware "isolation context" and a 10-bit value called an ICID > > +(isolation context id) is expressed by the hardware to identify > > +the requester. > > + > > +The generic 'iommus' property is cannot be used to describe the > > relationship > > +between fsl-mc and IOMMUs, so an iommu-parent property is used to define > > +the same. > > Why not? It is just a link between 2 nodes. We have #iommu-cells as '1' i.e. iommu will have one stream ID configured for a device. Once USB and other devices start to use IOMMU we will also need this iommu-cells. When #iommu-cells is defined as '1' and we have 'iommus=<&smmu>' compilation reports warning about the mismatch. In fsl-mc bus case we do not have any stream id associated with the bus. As suggested by Robin, we can simply use the iommu-map property. > > > + > > +For generic IOMMU bindings, see > > +Documentation/devicetree/bindings/iommu/iommu.txt. > > + > > +For arm-smmu binding, see: > > +Documentation/devicetree/bindings/iommu/arm,smmu.txt. > > + > > Required properties: > > > > - compatible > > @@ -88,14 +106,27 @@ Sub-nodes: > >Value type: > >Definition: Specifies the phandle to the PHY device node > > associated > >with the this dpmac. > > +Optional properties: > > + > > +- iommu-parent: Maps the devices on fsl-mc bus to an IOMMU. > > + The property specifies the IOMMU behind which the devices on > > + fsl-mc bus are residing. > > If you want a generic property, this should be documented in the common > binding. We can use the iommu-map property which is already documented. > > Couldn't you have more than 1 IOMMU upstream of a MC? There is no such device currently with which fsl-mc bus uses more than one iommu. Infact, our current systems have only single IOMMU :). Even in future if such devices are there then we can use iommu-map to specify more than one iommu with separate requester ID's (RID's). Thank you for review... Regards, Nipun > > > > > Example: > > > > +smmu: iommu@500 { > > + compatible = "arm,mmu-500"; > > + #iommu-cells = <1>; > > + stream-match-mask = <0x7C00>; > > + ... > > +}; > > + > > fsl_mc: fsl-mc@80c00 { > > compatible = "fsl,qoriq-mc"; > > reg = <0x0008 0x0c00 0 0x40>,/* MC portal base > > */ > ><0x 0x0834 0 0x4>; /* MC control reg > > */ > > msi-parent = <&its>; > > +iommu-parent = <&smmu>; > > #address-cells = <3>; > > #size-cells = <1>; > > > > -- > > 1.9.1 > > > > > > ___ > > linux-arm-kernel mailing list > > linux-arm-ker...@lists.infradead.org > > > https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Flists.infr > adead.org%2Fmailman%2Flistinfo%2Flinux-arm- > kernel&data=02%7C01%7Cnipun.gupta%40nxp.com%7Cf64b4fe9c5cf45ce8a9a > 08d5847c6919%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C636560 > 592302736942&sdata=iOwv%2Fzd8UTLm7YCapDOWzrtd48VQeYY2vlufck7eYZI > %3D&reserved=0
RE: [PATCH 5/6] dma-mapping: support fsl-mc bus
> From: Robin Murphy [mailto:robin.mur...@arm.com] > Sent: Tuesday, March 06, 2018 0:22 > > On 05/03/18 18:39, Christoph Hellwig wrote: > > On Mon, Mar 05, 2018 at 03:48:32PM +, Robin Murphy wrote: > >> Unfortunately for us, fsl-mc is conceptually rather like PCI in that it's > >> software-discoverable and the only thing described in DT is the bus "host", > >> thus we need the same sort of thing as for PCI to map from the child > >> devices back to the bus root in order to find the appropriate firmware > >> node. Worse than PCI, though, we wouldn't even have the option of > >> describing child devices statically in firmware at all, since it's actually > >> one of these runtime-configurable "build your own network accelerator" > >> hardware pools where userspace gets to create and destroy "devices" as it > >> likes. > > > > I really hate the PCI special case just as much. Maybe we just > > need a dma_configure method on the bus, and move PCI as well as fsl-mc > > to it. > > Hmm, on reflection, 100% ack to that idea. It would neatly supersede > bus->force_dma *and* mean that we don't have to effectively pull pci.h > into everything, which I've never liked. In hindsight dma_configure() > does feel like it's grown into this odd choke point where we munge > everything in just for it to awkwardly unpick things again. > > Robin. +1 to the idea. Sorry for asking a trivial question - looking into dma_configure() I see that PCI is used in the start and the end of the API. In the end part pci_put_host_bridge_device() is called. So are two bus callbacks something like 'dma_config_start' & 'dma_config_end' will be required where the former one will return "dma_dev"? Regards, Nipun
RE: [PATCH 1/6] Docs: dt: add fsl-mc iommu-parent device-tree binding
> -Original Message- > From: Robin Murphy [mailto:robin.mur...@arm.com] > Sent: Monday, March 05, 2018 21:07 > To: Nipun Gupta ; will.dea...@arm.com; > mark.rutl...@arm.com; catalin.mari...@arm.com > Cc: io...@lists.linux-foundation.org; robh...@kernel.org; h...@lst.de; > m.szyprow...@samsung.com; gre...@linuxfoundation.org; j...@8bytes.org; > Leo Li ; shawn...@kernel.org; linux- > ker...@vger.kernel.org; devicet...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; Bharat Bhushan > ; stuyo...@gmail.com; Laurentiu Tudor > > Subject: Re: [PATCH 1/6] Docs: dt: add fsl-mc iommu-parent device-tree binding > > On 05/03/18 15:00, Nipun Gupta wrote: > > > > > >> -Original Message- > >> From: Robin Murphy [mailto:robin.mur...@arm.com] > >> Sent: Monday, March 05, 2018 20:23 > >> To: Nipun Gupta ; will.dea...@arm.com; > >> mark.rutl...@arm.com; catalin.mari...@arm.com > >> Cc: io...@lists.linux-foundation.org; robh...@kernel.org; h...@lst.de; > >> m.szyprow...@samsung.com; gre...@linuxfoundation.org; > j...@8bytes.org; > >> Leo Li ; shawn...@kernel.org; linux- > >> ker...@vger.kernel.org; devicet...@vger.kernel.org; linux-arm- > >> ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; Bharat Bhushan > >> ; stuyo...@gmail.com; Laurentiu Tudor > >> > >> Subject: Re: [PATCH 1/6] Docs: dt: add fsl-mc iommu-parent device-tree > binding > >> > >> On 05/03/18 14:29, Nipun Gupta wrote: > >>> The existing IOMMU bindings cannot be used to specify the relationship > >>> between fsl-mc devices and IOMMUs. This patch adds a binding for > >>> mapping fsl-mc devices to IOMMUs, using a new iommu-parent property. > >> > >> Given that allowing "msi-parent" for #msi-cells > 1 is merely a > >> backward-compatibility bodge full of hard-coded assumptions, why would > >> we want to knowingly introduce a similarly unpleasant equivalent for > >> IOMMUs? What's wrong with "iommu-map"? > > > > Hi Robin, > > > > With 'msi-parent' the property is fixed up to have msi-map. In this case > > there is > > no fixup required and simple 'iommu-parent' property can be used, with MC > bus > > itself providing the stream-id's (in the code execution via FW). > > > > We can also use the iommu-map property similar to PCI, which will require u- > boot > > fixup. But then it leads to little bit complications of u-boot - kernel > compatibility. > > What needs fixing up? With a stream-map-mask in place to ignore the > upper Stream ID bits, you just need: > > iommu-map = <0 &smmu 0 0x80>; > > to say that the lower bits of the ICID value map directly to the lower > bits of the Stream ID value - that's the same fixed property of the > hardware that you're wanting to assume in iommu-parent. Makes sense. I was going in a little bit wrong direction. Thanks for correcting. I will send v2 patchset with iommu-map property. Regards, Nipun > > > If you suggest we can re-use the iommu-map property. What is your opinion? > > I think it makes a lot more sense to directly use the property which > already exists, than to introduce a new one to merely assume one > hard-coded value of the existing one. Extending msi-parent to msi-map > was a case of "oops, it turns out we need more flexibility here"; for > the case of iommu-map I can't imagine any justification for saying > "oops, we need less flexibility here" (saving 9 whole bytes in the DT > really is irrelevant). > > Robin.
RE: [PATCH 1/6] Docs: dt: add fsl-mc iommu-parent device-tree binding
> -Original Message- > From: Robin Murphy [mailto:robin.mur...@arm.com] > Sent: Monday, March 05, 2018 20:23 > To: Nipun Gupta ; will.dea...@arm.com; > mark.rutl...@arm.com; catalin.mari...@arm.com > Cc: io...@lists.linux-foundation.org; robh...@kernel.org; h...@lst.de; > m.szyprow...@samsung.com; gre...@linuxfoundation.org; j...@8bytes.org; > Leo Li ; shawn...@kernel.org; linux- > ker...@vger.kernel.org; devicet...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linuxppc-dev@lists.ozlabs.org; Bharat Bhushan > ; stuyo...@gmail.com; Laurentiu Tudor > > Subject: Re: [PATCH 1/6] Docs: dt: add fsl-mc iommu-parent device-tree binding > > On 05/03/18 14:29, Nipun Gupta wrote: > > The existing IOMMU bindings cannot be used to specify the relationship > > between fsl-mc devices and IOMMUs. This patch adds a binding for > > mapping fsl-mc devices to IOMMUs, using a new iommu-parent property. > > Given that allowing "msi-parent" for #msi-cells > 1 is merely a > backward-compatibility bodge full of hard-coded assumptions, why would > we want to knowingly introduce a similarly unpleasant equivalent for > IOMMUs? What's wrong with "iommu-map"? Hi Robin, With 'msi-parent' the property is fixed up to have msi-map. In this case there is no fixup required and simple 'iommu-parent' property can be used, with MC bus itself providing the stream-id's (in the code execution via FW). We can also use the iommu-map property similar to PCI, which will require u-boot fixup. But then it leads to little bit complications of u-boot - kernel compatibility. If you suggest we can re-use the iommu-map property. What is your opinion? Thanks, Nipun > > > Signed-off-by: Nipun Gupta > > --- > > .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 31 > ++ > > 1 file changed, 31 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > index 6611a7c..011c7d6 100644 > > --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt > > @@ -9,6 +9,24 @@ blocks that can be used to create functional hardware > objects/devices > > such as network interfaces, crypto accelerator instances, L2 switches, > > etc. > > > > +For an overview of the DPAA2 architecture and fsl-mc bus see: > > +drivers/staging/fsl-mc/README.txt > > + > > +As described in the above overview, all DPAA2 objects in a DPRC share the > > +same hardware "isolation context" and a 10-bit value called an ICID > > +(isolation context id) is expressed by the hardware to identify > > +the requester. > > IOW, precisely the case for which "{msi,iommu}-map" exist. Yes, I know > they're currently documented under bindings/pci, but they're not really > intended to be absolutely PCI-specific. > > Robin. > > > +The generic 'iommus' property is cannot be used to describe the > > relationship > > +between fsl-mc and IOMMUs, so an iommu-parent property is used to define > > +the same. > > + > > +For generic IOMMU bindings, see > > +Documentation/devicetree/bindings/iommu/iommu.txt. > > + > > +For arm-smmu binding, see: > > +Documentation/devicetree/bindings/iommu/arm,smmu.txt. > > + > > Required properties: > > > > - compatible > > @@ -88,14 +106,27 @@ Sub-nodes: > > Value type: > > Definition: Specifies the phandle to the PHY device node > > associated > > with the this dpmac. > > +Optional properties: > > + > > +- iommu-parent: Maps the devices on fsl-mc bus to an IOMMU. > > + The property specifies the IOMMU behind which the devices on > > + fsl-mc bus are residing. > > > > Example: > > > > +smmu: iommu@500 { > > + compatible = "arm,mmu-500"; > > + #iommu-cells = <1>; > > + stream-match-mask = <0x7C00>; > > + ... > > +}; > > + > > fsl_mc: fsl-mc@80c00 { > > compatible = "fsl,qoriq-mc"; > > reg = <0x0008 0x0c00 0 0x40>,/* MC portal > > base */ > > <0x 0x0834 0 0x4>; /* MC control > > reg */ > > msi-parent = <&its>; > > +iommu-parent = <&smmu>; > > #address-cells = <3>; > > #size-cells = <1>; > > > >
[PATCH 0/6] Support for fsl-mc bus and its devices in SMMU
This patchset defines IOMMU DT binding for fsl-mc bus and adds support in SMMU for fsl-mc bus. These patches - Define the new property 'iommu-parent' for fsl-mc bus (patch 1) - Integrates the fsl-mc bus with the SMMU using this IOMMU binding (patch 2,3) - Adds the dma-mapping support for fsl-mc bus (patch 4,5) - Updates the fsl-mc device node with iommu/dma related changes This patchset is based on staging-testing tree where fsl-mc bus is out from staging This patchset is dependent on patch https://patchwork.kernel.org/patch/10207507/; otherwise DPAA2 Ethernet driver functionality will break. Nipun Gupta (6): Docs: dt: add fsl-mc iommu-parent device-tree binding iommu: support iommu configuration for fsl-mc devices iommu: arm-smmu: Add support for the fsl-mc bus bus: fsl-mc: remove dma ops setup from driver dma-mapping: support fsl-mc bus dts: fsl-ls208x: updated DT with SMMU support for fsl-mc .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 31 ++ arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 - drivers/base/dma-mapping.c | 7 + drivers/bus/fsl-mc/fsl-mc-bus.c| 5 +--- drivers/iommu/arm-smmu.c | 7 + drivers/iommu/iommu.c | 21 +++ drivers/iommu/of_iommu.c | 23 include/linux/fsl/mc.h | 8 ++ include/linux/iommu.h | 2 ++ 9 files changed, 105 insertions(+), 5 deletions(-) -- 1.9.1
[PATCH 6/6] dts: fsl-ls208x: updated DT with SMMU support for fsl-mc
Signed-off-by: Nipun Gupta --- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index f3a40af..1f15492 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -135,6 +135,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; + dma-ranges = <0x0 0x0 0x0 0x0 0x1 0x>; clockgen: clocking@130 { compatible = "fsl,ls2080a-clockgen"; @@ -357,6 +358,8 @@ reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; + iommu-parent = <&smmu>; + dma-coherent; #address-cells = <3>; #size-cells = <1>; @@ -460,6 +463,8 @@ compatible = "arm,mmu-500"; reg = <0 0x500 0 0x80>; #global-interrupts = <12>; + stream-match-mask = <0x7C00>; + dma-coherent; interrupts = <0 13 4>, /* global secure fault */ <0 14 4>, /* combined secure interrupt */ <0 15 4>, /* global non-secure fault */ @@ -502,7 +507,6 @@ <0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>, <0 208 4>, <0 209 4>; - mmu-masters = <&fsl_mc 0x300 0>; }; dspi: dspi@210 { -- 1.9.1
[PATCH 5/6] dma-mapping: support fsl-mc bus
Signed-off-by: Nipun Gupta --- drivers/base/dma-mapping.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 3b11835..2279c4d 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -334,6 +334,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags) * Common configuration to enable DMA API use for a device */ #include +#include int dma_configure(struct device *dev) { @@ -349,6 +350,12 @@ int dma_configure(struct device *dev) dma_dev = dma_dev->parent; } + if (dev_is_fsl_mc(dev)) { + dma_dev = dev; + while (dev_is_fsl_mc(dma_dev)) + dma_dev = dma_dev->parent; + } + if (dma_dev->of_node) { ret = of_dma_configure(dev, dma_dev->of_node); } else if (has_acpi_companion(dma_dev)) { -- 1.9.1
[PATCH 4/6] bus: fsl-mc: remove dma ops setup from driver
The dma setup for fsl-mc devices is being done from device_add() function. So, no need to call in mc bus driver. Signed-off-by: Nipun Gupta --- drivers/bus/fsl-mc/fsl-mc-bus.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 1b333c4..c9a239a 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -616,6 +616,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, mc_dev->icid = parent_mc_dev->icid; mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; mc_dev->dev.dma_mask = &mc_dev->dma_mask; + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; dev_set_msi_domain(&mc_dev->dev, dev_get_msi_domain(&parent_mc_dev->dev)); } @@ -633,10 +634,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, goto error_cleanup_dev; } - /* Objects are coherent, unless 'no shareability' flag set. */ - if (!(obj_desc->flags & FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) - arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true); - /* * The device-specific probe callback will get invoked by device_add() */ -- 1.9.1
[PATCH 3/6] iommu: arm-smmu: Add support for the fsl-mc bus
Implement bus specific support for the fsl-mc bus including registering arm_smmu_ops and bus specific device add operations. Signed-off-by: Nipun Gupta --- drivers/iommu/arm-smmu.c | 7 +++ drivers/iommu/iommu.c| 21 + include/linux/fsl/mc.h | 8 include/linux/iommu.h| 2 ++ 4 files changed, 38 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69e7c60..e1d5090 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -52,6 +52,7 @@ #include #include +#include #include "io-pgtable.h" #include "arm-smmu-regs.h" @@ -1459,6 +1460,8 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) if (dev_is_pci(dev)) group = pci_device_group(dev); + else if (dev_is_fsl_mc(dev)) + group = fsl_mc_device_group(dev); else group = generic_device_group(dev); @@ -2037,6 +2040,10 @@ static void arm_smmu_bus_init(void) bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } #endif +#ifdef CONFIG_FSL_MC_BUS + if (!iommu_present(&fsl_mc_bus_type)) + bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops); +#endif } static int arm_smmu_device_probe(struct platform_device *pdev) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 69fef99..fbeebb2 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include static struct kset *iommu_group_kset; @@ -987,6 +988,26 @@ struct iommu_group *pci_device_group(struct device *dev) return iommu_group_alloc(); } +/* Get the IOMMU group for device on fsl-mc bus */ +struct iommu_group *fsl_mc_device_group(struct device *dev) +{ + struct device *cont_dev = fsl_mc_cont_dev(dev); + struct iommu_group *group; + + /* Container device is responsible for creating the iommu group */ + if (fsl_mc_is_cont_dev(dev)) { + group = iommu_group_alloc(); + if (IS_ERR(group)) + return NULL; + } else { + get_device(cont_dev); + group = iommu_group_get(cont_dev); + put_device(cont_dev); + } + + return group; +} + /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index 765ba41..ae9382b 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -351,6 +351,14 @@ struct fsl_mc_io { #define dev_is_fsl_mc(_dev) (0) #endif +/* Macro to check if a device is a container device */ +#define fsl_mc_is_cont_dev(_dev) (to_fsl_mc_device(_dev)->flags & \ + FSL_MC_IS_DPRC) + +/* Macro to get the container device of a MC device */ +#define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \ + (_dev) : (_dev)->parent) + /* * module_fsl_mc_driver() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 41b8c57..00a460b 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -389,6 +389,8 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +/* FSL-MC device grouping function */ +struct iommu_group *fsl_mc_device_group(struct device *dev); /** * struct iommu_fwspec - per-device IOMMU instance data -- 1.9.1
[PATCH 2/6] iommu: support iommu configuration for fsl-mc devices
Signed-off-by: Nipun Gupta --- drivers/iommu/of_iommu.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b..cc2fb9c 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -24,6 +24,7 @@ #include #include #include +#include #define NO_IOMMU 1 @@ -160,6 +161,26 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) return err; } +static int +of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, + struct device_node *master_np) +{ + struct of_phandle_args iommu_spec; + int err; + + iommu_spec.np = of_parse_phandle(master_np, "iommu-parent", 0); + if (!iommu_spec.np) + return NO_IOMMU; + + iommu_spec.args[0] = mc_dev->icid; + iommu_spec.args_count = 1; + + err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); + of_node_put(iommu_spec.np); + + return err; +} + const struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { @@ -191,6 +212,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, err = pci_for_each_dma_alias(to_pci_dev(dev), of_pci_iommu_init, &info); + } else if (dev_is_fsl_mc(dev)) { + err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); } else { struct of_phandle_args iommu_spec; int idx = 0; -- 1.9.1
[PATCH 1/6] Docs: dt: add fsl-mc iommu-parent device-tree binding
The existing IOMMU bindings cannot be used to specify the relationship between fsl-mc devices and IOMMUs. This patch adds a binding for mapping fsl-mc devices to IOMMUs, using a new iommu-parent property. Signed-off-by: Nipun Gupta --- .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 31 ++ 1 file changed, 31 insertions(+) diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt index 6611a7c..011c7d6 100644 --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt @@ -9,6 +9,24 @@ blocks that can be used to create functional hardware objects/devices such as network interfaces, crypto accelerator instances, L2 switches, etc. +For an overview of the DPAA2 architecture and fsl-mc bus see: +drivers/staging/fsl-mc/README.txt + +As described in the above overview, all DPAA2 objects in a DPRC share the +same hardware "isolation context" and a 10-bit value called an ICID +(isolation context id) is expressed by the hardware to identify +the requester. + +The generic 'iommus' property is cannot be used to describe the relationship +between fsl-mc and IOMMUs, so an iommu-parent property is used to define +the same. + +For generic IOMMU bindings, see +Documentation/devicetree/bindings/iommu/iommu.txt. + +For arm-smmu binding, see: +Documentation/devicetree/bindings/iommu/arm,smmu.txt. + Required properties: - compatible @@ -88,14 +106,27 @@ Sub-nodes: Value type: Definition: Specifies the phandle to the PHY device node associated with the this dpmac. +Optional properties: + +- iommu-parent: Maps the devices on fsl-mc bus to an IOMMU. + The property specifies the IOMMU behind which the devices on + fsl-mc bus are residing. Example: +smmu: iommu@500 { + compatible = "arm,mmu-500"; + #iommu-cells = <1>; + stream-match-mask = <0x7C00>; + ... +}; + fsl_mc: fsl-mc@80c00 { compatible = "fsl,qoriq-mc"; reg = <0x0008 0x0c00 0 0x40>,/* MC portal base */ <0x 0x0834 0 0x4>; /* MC control reg */ msi-parent = <&its>; +iommu-parent = <&smmu>; #address-cells = <3>; #size-cells = <1>; -- 1.9.1