Re: [PATCH 2/2] iommu/omap: Add support for configuring dsp iommus on DRA7xx
* Suman Anna [150721 16:58]: > --- a/drivers/iommu/omap-iommu.c > +++ b/drivers/iommu/omap-iommu.c > @@ -26,6 +26,8 @@ > #include > #include > #include > +#include > +#include > > #include > > @@ -112,6 +114,18 @@ void omap_iommu_restore_ctx(struct device *dev) > } > EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx); > > +static void dra7_cfg_dspsys_mmu(struct omap_iommu *obj, bool enable) > +{ > + u32 val, mask; > + > + if (!obj->syscfg) > + return; > + > + mask = (1 << (obj->id * DSP_SYS_MMU_CONFIG_EN_SHIFT)); > + val = enable ? mask : 0; > + regmap_update_bits(obj->syscfg, DSP_SYS_MMU_CONFIG, mask, val); > +} > + > static void __iommu_set_twl(struct omap_iommu *obj, bool on) I don't like using syscon for tinkering directly with SoC registers. We should use some Linux generic framework for configuring these bits to avoid nasty dependencies between various hardware modules on the SoC. What does DSP_SYS_MMU_CONFIG register do? It seems it's probably a regulator or a gate clock? If so, it should be set up as a regulator or a clock and then the omap-iommu driver can just use regulator or clcok framework to request the resource. Regards, Tony ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 0/5] iommu/arm-smmu: add support for non-pci devices
On 2015/7/21 18:30, Robin Murphy wrote: > On 21/07/15 08:30, Zhen Lei wrote: >> Changelog: >> v2 -> v3: >> 1. add support for pci device hotplug, which missed in patch v2. >> 2. only support #iommu-cells = <1>, add corresponding description in >> arm,smmu-v3.txt. >> 3. add function find_smmu_by_device which extracted from find_smmu_by_node, >> to resolve >> the problem mentioned by Robin Murphy in [PATCH v2 7/9]. >> Additionally: >> +platform_set_drvdata(pdev, smmu); //Patch v2 >> +dev->archdata.iommu = smmu; //Patch v3, dev = &pdev->dev > > > I didn't give any Reviewed-by tags, much less to revised patches that I've > not even looked at yet; please see section 13 of > Documentation/SubmittingPatches for what the Reviewed-by tag means. OK. I see that now. So that Reviewed-by tags should always be given by the reviewer. I initially thought that "Reviewed-by" should be added for who had reviewed the patch. > > Robin. > >> >> v1 -> v2: >> update the implementation of patch 1/9 according to Will Deacon's suggestion. >> update the comment of patch 3/9 and 4/9. >> use arm_smmu_options to skip the execution of command CMD_PREFETCH_CONFIG, >> see patch 5/9. >> patch 6/9 is base on Laurent's series, to support probe deferral. >> patch 7/9 according to Robin Murphy's suggestion, remove global variable >> arm_smmu_devices, thanks. >> patch 9/9 add support for a master with multiple stream IDs. >> >> Zhen Lei (5): >>iommu/arm-smmu: to support probe deferral >>iommu/arm-smmu: remove arm_smmu_devices >>iommu/arm-smmu: rename __arm_smmu_get_pci_sid >>iommu/arm-smmu: add support for non-pci devices >>iommu/arm-smmu: describe the limitation of #iommu-cells >> >> .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 + >> drivers/iommu/arm-smmu-v3.c| 209 >> - >> 2 files changed, 163 insertions(+), 52 deletions(-) >> >> -- >> 1.8.0 >> >> > > > . > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 0/4] Add DRA7 IOMMU DT nodes
Hi Tony, The following patches add the basic DT nodes for the DSP and IPU IOMMU devices for the DRA7xx SoC family. The first two patches add syscon nodes for DSP_SYSTEM sub-modules, while the last two add the IOMMU nodes. The IPU IOMMU nodes mostly are similar to existing ones on OMAP4 and OMAP5. The DSP sub-system though has two MMUs, with a dedicated MMU for the internal EDMA engine. On previous SoCs, a single MMU served both the DSP processor and the internal EDMA. The DSP IOMMU nodes require a new property to reference the syscon nodes, as they each need a specific bit to be set in a register within the corresponding DSP_SYSTEM sub-module. So, these are pending based on the equivalent bindings update series [1]. Please let me know if the binding looks ok to you, as this seems it can be done in couple of ways. Patches are based on 4.2-rc3. regards Suman [1] http://marc.info/?l=linux-omap&m=143752295508435&w=2 Suman Anna (4): ARM: dts: DRA7: Add dsp1_system syscon node ARM: dts: DRA74x: Add dsp2_system syscon node ARM: dts: DRA7: Add common IOMMU nodes ARM: dts: DRA74x: Add IOMMU nodes for DSP2 arch/arm/boot/dts/dra7.dtsi | 45 +++ arch/arm/boot/dts/dra74x.dtsi | 25 2 files changed, 70 insertions(+) -- 2.4.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 2/4] ARM: dts: DRA74x: Add dsp2_system syscon node
The DSP_SYSTEM sub-module is a dedicated system control logic module present within a DRA7 DSP processor sub-system. This module is responsible for power management, clock generation and connection to the device PRCM module. Add a syscon node for this module for the DSP2 processor sub-system. This is added as a syscon node as it is a common configuration module that can be used by the different IOMMU instances and the corresponding remoteproc device. The node is added to the dra74x.dtsi file, as the DSP2 processor subsystem is usually present only on the DRA74x variants of the DRA7 SoC family. Signed-off-by: Suman Anna --- arch/arm/boot/dts/dra74x.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi index fa995d0ca1f2..6cb112450ddd 100644 --- a/arch/arm/boot/dts/dra74x.dtsi +++ b/arch/arm/boot/dts/dra74x.dtsi @@ -52,6 +52,11 @@ }; ocp { + dsp2_system: dsp_system@4150 { + compatible = "syscon"; + reg = <0x4150 0x100>; + }; + omap_dwc3_4: omap_dwc3_4@4894 { compatible = "ti,dwc3"; ti,hwmods = "usb_otg_ss4"; -- 2.4.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 3/4] ARM: dts: DRA7: Add common IOMMU nodes
The DRA7xx family of SOCs have two IPUs and one DSP processor subsystems in common. The IOMMU DT nodes have been added for these processor subsystems, and have been disabled by default. These MMUs are very similar to those on OMAP4 and OMAP5, with the only difference being the presence of a second MMU within the DSP subsystem for the EDMA port. The DSP IOMMUs also need an additional 'ti,syscon-mmuconfig' property compared to the IPU IOMMUs. NOTE: The enabling of these nodes is left to the respective board dts files. Signed-off-by: Suman Anna --- arch/arm/boot/dts/dra7.dtsi | 40 1 file changed, 40 insertions(+) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 1c96729641b6..0754df4ca59c 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -911,6 +911,46 @@ status = "disabled"; }; + mmu0_dsp1: mmu@40d01000 { + compatible = "ti,dra7-dsp-iommu"; + reg = <0x40d01000 0x100>; + interrupts = ; + ti,hwmods = "mmu0_dsp1"; + #iommu-cells = <0>; + ti,syscon-mmuconfig = <&dsp1_system 0x0>; + status = "disabled"; + }; + + mmu1_dsp1: mmu@40d02000 { + compatible = "ti,dra7-dsp-iommu"; + reg = <0x40d02000 0x100>; + interrupts = ; + ti,hwmods = "mmu1_dsp1"; + #iommu-cells = <0>; + ti,syscon-mmuconfig = <&dsp1_system 0x1>; + status = "disabled"; + }; + + mmu_ipu1: mmu@58882000 { + compatible = "ti,dra7-iommu"; + reg = <0x58882000 0x100>; + interrupts = ; + ti,hwmods = "mmu_ipu1"; + #iommu-cells = <0>; + ti,iommu-bus-err-back; + status = "disabled"; + }; + + mmu_ipu2: mmu@55082000 { + compatible = "ti,dra7-iommu"; + reg = <0x55082000 0x100>; + interrupts = ; + ti,hwmods = "mmu_ipu2"; + #iommu-cells = <0>; + ti,iommu-bus-err-back; + status = "disabled"; + }; + abb_mpu: regulator-abb-mpu { compatible = "ti,abb-v3"; regulator-name = "abb_mpu"; -- 2.4.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 4/4] ARM: dts: DRA74x: Add IOMMU nodes for DSP2
The DRA74x family of SoCs have a second DSP, that also has two MMUs just like the DSP1 subsystem. Add the IOMMU nodes for this DSP2 subsystem in disabled state to the DRA74x specific DTS file, the nodes would need to be enabled appropriately in the respective board DTS files. Signed-off-by: Suman Anna --- arch/arm/boot/dts/dra74x.dtsi | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi index 6cb112450ddd..612cc7e13bab 100644 --- a/arch/arm/boot/dts/dra74x.dtsi +++ b/arch/arm/boot/dts/dra74x.dtsi @@ -76,6 +76,26 @@ dr_mode = "otg"; }; }; + + mmu0_dsp2: mmu@41501000 { + compatible = "ti,dra7-dsp-iommu"; + reg = <0x41501000 0x100>; + interrupts = ; + ti,hwmods = "mmu0_dsp2"; + #iommu-cells = <0>; + ti,syscon-mmuconfig = <&dsp2_system 0x0>; + status = "disabled"; + }; + + mmu1_dsp2: mmu@41502000 { + compatible = "ti,dra7-dsp-iommu"; + reg = <0x41502000 0x100>; + interrupts = ; + ti,hwmods = "mmu1_dsp2"; + #iommu-cells = <0>; + ti,syscon-mmuconfig = <&dsp2_system 0x1>; + status = "disabled"; + }; }; }; -- 2.4.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 1/4] ARM: dts: DRA7: Add dsp1_system syscon node
The DSP_SYSTEM sub-module is a dedicated system control logic module present within a DRA7 DSP processor sub-system. This module is responsible for power management, clock generation and connection to the device PRCM module. Add a syscon node for this module for the DSP1 processor sub-system. This is added as a syscon node as it is a common configuration module that can be used by the different IOMMU instances and the corresponding remoteproc device. The node is added to the common dra7.dtsi file, as the DSP1 processor sub-system is mostly common across all the variants of the DRA7 SoC family. Signed-off-by: Suman Anna --- arch/arm/boot/dts/dra7.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 8f1e25bcecbd..1c96729641b6 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -296,6 +296,11 @@ reg = <0x4a002e00 0x7c>; }; + dsp1_system: dsp_system@40d0 { + compatible = "syscon"; + reg = <0x40d0 0x100>; + }; + sdma: dma-controller@4a056000 { compatible = "ti,omap4430-sdma"; reg = <0x4a056000 0x1000>; -- 2.4.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 0/2] DRA7 DSP MMU config support
Hi, This series adds the basic support in the OMAP IOMMU driver to enable/disable DSP IOMMUs for the DRA7xx family of SoCs. The DRA7 family has two MMUs within the DSP processor subsystems. This is the first time this was designed so in the silicon compared to the equivalent ones on OMAP2+ SoCs. Each MMU requires a specific bit to be turned on within a register from a separate sub-module DSP_SYSTEM present within the respective processor subsystem. The DSP_SYSTEM sub-module is represented as a syscon node, and an additional property "ti,syscon-mmuconfig" is used alongside a unique compatible property for configuring these devices. The register and bit offset is coded up in the driver while the DT property references the syscon phandle the MMU instance number. The binding support could have been done in couple of other ways, like using separate compatible each for the DSP processor MMU & the DSP EDMA MMU that automatically identifies the instance number; and/or coding up the register offset & bit position/offset in the syscon property, so let me know if the current approach is fine. The patches are baselined on 4.2-rc3 + the recent OMAP IOMMU cleanup series [1]. I will post the DTS patches separately to allow Tony to pick them up independently. regards Suman [1] http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013659.html Suman Anna (2): Documentation: dt: Update OMAP iommu bindings for DRA7 DSPs iommu/omap: Add support for configuring dsp iommus on DRA7xx .../devicetree/bindings/iommu/ti,omap-iommu.txt| 27 ++ drivers/iommu/omap-iommu.c | 58 ++ drivers/iommu/omap-iommu.h | 9 3 files changed, 94 insertions(+) -- 2.4.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 2/2] iommu/omap: Add support for configuring dsp iommus on DRA7xx
The DSP MMUs on DRA7xx SoC requires configuring an additional MMU_CONFIG register present in the DSP_SYSTEM sub module. This setting dictates whether the DSP Core's MDMA and EDMA traffic is routed through the respective MMU or not. Add the support to the OMAP iommu driver so that the traffic is not bypassed when enabling the MMUs. The MMU_CONFIG register has two different bits for enabling each of these two MMUs present in the DSP processor sub-system on DRA7xx. An id field is added to the OMAP iommu object to identify and enable each IOMMU. The id information and the DSP_SYSTEM.MMU_CONFIG register programming is achieved through the processing of the optional "ti,syscon-mmuconfig" property. A proper value is assigned to the id field only when this property is present. Signed-off-by: Suman Anna --- drivers/iommu/omap-iommu.c | 58 ++ drivers/iommu/omap-iommu.h | 9 +++ 2 files changed, 67 insertions(+) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index fe742c01a4f2..0849a5927732 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include @@ -112,6 +114,18 @@ void omap_iommu_restore_ctx(struct device *dev) } EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx); +static void dra7_cfg_dspsys_mmu(struct omap_iommu *obj, bool enable) +{ + u32 val, mask; + + if (!obj->syscfg) + return; + + mask = (1 << (obj->id * DSP_SYS_MMU_CONFIG_EN_SHIFT)); + val = enable ? mask : 0; + regmap_update_bits(obj->syscfg, DSP_SYS_MMU_CONFIG, mask, val); +} + static void __iommu_set_twl(struct omap_iommu *obj, bool on) { u32 l = iommu_read_reg(obj, MMU_CNTL); @@ -147,6 +161,8 @@ static int omap2_iommu_enable(struct omap_iommu *obj) iommu_write_reg(obj, pa, MMU_TTB); + dra7_cfg_dspsys_mmu(obj, true); + if (obj->has_bus_err_back) iommu_write_reg(obj, MMU_GP_REG_BUS_ERR_BACK_EN, MMU_GP_REG); @@ -161,6 +177,7 @@ static void omap2_iommu_disable(struct omap_iommu *obj) l &= ~MMU_CNTL_MASK; iommu_write_reg(obj, l, MMU_CNTL); + dra7_cfg_dspsys_mmu(obj, false); dev_dbg(obj->dev, "%s is shutting down\n", obj->name); } @@ -864,6 +881,42 @@ static void omap_iommu_detach(struct omap_iommu *obj) dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name); } +static int omap_iommu_dra7_get_dsp_system_cfg(struct platform_device *pdev, + struct omap_iommu *obj) +{ + struct device_node *np = pdev->dev.of_node; + int ret; + + if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu")) + return 0; + + if (!of_property_read_bool(np, "ti,syscon-mmuconfig")) { + dev_err(&pdev->dev, "ti,syscon-mmuconfig property is missing\n"); + return -EINVAL; + } + + obj->syscfg = + syscon_regmap_lookup_by_phandle(np, "ti,syscon-mmuconfig"); + if (IS_ERR(obj->syscfg)) { + /* can fail with -EPROBE_DEFER */ + ret = PTR_ERR(obj->syscfg); + return ret; + } + + if (of_property_read_u32_index(np, "ti,syscon-mmuconfig", 1, + &obj->id)) { + dev_err(&pdev->dev, "couldn't get the IOMMU instance id within subsystem\n"); + return -EINVAL; + } + + if (obj->id != 0 && obj->id != 1) { + dev_err(&pdev->dev, "invalid IOMMU instance id\n"); + return -EINVAL; + } + + return 0; +} + /* * OMAP Device MMU(IOMMU) detection */ @@ -907,6 +960,10 @@ static int omap_iommu_probe(struct platform_device *pdev) if (IS_ERR(obj->regbase)) return PTR_ERR(obj->regbase); + err = omap_iommu_dra7_get_dsp_system_cfg(pdev, obj); + if (err) + return err; + irq = platform_get_irq(pdev, 0); if (irq < 0) return -ENODEV; @@ -943,6 +1000,7 @@ static const struct of_device_id omap_iommu_of_match[] = { { .compatible = "ti,omap2-iommu" }, { .compatible = "ti,omap4-iommu" }, { .compatible = "ti,dra7-iommu" }, + { .compatible = "ti,dra7-dsp-iommu" }, {}, }; diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index a656df2f9e03..59628e5017b4 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -30,6 +30,7 @@ struct iotlb_entry { struct omap_iommu { const char *name; void __iomem*regbase; + struct regmap *syscfg; struct device *dev; struct iommu_domain *domain; struct dentry *debug_dir; @@ -48,6 +49,7 @@ struct omap_iommu { void *ctx; /* iommu context: registres saved area */ int has_bus_err_back; + u32 id; }; struct cr_regs { @@ -159,6 +161,13 @@ static in
[PATCH 1/2] Documentation: dt: Update OMAP iommu bindings for DRA7 DSPs
The DSP processor sub-systems on DRA7xx have two MMU instances each, one for the processor core and the other for an internal EDMA block. These MMUs need an additional shared register to be programmed in the DSP_SYSTEM sub-module to be enabled properly. The OMAP IOMMU bindings is updated to account for this additional syscon property required for these DSP IOMMU instances on DRA7xx SoCs. A new compatible "ti,dra7-dsp-iommu" is also defined to distinguish these devices specifically from other DRA7 IOMMU devices. An example of the DRA7 DSP IOMMU nodes is also added to the document for clarity. Signed-off-by: Suman Anna --- .../devicetree/bindings/iommu/ti,omap-iommu.txt| 27 ++ 1 file changed, 27 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt index 869699925fd5..4bd10dd881b8 100644 --- a/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt +++ b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt @@ -4,6 +4,7 @@ Required properties: - compatible : Should be one of, "ti,omap2-iommu" for OMAP2/OMAP3 IOMMU instances "ti,omap4-iommu" for OMAP4/OMAP5 IOMMU instances + "ti,dra7-dsp-iommu" for DRA7xx DSP IOMMU instances "ti,dra7-iommu" for DRA7xx IOMMU instances - ti,hwmods : Name of the hwmod associated with the IOMMU instance - reg: Address space for the configuration registers @@ -19,6 +20,13 @@ Optional properties: Should be either 8 or 32 (default: 32) - ti,iommu-bus-err-back : Indicates the IOMMU instance supports throwing back a bus error response on MMU faults. +- ti,syscon-mmuconfig : Should be a pair of the phandle to the DSP_SYSTEM +syscon node that contains the additional control +register for enabling the MMU, and the MMU instance +number (0-indexed) within the sub-system. This property +is required for DSP IOMMU instances on DRA7xx SoCs. The +instance number should be 0 for DSP MDMA MMUs and 1 for +DSP EDMA MMUs. Example: /* OMAP3 ISP MMU */ @@ -30,3 +38,22 @@ Example: ti,hwmods = "mmu_isp"; ti,#tlb-entries = <8>; }; + + /* DRA74x DSP2 MMUs */ + mmu0_dsp2: mmu@41501000 { + compatible = "ti,dra7-dsp-iommu"; + reg = <0x41501000 0x100>; + interrupts = ; + ti,hwmods = "mmu0_dsp2"; + #iommu-cells = <0>; + ti,syscon-mmuconfig = <&dsp2_system 0x0>; + }; + + mmu1_dsp2: mmu@41502000 { + compatible = "ti,dra7-dsp-iommu"; + reg = <0x41502000 0x100>; + interrupts = ; + ti,hwmods = "mmu1_dsp2"; + #iommu-cells = <0>; + ti,syscon-mmuconfig = <&dsp2_system 0x1>; + }; -- 2.4.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 02/11] iommu/omap: Remove all module references
Hi Laurent, > > On Monday 20 July 2015 17:33:24 Suman Anna wrote: >> The OMAP IOMMU driver has been adapted to the IOMMU framework >> for a while now, and it does not support being built as a >> module anymore. So, remove all the module references from the >> OMAP IOMMU driver. >> >> While at it, also relocate a comment around the subsys_initcall >> to avoid a checkpatch strict warning about using a blank line >> after function/struct/union/enum declarations. >> >> Signed-off-by: Suman Anna > > I think this is one of the checkpatch warnings that can be safely ignored, > but > it doesn't matter much. The comment will be removed after the OMAP3 ISP and > OMAP IOMMU drivers get support for a saner IOMMU probing dependency order > solution. > > The code seems fine to me. > > Reviewed-by: Laurent Pinchart Yes, indeed. I have also started to work on some patches to switch to using the IOMMU_OF_DECLARE init, that should also help us. I will post those for the 4.4 kernel merge window. regards Suman ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC PATCH 4/4] iommu/arm-smmu: Add support for specifying regulators
On 07/17/2015 09:53 AM, Sricharan R wrote: From: Mitchel Humpherys This adds the support to turn on the regulators required for SMMUs. It is turned on during the SMMU probe and remains 'on' till the device exists. The device always exists. Until the driver is removed perhaps? Signed-off-by: Sricharan R We won't be using regulators. We'll be using power domains instead so please rewrite this patch accordingly. -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 3/6] iommu: add ARM short descriptor page table allocator.
Hello, This is looking better, but I still have some concerns. On Thu, Jul 16, 2015 at 10:04:32AM +0100, Yong Wu wrote: > This patch is for ARM Short Descriptor Format. > > Signed-off-by: Yong Wu > --- > drivers/iommu/Kconfig| 18 + > drivers/iommu/Makefile |1 + > drivers/iommu/io-pgtable-arm-short.c | 742 > ++ > drivers/iommu/io-pgtable-arm.c |3 - > drivers/iommu/io-pgtable.c |4 + > drivers/iommu/io-pgtable.h | 13 + > 6 files changed, 778 insertions(+), 3 deletions(-) > create mode 100644 drivers/iommu/io-pgtable-arm-short.c [...] > +#define ARM_SHORT_PGDIR_SHIFT 20 > +#define ARM_SHORT_PAGE_SHIFT 12 > +#define ARM_SHORT_PTRS_PER_PTE \ > + (1 << (ARM_SHORT_PGDIR_SHIFT - ARM_SHORT_PAGE_SHIFT)) > +#define ARM_SHORT_BYTES_PER_PTE\ > + (ARM_SHORT_PTRS_PER_PTE * sizeof(arm_short_iopte)) > + > +/* level 1 pagetable */ > +#define ARM_SHORT_PGD_TYPE_PGTABLE BIT(0) > +#define ARM_SHORT_PGD_SECTION_XN (BIT(0) | BIT(4)) > +#define ARM_SHORT_PGD_TYPE_SECTION BIT(1) > +#define ARM_SHORT_PGD_PGTABLE_XN BIT(2) This should be PXN, but I'm not even sure why we care for a table at level 1. > +#define ARM_SHORT_PGD_BBIT(2) > +#define ARM_SHORT_PGD_CBIT(3) > +#define ARM_SHORT_PGD_PGTABLE_NS BIT(3) > +#define ARM_SHORT_PGD_IMPLEBIT(9) > +#define ARM_SHORT_PGD_TEX0 BIT(12) > +#define ARM_SHORT_PGD_SBIT(16) > +#define ARM_SHORT_PGD_nG BIT(17) > +#define ARM_SHORT_PGD_SUPERSECTION BIT(18) > +#define ARM_SHORT_PGD_SECTION_NS BIT(19) > + > +#define ARM_SHORT_PGD_TYPE_SUPERSECTION\ > + (ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_SUPERSECTION) > +#define ARM_SHORT_PGD_SECTION_TYPE_MSK \ > + (ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_SUPERSECTION) > +#define ARM_SHORT_PGD_PGTABLE_TYPE_MSK \ > + (ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_TYPE_PGTABLE) > +#define ARM_SHORT_PGD_TYPE_IS_PGTABLE(pgd) \ > + (((pgd) & ARM_SHORT_PGD_PGTABLE_TYPE_MSK) == > ARM_SHORT_PGD_TYPE_PGTABLE) > +#define ARM_SHORT_PGD_TYPE_IS_SECTION(pgd) \ > + (((pgd) & ARM_SHORT_PGD_SECTION_TYPE_MSK) == > ARM_SHORT_PGD_TYPE_SECTION) > +#define ARM_SHORT_PGD_TYPE_IS_SUPERSECTION(pgd)\ > + (((pgd) & ARM_SHORT_PGD_SECTION_TYPE_MSK) == \ > + ARM_SHORT_PGD_TYPE_SUPERSECTION) > +#define ARM_SHORT_PGD_PGTABLE_MSK 0xfc00 > +#define ARM_SHORT_PGD_SECTION_MSK (~(SZ_1M - 1)) > +#define ARM_SHORT_PGD_SUPERSECTION_MSK (~(SZ_16M - 1)) > + > +/* level 2 pagetable */ > +#define ARM_SHORT_PTE_TYPE_LARGE BIT(0) > +#define ARM_SHORT_PTE_SMALL_XN BIT(0) > +#define ARM_SHORT_PTE_TYPE_SMALL BIT(1) > +#define ARM_SHORT_PTE_BBIT(2) > +#define ARM_SHORT_PTE_CBIT(3) > +#define ARM_SHORT_PTE_SMALL_TEX0 BIT(6) > +#define ARM_SHORT_PTE_IMPLEBIT(9) This is AP[2] for small pages. > +#define ARM_SHORT_PTE_SBIT(10) > +#define ARM_SHORT_PTE_nG BIT(11) > +#define ARM_SHORT_PTE_LARGE_TEX0 BIT(12) > +#define ARM_SHORT_PTE_LARGE_XN BIT(15) > +#define ARM_SHORT_PTE_LARGE_MSK(~(SZ_64K - 1)) > +#define ARM_SHORT_PTE_SMALL_MSK(~(SZ_4K - 1)) > +#define ARM_SHORT_PTE_TYPE_MSK \ > + (ARM_SHORT_PTE_TYPE_LARGE | ARM_SHORT_PTE_TYPE_SMALL) > +#define ARM_SHORT_PTE_TYPE_IS_SMALLPAGE(pte) \ > + (pte) & ARM_SHORT_PTE_TYPE_MSK) >> 1) << 1)\ > + == ARM_SHORT_PTE_TYPE_SMALL) I see what you're trying to do here, but the shifting is confusing. I think it's better doing something like: ((pte) & ARM_SHORT_PTE_TYPE_SMALL) == ARM_SHORT_PTE_TYPE_SMALL or even just: (pte) & ARM_SHORT_PTE_TYPE_SMALL > +#define ARM_SHORT_PTE_TYPE_IS_LARGEPAGE(pte) \ > + (((pte) & ARM_SHORT_PTE_TYPE_MSK) == ARM_SHORT_PTE_TYPE_LARGE) > + > +#define ARM_SHORT_PGD_IDX(a) ((a) >> ARM_SHORT_PGDIR_SHIFT) > +#define ARM_SHORT_PTE_IDX(a) \ > + (((a) >> ARM_SHORT_PAGE_SHIFT) & (ARM_SHORT_PTRS_PER_PTE - 1)) > + > +#define ARM_SHORT_GET_PTE_VA(pgd) \ > + (phys_to_virt((unsigned long)pgd & ARM_SHORT_PGD_PGTABLE_MSK)) Maybe better named as ARM_SHORT_GET_PGTABLE_VA ? > + > +#define ARM_SHORT_PTE_LARGE_GET_PROT(pte) \ > + (((pte) & (~ARM_SHORT_PTE_LARGE_MSK)) & ~ARM_SHORT_PTE_TYPE_MSK) > + > +#define ARM_SHORT_PGD_GET_PROT(pgd)\ > + (((pgd) & (~ARM_SHORT_
Re: Since Linux 4.1: A lot of AMD-Vi IO_PAGE_FAULTs
On Tue, Jul 21, 2015 at 06:20:23PM +0200, Andreas Hartmann wrote: > [ 48.193901] <6>[fglrx] Firegl kernel thread PID: 1840 > [ 48.193985] <6>[fglrx] Firegl kernel thread PID: 1841 > [ 48.194063] <6>[fglrx] Firegl kernel thread PID: 1842 > [ 48.194172] <6>[fglrx] IRQ 28 Enabled > [ 48.261580] <6>[fglrx] Reserved FB block: Shared offset:0, size:100 > [ 48.261586] <6>[fglrx] Reserved FB block: Unshared offset:f7b4000, > size:4000 > [ 48.261587] <6>[fglrx] Reserved FB block: Unshared offset:f7b8000, > size:548000 > [ 48.261588] <6>[fglrx] Reserved FB block: Unshared offset:3fff3000, > size:d000 >From a first glance it doesn't look like an IOMMU driver issue, because the addresses where the faults happen are not from the AMD IOMMU driver. And you have proprietary closed-source drivers loaded, can you reproduce the issue without fglrx? Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: Since Linux 4.1: A lot of AMD-Vi IO_PAGE_FAULTs
On Tue, Jul 21, 2015 at 06:20:23PM +0200, Andreas Hartmann wrote: > Hi Jörg, > > I attached the dmesg output of the boot seuqence. This time after > reboot, the amount of IO_PAGE_FAULTs is not that much, but now, I got a > few ata3.00 errors. > > > Am 21.07.2015 um 17:56 schrieb Joerg Roedel: > > Hi Andreas, > > > > On Tue, Jul 21, 2015 at 09:34:46AM -0600, Alex Williamson wrote: > >>> Since Linux 4.1, I'm getting a lot of IO_PAGE_FAULT like this one > > To be more precise: The last kernel w/o this problem is 3.18.x - I never > used 3.19 or 4.0. Hmm, so you don't know whether 3.19 and 4.0 show the same problems? Can you find that out eventually? I look into your dmesg in the meantime. Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 07/11] iommu/omap: Remove unnecessary error traces on alloc failures
Hi Suman, Thank you for the patch. On Monday 20 July 2015 17:33:29 Suman Anna wrote: > Fix couple of checkpatch warnings of the type, > "WARNING: Possible unnecessary 'out of memory' message" > > Signed-off-by: Suman Anna The commit message could also mention that the reason to remove the error messages is that memory allocation failures will already be reported in the kernel log by the memory management code. No big deal though, Reviewed-by: Laurent Pinchart > --- > drivers/iommu/omap-iommu.c | 8 ++-- > 1 file changed, 2 insertions(+), 6 deletions(-) > > diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c > index 0fc00f31c39d..4328d9855edb 100644 > --- a/drivers/iommu/omap-iommu.c > +++ b/drivers/iommu/omap-iommu.c > @@ -1093,16 +1093,12 @@ static struct iommu_domain > *omap_iommu_domain_alloc(unsigned type) return NULL; > > omap_domain = kzalloc(sizeof(*omap_domain), GFP_KERNEL); > - if (!omap_domain) { > - pr_err("kzalloc failed\n"); > + if (!omap_domain) > goto out; > - } > > omap_domain->pgtable = kzalloc(IOPGD_TABLE_SIZE, GFP_KERNEL); > - if (!omap_domain->pgtable) { > - pr_err("kzalloc failed\n"); > + if (!omap_domain->pgtable) > goto fail_nomem; > - } > > /* >* should never fail, but please keep this around to ensure -- Regards, Laurent Pinchart ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 04/11] iommu/omap: Protect omap-iopgtable.h against double inclusion
Hi Suman, Thank you for the patch. On Monday 20 July 2015 17:33:26 Suman Anna wrote: > Protect the omap-pgtable.h header against double inclusion in > source code by using the standard include guard mechanism. > > Signed-off-by: Suman Anna Reviewed-by: Laurent Pinchart > --- > drivers/iommu/omap-iopgtable.h | 5 + > 1 file changed, 5 insertions(+) > > diff --git a/drivers/iommu/omap-iopgtable.h b/drivers/iommu/omap-iopgtable.h > index f891683e3f05..bfde5405f514 100644 > --- a/drivers/iommu/omap-iopgtable.h > +++ b/drivers/iommu/omap-iopgtable.h > @@ -10,6 +10,9 @@ > * published by the Free Software Foundation. > */ > > +#ifndef _OMAP_IOPGTABLE_H > +#define _OMAP_IOPGTABLE_H > + > /* > * "L2 table" address mask and size definitions. > */ > @@ -93,3 +96,5 @@ static inline phys_addr_t omap_iommu_translate(u32 d, u32 > va, u32 mask) /* to find an entry in the second-level page table. */ > #define iopte_index(da) (((da) >> IOPTE_SHIFT) & > (PTRS_PER_IOPTE - 1)) > #define iopte_offset(iopgd, da) (iopgd_page_vaddr(iopgd) + iopte_index(da)) > + > +#endif /* _OMAP_IOPGTABLE_H */ -- Regards, Laurent Pinchart ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 02/11] iommu/omap: Remove all module references
Hi Suman, On Monday 20 July 2015 17:33:24 Suman Anna wrote: > The OMAP IOMMU driver has been adapted to the IOMMU framework > for a while now, and it does not support being built as a > module anymore. So, remove all the module references from the > OMAP IOMMU driver. > > While at it, also relocate a comment around the subsys_initcall > to avoid a checkpatch strict warning about using a blank line > after function/struct/union/enum declarations. > > Signed-off-by: Suman Anna I think this is one of the checkpatch warnings that can be safely ignored, but it doesn't matter much. The comment will be removed after the OMAP3 ISP and OMAP IOMMU drivers get support for a saner IOMMU probing dependency order solution. The code seems fine to me. Reviewed-by: Laurent Pinchart > --- > drivers/iommu/omap-iommu.c | 19 +-- > 1 file changed, 1 insertion(+), 18 deletions(-) > > diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c > index a22c33d6a486..eeecfc4073af 100644 > --- a/drivers/iommu/omap-iommu.c > +++ b/drivers/iommu/omap-iommu.c > @@ -12,7 +12,6 @@ > */ > > #include > -#include > #include > #include > #include > @@ -1089,7 +1088,6 @@ static const struct of_device_id omap_iommu_of_match[] > = { { .compatible = "ti,dra7-iommu" }, > {}, > }; > -MODULE_DEVICE_TABLE(of, omap_iommu_of_match); > > static struct platform_driver omap_iommu_driver = { > .probe = omap_iommu_probe, > @@ -1405,20 +1403,5 @@ static int __init omap_iommu_init(void) > > return platform_driver_register(&omap_iommu_driver); > } > -/* must be ready before omap3isp is probed */ > subsys_initcall(omap_iommu_init); > - > -static void __exit omap_iommu_exit(void) > -{ > - kmem_cache_destroy(iopte_cachep); > - > - platform_driver_unregister(&omap_iommu_driver); > - > - omap_iommu_debugfs_exit(); > -} > -module_exit(omap_iommu_exit); > - > -MODULE_DESCRIPTION("omap iommu: tlb and pagetable primitives"); > -MODULE_ALIAS("platform:omap-iommu"); > -MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi"); > -MODULE_LICENSE("GPL v2"); > +/* must be ready before omap3isp is probed */ -- Regards, Laurent Pinchart ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: Since Linux 4.1: A lot of AMD-Vi IO_PAGE_FAULTs
Hi Andreas, On Tue, Jul 21, 2015 at 09:34:46AM -0600, Alex Williamson wrote: > > Since Linux 4.1, I'm getting a lot of IO_PAGE_FAULT like this one > > > > [ 17.048609] AMD-Vi: Event logged [IO_PAGE_FAULT device=00:11.0 > > domain=0x0008 address=0x40ebaaab00618000 flags=0x0010] > > > > with different addresses: > > > > 0x40ebaaab00618000 > > 0x40ebaaab00618040 > > 0x > > 0x0180 > > 0x00c0 > > 0x0080 > > 0x0100 > > 0x0040 > > 0x0140 > > 0x01c0 > > 0x0200 > > 0x0240 > > 0x0280 These addresses are not returned from the address allocator of the AMD IOMMU driver. Hard to tell what went wrong here, can you probably get a complete boot-log (dmesg output after boot) and send it to me? Please also boot with amd_iommu_dump on the kernel command line. Thanks, Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 01/11] Documentation: dt: Add #iommu-cells info to OMAP iommu bindings
Hi Suman, Thank you for the patch. On Monday 20 July 2015 17:33:23 Suman Anna wrote: > The OMAP IOMMU bindings is updated to reflect the required #iommu-cells > property. > > Signed-off-by: Suman Anna This brings the documentation in sync with both mainline DT sources and code so it looks good to me. Reviewed-by: Laurent Pinchart > --- > Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt > b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt index > 42531dc387aa..869699925fd5 100644 > --- a/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt > +++ b/Documentation/devicetree/bindings/iommu/ti,omap-iommu.txt > @@ -8,6 +8,11 @@ Required properties: > - ti,hwmods : Name of the hwmod associated with the IOMMU instance > - reg: Address space for the configuration registers > - interrupts : Interrupt specifier for the IOMMU instance > +- #iommu-cells : Should be 0. OMAP IOMMUs are all "single-master" devices, > + and needs no additional data in the pargs specifier. > Please + also refer to the generic bindings document for > more info + on this property, > + Documentation/devicetree/bindings/iommu/iommu.txt > > Optional properties: > - ti,#tlb-entries : Number of entries in the translation look-aside buffer. > @@ -18,6 +23,7 @@ Optional properties: > Example: > /* OMAP3 ISP MMU */ > mmu_isp: mmu@480bd400 { > + #iommu-cells = <0>; > compatible = "ti,omap2-iommu"; > reg = <0x480bd400 0x80>; > interrupts = <24>; -- Regards, Laurent Pinchart ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: Since Linux 4.1: A lot of AMD-Vi IO_PAGE_FAULTs
[cc +iommu, +joerg] On Tue, 2015-07-21 at 17:04 +0200, Andreas Hartmann wrote: > Hello! > > Since Linux 4.1, I'm getting a lot of IO_PAGE_FAULT like this one > > [ 17.048609] AMD-Vi: Event logged [IO_PAGE_FAULT device=00:11.0 > domain=0x0008 address=0x40ebaaab00618000 flags=0x0010] > > with different addresses: > > 0x40ebaaab00618000 > 0x40ebaaab00618040 > 0x > 0x0180 > 0x00c0 > 0x0080 > 0x0100 > 0x0040 > 0x0140 > 0x01c0 > 0x0200 > 0x0240 > 0x0280 > > ... > > device=00:11.0 is: > > # lspci -vvs 00:11.0 > 00:11.0 SATA controller: Advanced Micro Devices, Inc. [AMD/ATI] > SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (rev 40) (prog-if 01 [AHCI > 1.0]) > Subsystem: Gigabyte Technology Co., Ltd Device b002 > Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- > ParErr- Stepping- SERR- FastB2B- DisINTx- > Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- > SERR- Latency: 32, Cache Line Size: 64 bytes > Interrupt: pin A routed to IRQ 19 > Region 0: I/O ports at ff00 [size=8] > Region 1: I/O ports at fe00 [size=4] > Region 2: I/O ports at fd00 [size=8] > Region 3: I/O ports at fc00 [size=4] > Region 4: I/O ports at fb00 [size=16] > Region 5: Memory at fdfff000 (32-bit, non-prefetchable) [size=1K] > Capabilities: [70] SATA HBA v1.0 InCfgSpace > Capabilities: [a4] PCI Advanced Features > AFCap: TP+ FLR+ > AFCtrl: FLR- > AFStatus: TP- > Kernel driver in use: ahci > > > Any idea what could be wrong? > > > Thanks, > kind regards, > Andreas Hartmann > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC PATCH 1/4] iommu/arm-smmu: Init driver using IOMMU_OF_DECLARE
[adding Robin] On Fri, Jul 17, 2015 at 05:53:22PM +0100, Sricharan R wrote: > This patch uses IOMMU_OF_DECLARE to register the driver > and the iommu_ops. So when master devices of the iommu are > registered, of_xlate callback can be used to add the master > configurations to the smmu driver. I'd really prefer to do this on top of Laurent's series reworking some of the of_xlate code and I think Robin [CC'd] is working on that. That will also pave the way for specifying per-master SMR configuration in the device-tree. Will ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC PATCH 3/4] iommu/arm-smmu: Add support for specifying clocks
On Fri, Jul 17, 2015 at 05:53:24PM +0100, Sricharan R wrote: > From: Mitchel Humpherys > > On some platforms with tight power constraints it is polite to only > leave your clocks on for as long as you absolutely need them. Currently > we assume that all clocks necessary for SMMU register access are always > on. You've borrowed this commit message from Mitch's previous version of this patch, but now you leave the clocks enabled most of the time so it doesn't make much sense anymore. Anyway, I'm OK with this kind of clock management in the driver, but I think that anything more fine-grained needs to be designed into the IOMMU core. Will ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 5/6] iommu/mediatek: Add mt8173 IOMMU driver
Hi Yong Wu, On Thu, Jul 16, 2015 at 10:04:34AM +0100, Yong Wu wrote: > This patch adds support for mediatek m4u (MultiMedia Memory Management > Unit). [...] > +static void mtk_iommu_tlb_flush_all(void *cookie) > +{ > + struct mtk_iommu_domain *domain = cookie; > + void __iomem *base; > + > + base = domain->data->base; > + writel(F_INVLD_EN1 | F_INVLD_EN0, base + REG_MMU_INV_SEL); > + writel(F_ALL_INVLD, base + REG_MMU_INVALIDATE); This needs to be synchronous, so you probably want to call mtk_iommu_tlb_sync at the end. > +} > + > +static void mtk_iommu_tlb_add_flush(unsigned long iova, size_t size, > + bool leaf, void *cookie) > +{ > + struct mtk_iommu_domain *domain = cookie; > + void __iomem *base = domain->data->base; > + unsigned int iova_start = iova, iova_end = iova + size - 1; > + > + writel(F_INVLD_EN1 | F_INVLD_EN0, base + REG_MMU_INV_SEL); > + > + writel(iova_start, base + REG_MMU_INVLD_START_A); > + writel(iova_end, base + REG_MMU_INVLD_END_A); > + writel(F_MMU_INV_RANGE, base + REG_MMU_INVALIDATE); Why are you using writel instead of writel_relaxed? I asked this before but I don't think you replied. Will ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 0/5] iommu/arm-smmu: add support for non-pci devices
On 21/07/15 08:30, Zhen Lei wrote: Changelog: v2 -> v3: 1. add support for pci device hotplug, which missed in patch v2. 2. only support #iommu-cells = <1>, add corresponding description in arm,smmu-v3.txt. 3. add function find_smmu_by_device which extracted from find_smmu_by_node, to resolve the problem mentioned by Robin Murphy in [PATCH v2 7/9]. Additionally: +platform_set_drvdata(pdev, smmu); //Patch v2 + dev->archdata.iommu = smmu; //Patch v3, dev = &pdev->dev I didn't give any Reviewed-by tags, much less to revised patches that I've not even looked at yet; please see section 13 of Documentation/SubmittingPatches for what the Reviewed-by tag means. Robin. v1 -> v2: update the implementation of patch 1/9 according to Will Deacon's suggestion. update the comment of patch 3/9 and 4/9. use arm_smmu_options to skip the execution of command CMD_PREFETCH_CONFIG, see patch 5/9. patch 6/9 is base on Laurent's series, to support probe deferral. patch 7/9 according to Robin Murphy's suggestion, remove global variable arm_smmu_devices, thanks. patch 9/9 add support for a master with multiple stream IDs. Zhen Lei (5): iommu/arm-smmu: to support probe deferral iommu/arm-smmu: remove arm_smmu_devices iommu/arm-smmu: rename __arm_smmu_get_pci_sid iommu/arm-smmu: add support for non-pci devices iommu/arm-smmu: describe the limitation of #iommu-cells .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 + drivers/iommu/arm-smmu-v3.c| 209 - 2 files changed, 163 insertions(+), 52 deletions(-) -- 1.8.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 3/5] iommu/arm-smmu: rename __arm_smmu_get_pci_sid
Remove the words "pci", to make this function can also be used by non-pci devices. Signed-off-by: Zhen Lei --- drivers/iommu/arm-smmu-v3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 9daf4cc..216c9d4 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -1734,7 +1734,7 @@ static int __arm_smmu_get_pci_sid(struct pci_dev *pdev, u16 alias, void *sidp) return 0; /* Continue walking */ } -static void __arm_smmu_release_pci_iommudata(void *data) +static void __arm_smmu_release_iommudata(void *data) { kfree(data); } @@ -1811,7 +1811,7 @@ static int __arm_smmu_add_device(struct device *dev, u32 sid) smmu_group->ste.valid = true; smmu_group->smmu= smmu; iommu_group_set_iommudata(group, smmu_group, - __arm_smmu_release_pci_iommudata); + __arm_smmu_release_iommudata); } else { smmu = smmu_group->smmu; } -- 1.8.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 5/5] iommu/arm-smmu: describe the limitation of #iommu-cells
Only support #iommu-cells = <1>. Signed-off-by: Zhen Lei --- Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt | 6 ++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index 3443e0f..7d110a1 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -5,6 +5,12 @@ revisions, replacing the MMIO register interface with in-memory command and event queues and adding support for the ATS and PRI components of the PCIe specification. +Please read ./iommu.txt first, here list something special as below: + +** SMMUv3 limited properties: +- #iommu-cells : fixed to <1>. The pci root device is a special case, + its IDs can be omitted in dts, seems #iommu-cells = <0>. + ** SMMUv3 required properties: - compatible: Should include: -- 1.8.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 2/5] iommu/arm-smmu: remove arm_smmu_devices
It can be replaced by of_iommu_list(in of_iommu.c). Reviewed-by: Robin Murphy Signed-off-by: Zhen Lei --- drivers/iommu/arm-smmu-v3.c | 22 ++ 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 474eca4..9daf4cc 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -605,10 +605,6 @@ struct arm_smmu_domain { struct iommu_domain domain; }; -/* Our list of SMMU instances */ -static DEFINE_SPINLOCK(arm_smmu_devices_lock); -static LIST_HEAD(arm_smmu_devices); - struct arm_smmu_option_prop { u32 opt; const char *prop; @@ -2712,11 +2708,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) if (ret) goto out_free_structures; - /* Record our private device structure */ - INIT_LIST_HEAD(&smmu->list); - spin_lock(&arm_smmu_devices_lock); - list_add(&smmu->list, &arm_smmu_devices); - spin_unlock(&arm_smmu_devices_lock); dev->archdata.iommu = smmu; of_iommu_set_ops(smmu->dev->of_node, &arm_smmu_ops); @@ -2729,19 +2720,10 @@ out_free_structures: static int arm_smmu_device_remove(struct platform_device *pdev) { - struct arm_smmu_device *curr, *smmu = NULL; + struct arm_smmu_device *smmu; struct device *dev = &pdev->dev; - spin_lock(&arm_smmu_devices_lock); - list_for_each_entry(curr, &arm_smmu_devices, list) { - if (curr->dev == dev) { - smmu = curr; - list_del(&smmu->list); - break; - } - } - spin_unlock(&arm_smmu_devices_lock); - + smmu = find_smmu_by_device(dev); if (!smmu) return -ENODEV; -- 1.8.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 1/5] iommu/arm-smmu: to support probe deferral
For pci devices, only the root nodes have "iommus" property. So we should traverse all of its sub nodes in of_xlate. There exists two cases: Case 1: .add_device(sub node) happened before .of_xlate(root node) Case 2: .add_device(sub node) happened after .of_xlate(root node) (1).add_device if (!root->archdata.iommu) return -ENODEV; (2).of_xlate root->archdata.iommu = smmu; /* * Probe the pci devices deferred in phase (1) */ (3).add_device /* * After phase (2), it's not NULL */ if (!root->archdata.iommu) return -ENODEV; __arm_smmu_add_pci_device(pdev, root->archdata.iommu); Reviewed-by: Robin Murphy Signed-off-by: Zhen Lei --- drivers/iommu/arm-smmu-v3.c | 147 +++- 1 file changed, 117 insertions(+), 30 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 4f09337..474eca4 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include "io-pgtable.h" @@ -1741,32 +1743,37 @@ static void __arm_smmu_release_pci_iommudata(void *data) kfree(data); } -static struct arm_smmu_device *arm_smmu_get_for_pci_dev(struct pci_dev *pdev) +static struct arm_smmu_device *find_smmu_by_device(struct device *dev) +{ + struct device_node *np = dev->of_node; + + /* to ensure np is a smmu device node */ + if (!of_iommu_get_ops(np)) + return NULL; + + return dev->archdata.iommu; +} + +static struct arm_smmu_device *find_smmu_by_node(struct device_node *np) +{ + struct platform_device *pdev; + + pdev = of_find_device_by_node(np); + if (!pdev) + return NULL; + + return find_smmu_by_device(&pdev->dev); +} + +static struct device *arm_smmu_get_pci_dev_root(struct pci_dev *pdev) { - struct device_node *of_node; - struct arm_smmu_device *curr, *smmu = NULL; struct pci_bus *bus = pdev->bus; /* Walk up to the root bus */ while (!pci_is_root_bus(bus)) bus = bus->parent; - /* Follow the "iommus" phandle from the host controller */ - of_node = of_parse_phandle(bus->bridge->parent->of_node, "iommus", 0); - if (!of_node) - return NULL; - - /* See if we can find an SMMU corresponding to the phandle */ - spin_lock(&arm_smmu_devices_lock); - list_for_each_entry(curr, &arm_smmu_devices, list) { - if (curr->dev->of_node == of_node) { - smmu = curr; - break; - } - } - spin_unlock(&arm_smmu_devices_lock); - of_node_put(of_node); - return smmu; + return bus->bridge->parent; } static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid) @@ -1779,27 +1786,21 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid) return sid < limit; } -static int arm_smmu_add_device(struct device *dev) +static int __arm_smmu_add_device(struct device *dev, u32 sid) { int i, ret; - u32 sid, *sids; - struct pci_dev *pdev; + u32 *sids; struct iommu_group *group; struct arm_smmu_group *smmu_group; struct arm_smmu_device *smmu; - /* We only support PCI, for now */ - if (!dev_is_pci(dev)) - return -ENODEV; - - pdev = to_pci_dev(dev); group = iommu_group_get_for_dev(dev); if (IS_ERR(group)) return PTR_ERR(group); smmu_group = iommu_group_get_iommudata(group); if (!smmu_group) { - smmu = arm_smmu_get_for_pci_dev(pdev); + smmu = dev->archdata.iommu; if (!smmu) { ret = -ENOENT; goto out_put_group; @@ -1819,8 +1820,6 @@ static int arm_smmu_add_device(struct device *dev) smmu = smmu_group->smmu; } - /* Assume SID == RID until firmware tells us otherwise */ - pci_for_each_dma_alias(pdev, __arm_smmu_get_pci_sid, &sid); for (i = 0; i < smmu_group->num_sids; ++i) { /* If we already know about this SID, then we're done */ if (smmu_group->sids[i] == sid) @@ -1857,11 +1856,43 @@ static int arm_smmu_add_device(struct device *dev) out_put_group: iommu_group_put(group); + dev_err(dev, "failed to add into SMMU\n"); return ret; } +static int __arm_smmu_add_pci_device(struct pci_dev *pdev, void *smmu) +{ + u32 sid; + struct device *dev = &pdev->dev; + + /* Assume SID == RID until firmware tells us otherwise */ + pci_for_each_dma_alias(pdev, __arm_smmu_get_pci_sid, &sid); + + dev->archdata.iommu = smmu; + + return __arm_smmu_add_device(dev, sid); +} + +static int arm_smmu_add_device(struct device *dev) +{ + str
[PATCH v3 4/5] iommu/arm-smmu: add support for non-pci devices
This patch support a master with multiple stream IDs, but doesn't support a master behinds more than one SMMUs. Reviewed-by: Robin Murphy Signed-off-by: Zhen Lei --- drivers/iommu/arm-smmu-v3.c | 40 ++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 216c9d4..129ff36 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -1965,9 +1966,36 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args) return -EINVAL; } - /* We only support PCI, for now */ if (!dev_is_pci(dev)) { - return -ENODEV; + struct iommu_group *group; + + if (args->args_count != 1) { + dev_err(dev, + "only support #iommu-cells = <1>, please check node: %s\n", + dev_name(smmu->dev)); + return -ENODEV; + } + + group = iommu_group_get(dev); + if (!group) { + group = iommu_group_alloc(); + if (IS_ERR(group)) { + dev_err(dev, "failed to allocate IOMMU group\n"); + return PTR_ERR(group); + } + + ret = iommu_group_add_device(group, dev); + if (ret) { + iommu_group_put(group); + dev_err(dev, "failed to add device into IOMMU group\n"); + return ret; + } + } + iommu_group_put(group); + + ret = __arm_smmu_add_device(dev, args->args[0]); + if (ret) + return ret; } else { struct device *root; struct pci_dev *pdev = NULL; @@ -2762,6 +2790,14 @@ static int __init arm_smmu_init(void) if (ret) return ret; + if (!iommu_present(&platform_bus_type)) + bus_set_iommu(&platform_bus_type, &arm_smmu_ops); + +#ifdef CONFIG_ARM_AMBA + if (!iommu_present(&amba_bustype)) + bus_set_iommu(&amba_bustype, &arm_smmu_ops); +#endif + return bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } -- 1.8.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 0/5] iommu/arm-smmu: add support for non-pci devices
Changelog: v2 -> v3: 1. add support for pci device hotplug, which missed in patch v2. 2. only support #iommu-cells = <1>, add corresponding description in arm,smmu-v3.txt. 3. add function find_smmu_by_device which extracted from find_smmu_by_node, to resolve the problem mentioned by Robin Murphy in [PATCH v2 7/9]. Additionally: +platform_set_drvdata(pdev, smmu); //Patch v2 +dev->archdata.iommu = smmu; //Patch v3, dev = &pdev->dev v1 -> v2: update the implementation of patch 1/9 according to Will Deacon's suggestion. update the comment of patch 3/9 and 4/9. use arm_smmu_options to skip the execution of command CMD_PREFETCH_CONFIG, see patch 5/9. patch 6/9 is base on Laurent's series, to support probe deferral. patch 7/9 according to Robin Murphy's suggestion, remove global variable arm_smmu_devices, thanks. patch 9/9 add support for a master with multiple stream IDs. Zhen Lei (5): iommu/arm-smmu: to support probe deferral iommu/arm-smmu: remove arm_smmu_devices iommu/arm-smmu: rename __arm_smmu_get_pci_sid iommu/arm-smmu: add support for non-pci devices iommu/arm-smmu: describe the limitation of #iommu-cells .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 + drivers/iommu/arm-smmu-v3.c| 209 - 2 files changed, 163 insertions(+), 52 deletions(-) -- 1.8.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu