[RESEND PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. New named irq "combined" is set as a errata workaround, which allows to share the irq line by register single irq handler for all the interrupts. Signed-off-by: Geetha sowjanya --- Documentation/arm64/silicon-errata.txt |1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |6 + drivers/acpi/arm64/iort.c | 57 --- drivers/iommu/arm-smmu-v3.c| 100 ++- 4 files changed, 121 insertions(+), 43 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 4693a32..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -63,6 +63,7 @@ stable kernels. | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | | Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index e7855cf..c9abbf3 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -26,6 +26,12 @@ the PCIe specification. * "priq" - PRI Queue not empty * "cmdq-sync" - CMD_SYNC complete * "gerror"- Global Error activated + * "combined" - The combined interrupt is optional, + and should only be provided if the + hardware supports just a single, + combined interrupt line. + If provided, then the combined interrupt + will be used in preference to any others. - #iommu-cells : See the generic IOMMU binding described in devicetree/bindings/pci/pci-iommu.txt diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index bd97b7d..21c1ed3 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -828,6 +828,18 @@ static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node) return num_res; } +static bool arm_smmu_v3_is_combined_irq(struct acpi_iort_smmu_v3 *smmu) +{ + /* +* Cavium ThunderX2 implementation doesn't not support unique +* irq line. Use single irq line for all the SMMUv3 interrupts. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + return true; + + return false; +} + static unsigned long arm_smmu_v3_resource_size(struct acpi_iort_smmu_v3 *smmu) { /* @@ -855,26 +867,39 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, res[num_res].flags = IORESOURCE_MEM; num_res++; + if (arm_smmu_v3_is_combined_irq(smmu)) { + int irq = smmu->event_gsiv; - if (smmu->event_gsiv) - acpi_iort_register_irq(smmu->event_gsiv, "eventq", - ACPI_EDGE_SENSITIVE, - &res[num_res++]); - - if (smmu->pri_gsiv) - acpi_iort_register_irq(smmu->pri_gsiv, "priq", - ACPI_EDGE_SENSITIVE, - &res[num_res++]); - - if (smmu->gerr_gsiv) - acpi_iort_register_irq(smmu->gerr_gsiv, "gerror", + if (!(irq == smmu->pri_gsiv && irq == smmu->gerr_gsiv && + irq == smmu->sync_gsiv)) { + pr_warn(FW_BUG "Incosistent combined GSIV configuration\n"); + return; + } + acpi_iort_register_irq(smmu->event_gsiv, "combined", ACPI_EDGE_SENSITIVE, &res[num_res++]); + } else { - if (smmu->sync_gsiv) - acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync", - ACPI_EDGE_SENSITIVE, - &a
[PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. New named irq "combined" is set as a errata workaround, which allows to share the irq line by register single irq handler for all the interrupts. Signed-off-by: Geetha sowjanya --- Documentation/arm64/silicon-errata.txt |1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |6 + drivers/acpi/arm64/iort.c | 54 +++ drivers/iommu/arm-smmu-v3.c| 100 ++- 4 files changed, 116 insertions(+), 45 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 4693a32..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -63,6 +63,7 @@ stable kernels. | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | | Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index e7855cf..c9abbf3 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -26,6 +26,12 @@ the PCIe specification. * "priq" - PRI Queue not empty * "cmdq-sync" - CMD_SYNC complete * "gerror"- Global Error activated + * "combined" - The combined interrupt is optional, + and should only be provided if the + hardware supports just a single, + combined interrupt line. + If provided, then the combined interrupt + will be used in preference to any others. - #iommu-cells : See the generic IOMMU binding described in devicetree/bindings/pci/pci-iommu.txt diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index bd97b7d..4e9523b 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -828,6 +828,18 @@ static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node) return num_res; } +static bool arm_smmu_v3_is_combined_irq(struct acpi_iort_smmu_v3 *smmu) +{ + /* +* Cavium ThunderX2 implementation doesn't not support unique +* irq line. Use single irq line for all the SMMUv3 interrupts. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + return true; + + return false; +} + static unsigned long arm_smmu_v3_resource_size(struct acpi_iort_smmu_v3 *smmu) { /* @@ -855,26 +867,32 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, res[num_res].flags = IORESOURCE_MEM; num_res++; - - if (smmu->event_gsiv) - acpi_iort_register_irq(smmu->event_gsiv, "eventq", - ACPI_EDGE_SENSITIVE, - &res[num_res++]); - - if (smmu->pri_gsiv) - acpi_iort_register_irq(smmu->pri_gsiv, "priq", - ACPI_EDGE_SENSITIVE, - &res[num_res++]); - - if (smmu->gerr_gsiv) - acpi_iort_register_irq(smmu->gerr_gsiv, "gerror", - ACPI_EDGE_SENSITIVE, - &res[num_res++]); - - if (smmu->sync_gsiv) - acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync", + if (arm_smmu_v3_is_combined_irq(smmu)) + acpi_iort_register_irq(smmu->event_gsiv, "combined", ACPI_EDGE_SENSITIVE, &res[num_res++]); + else { + + if (smmu->event_gsiv) + acpi_iort_register_irq(smmu->event_gsiv, "eventq", + ACPI_EDGE_SENSITIVE, + &res[num_res++]); + + if (smmu->pri_gsiv) + acpi_iort_register_irq(smmu->p
[PATCH v9 2/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74
From: Linu Cherian Cavium ThunderX2 SMMU implementation doesn't support page 1 register space and PAGE0_REGS_ONLY option is enabled as an errata workaround. This option when turned on, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. SMMU resource size checks are now based on SMMU option PAGE0_REGS_ONLY, since resource size can be either 64k/128k. For this, arm_smmu_device_dt_probe/acpi_probe has been moved before platform_get_resource call, so that SMMU options are set beforehand. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt |1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |6 ++ drivers/iommu/arm-smmu-v3.c| 68 ++- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 10f2ddd..4693a32 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,7 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index be57550..6ecc48c 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -49,6 +49,12 @@ the PCIe specification. - hisilicon,broken-prefetch-cmd : Avoid sending CMD_PREFETCH_* commands to the SMMU. +- cavium,cn9900-broken-page1-regspace +: Replaces all page 1 offsets used for EVTQ_PROD/CONS, + PRIQ_PROD/CONS register access with page 0 offsets. + Set for Cavium ThunderX2 silicon that doesn't support + SMMU page1 register space. + ** Example smmu@2b40 { diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 380969a..2dea4a9 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -597,6 +597,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1) u32 options; struct arm_smmu_cmdqcmdq; @@ -663,9 +664,20 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium,cn9900-broken-page1-regspace"}, { 0, NULL}, }; +static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset, +struct arm_smmu_device *smmu) +{ + if ((offset > SZ_64K) && + (smmu->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY)) + offset -= SZ_64K; + + return smmu->base + offset; +} + static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); @@ -1961,8 +1973,8 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu, return -ENOMEM; } - q->prod_reg = smmu->base + prod_off; - q->cons_reg = smmu->base + cons_off; + q->prod_reg = arm_smmu_page1_fixup(prod_off, smmu); + q->cons_reg = arm_smmu_page1_fixup(cons_off, smmu); q->ent_dwords = dwords; q->q_base = Q_BASE_RWA; @@ -2363,8 +2375,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) /* Event queue */ writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE); - writel_relaxed(smmu->evtq.q.prod, smmu->base + ARM_SMMU_EVTQ_PROD); - writel_relaxed(smmu->evtq.q.cons, smmu->base + ARM_SMMU_EVTQ_CONS); + writel_relaxed(smmu->evtq.q.prod, + arm_smmu_page1_fixup(ARM_SMMU_EVTQ_PROD, smmu)); + writel_relaxed(smmu->evtq.q.cons, + arm_smmu_page1_fixup(ARM_SMMU_EVTQ_CONS, smmu)); enables |= CR0_EVTQEN; ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0, @@ -2379,9 +2393,9 @@ static int arm_s
[PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. New named irq "combined" is set as a errata workaround, which allows to share the irq line by register single irq handler for all the interrupts. Signed-off-by: Geetha sowjanya --- Documentation/arm64/silicon-errata.txt |1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |1 + drivers/acpi/arm64/iort.c | 54 +++ drivers/iommu/arm-smmu-v3.c| 105 +++- 4 files changed, 116 insertions(+), 45 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 4693a32..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -63,6 +63,7 @@ stable kernels. | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | | Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index 6ecc48c..a5a1ca4 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -26,6 +26,7 @@ the PCIe specification. * "priq" - PRI Queue not empty * "cmdq-sync" - CMD_SYNC complete * "gerror"- Global Error activated + * "combined" - Handles above all 4 interrupts. - #iommu-cells : See the generic IOMMU binding described in devicetree/bindings/pci/pci-iommu.txt diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c166f3e..43e1f13 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -828,6 +828,18 @@ static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node) return num_res; } +static bool arm_smmu_v3_is_combined_irq(struct acpi_iort_smmu_v3 *smmu) +{ + /* +* Cavium ThunderX2 implementation doesn't not support unique +* irq line. Use single irq line for all the SMMUv3 interrupts. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + return true; + + return false; +} + static unsigned long arm_smmu_v3_resource_size(struct acpi_iort_smmu_v3 *smmu) { /* @@ -855,26 +867,32 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, res[num_res].flags = IORESOURCE_MEM; num_res++; - - if (smmu->event_gsiv) - acpi_iort_register_irq(smmu->event_gsiv, "eventq", - ACPI_EDGE_SENSITIVE, - &res[num_res++]); - - if (smmu->pri_gsiv) - acpi_iort_register_irq(smmu->pri_gsiv, "priq", - ACPI_EDGE_SENSITIVE, - &res[num_res++]); - - if (smmu->gerr_gsiv) - acpi_iort_register_irq(smmu->gerr_gsiv, "gerror", - ACPI_EDGE_SENSITIVE, - &res[num_res++]); - - if (smmu->sync_gsiv) - acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync", + if (arm_smmu_v3_is_combined_irq(smmu)) + acpi_iort_register_irq(smmu->event_gsiv, "combined", ACPI_EDGE_SENSITIVE, &res[num_res++]); + else { + + if (smmu->event_gsiv) + acpi_iort_register_irq(smmu->event_gsiv, "eventq", + ACPI_EDGE_SENSITIVE, + &res[num_res++]); + + if (smmu->pri_gsiv) + acpi_iort_register_irq(smmu->pri_gsiv, "priq", + ACPI_EDGE_SENSITIVE, + &res[num_res++]); + + if (smmu->gerr_gsiv) + acpi_iort_register_irq(smmu->gerr_gsiv, "gerror", +
[PATCH v9 1/3] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model
From: Linu Cherian Cavium ThunderX2 implementation doesn't support second page in SMMU register space. Hence, resource size is set as 64k for this model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/acpi/arm64/iort.c | 15 ++- 1 files changed, 14 insertions(+), 1 deletions(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf9..c166f3e 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -828,6 +828,18 @@ static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node) return num_res; } +static unsigned long arm_smmu_v3_resource_size(struct acpi_iort_smmu_v3 *smmu) +{ + /* +* Override the size, for Cavium ThunderX2 implementation +* which doesn't support the page 1 SMMU register space. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + return SZ_64K; + + return SZ_128K; +} + static void __init arm_smmu_v3_init_resources(struct resource *res, struct acpi_iort_node *node) { @@ -838,7 +850,8 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, smmu = (struct acpi_iort_smmu_v3 *)node->node_data; res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + + arm_smmu_v3_resource_size(smmu) - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; -- 1.7.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v9 0/3] Cavium ThunderX2 SMMUv3 errata workarounds
Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines and also MSI for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on patchset. https://www.spinics.net/lists/arm-kernel/msg578443.html Changes since v8: - Reworked patch #3 as suggested by Will. - Corrected typo mistake in patch #2 Changes since v7: - Added new function "arm_smmu_v3_resource_size" in iort.c to get resource size. - Added new SMMU option "SHARED_IRQ" to enable errata #126 workaround. - Coding style issues fixed. - Suggested changes in arm_smmu_device_probe addressed. - Replaced ACPI_IORT_SMMU_CAVIUM_CN99XX macro with ACPI_IORT_SMMU_V3_CAVIUM_CN99XX Changes since v6: - Changed device tree compatible string to vendor specific. - Rebased on Robin's latest "Update SMMU models for IORT rev. C" v2 patch. https://www.spinics.net/lists/arm-kernel/msg582809.html Changes since v5: - Rebased on Robin's "Update SMMU models for IORT rev. C" patch. https://www.spinics.net/lists/arm-kernel/msg580728.html - Replaced ACPI_IORT_SMMU_V3_CAVIUM_CN99XX macro with ACPI_IORT_SMMU_CAVIUM_CN99XX Changes since v4: - Replaced all page1 offset macros ARM_SMMU_EVTQ/PRIQ_PROD/CONS with arm_smmu_page1_fixup(ARM_SMMU_EVTQ/PRIQ_PROD/CONS, smmu) Changes since v3: - Merged patches 1, 2 and 4 of Version 3. - Modified the page1_offset_adjust() and get_irq_flags() implementation as suggested by Robin. Changes since v2: - Updated "Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt" document with new SMMU option used to enable errata workaround. Changes since v1: - Since the use of MIDR register is rejected and SMMU_IIDR is broken on this silicon, as suggested by Will Deacon modified the patches to use ThunderX2 SMMUv3 IORT model number to enable errata workaround. Geetha Sowjanya (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Linu Cherian (2): ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74 Documentation/arm64/silicon-errata.txt |2 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |7 + drivers/acpi/arm64/iort.c | 69 ++--- drivers/iommu/arm-smmu-v3.c| 171 +++- 4 files changed, 186 insertions(+), 63 deletions(-) ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v8 0/3] Cavium ThunderX2 SMMUv3 errata workarounds
Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines and also MSI for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on patchset. https://www.spinics.net/lists/arm-kernel/msg578443.html Changes since v7: - Added new function "arm_smmu_v3_resource_size" in iort.c to get resource size. - Added new SMMU option "SHARED_IRQ" to enable errata #126 workaround. - Coding style issues fixed. - Suggested changes in arm_smmu_device_probe addressed. - Replaced ACPI_IORT_SMMU_CAVIUM_CN99XX macro with ACPI_IORT_SMMU_V3_CAVIUM_CN99XX Changes since v6: - Changed device tree compatible string to vendor specific. - Rebased on Robin's latest "Update SMMU models for IORT rev. C" v2 patch. https://www.spinics.net/lists/arm-kernel/msg582809.html Changes since v5: - Rebased on Robin's "Update SMMU models for IORT rev. C" patch. https://www.spinics.net/lists/arm-kernel/msg580728.html - Replaced ACPI_IORT_SMMU_V3_CAVIUM_CN99XX macro with ACPI_IORT_SMMU_CAVIUM_CN99XX Changes since v4: - Replaced all page1 offset macros ARM_SMMU_EVTQ/PRIQ_PROD/CONS with arm_smmu_page1_fixup(ARM_SMMU_EVTQ/PRIQ_PROD/CONS, smmu) Changes since v3: - Merged patches 1, 2 and 4 of Version 3. - Modified the page1_offset_adjust() and get_irq_flags() implementation as suggested by Robin. Changes since v2: - Updated "Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt" document with new SMMU option used to enable errata workaround. Changes since v1: - Since the use of MIDR register is rejected and SMMU_IIDR is broken on this silicon, as suggested by Will Deacon modified the patches to use ThunderX2 SMMUv3 IORT model number to enable errata workaround. Geetha Sowjanya (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Linu Cherian (2): ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74 Documentation/arm64/silicon-errata.txt |2 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |6 ++ drivers/acpi/arm64/iort.c | 14 +++- drivers/iommu/arm-smmu-v3.c| 93 4 files changed, 95 insertions(+), 20 deletions(-) ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v8 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. SHARED_IRQ option is set as a errata workaround, which allows to share the irq line by register single irq handler for all the interrupts. Signed-off-by: Geetha sowjanya --- .../devicetree/bindings/iommu/arm,smmu-v3.txt |5 ++ drivers/iommu/arm-smmu-v3.c| 73 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index 6ecc48c..44b40e0 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -55,6 +55,11 @@ the PCIe specification. Set for Caviun ThunderX2 silicon that doesn't support SMMU page1 register space. +- cavium,cn9900-broken-unique-irqline +: Use single irq line for all the SMMUv3 interrupts. + Set for Caviun ThunderX2 silicon that doesn't support + MSI and also doesn't have unique irq lines for gerror, + eventq and cmdq-sync. ** Example smmu@2b40 { diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 2dea4a9..6c0c632 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -598,6 +598,7 @@ struct arm_smmu_device { #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) #define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1) +#define ARM_SMMU_OPT_SHARED_IRQ(1 << 2) u32 options; struct arm_smmu_cmdqcmdq; @@ -665,6 +666,7 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium,cn9900-broken-page1-regspace"}, + { ARM_SMMU_OPT_SHARED_IRQ, "cavium,cn9900-broken-unique-irqline"}, { 0, NULL}, }; @@ -1313,6 +1315,21 @@ static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev) writel(gerror, smmu->base + ARM_SMMU_GERRORN); return IRQ_HANDLED; } +/* Shared irq handler*/ +static irqreturn_t arm_smmu_shared_irq_thread(int irq, void *dev) +{ + struct arm_smmu_device *smmu = dev; + irqreturn_t ret; + + ret = arm_smmu_gerror_handler(irq, dev); + if (ret == IRQ_NONE) { + arm_smmu_evtq_thread(irq, dev); + arm_smmu_cmdq_sync_handler(irq, dev); + if (smmu->features & ARM_SMMU_FEAT_PRI) + arm_smmu_priq_thread(irq, dev); + } + return IRQ_HANDLED; +} /* IO_PGTABLE API */ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu) @@ -2230,18 +2247,9 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) devm_add_action(dev, arm_smmu_free_msis, dev); } -static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) +static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu) { - int ret, irq; - u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN; - - /* Disable IRQs first */ - ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL, - ARM_SMMU_IRQ_CTRLACK); - if (ret) { - dev_err(smmu->dev, "failed to disable irqs\n"); - return ret; - } + int irq, ret; arm_smmu_setup_msis(smmu); @@ -2284,10 +2292,46 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (ret < 0) dev_warn(smmu->dev, "failed to enable priq irq\n"); - else - irqen_flags |= IRQ_CTRL_PRIQ_IRQEN; } } +} + +static void arm_smmu_setup_shared_irqs(struct arm_smmu_device *smmu) +{ + int ret, irq; + + /* Single irq is used for all queues, request single interrupt lines */ + irq = smmu->evtq.q.irq; + if (irq) { + ret = devm_request_threaded_irq(smmu->dev, irq, NULL, + arm_smmu_shared_irq_thread, + IRQF_ONESHOT | IRQF_SHARED, + "arm-smmu-v3-shared_irq", smmu); + if (ret < 0) + dev_warn(smmu->dev, "failed to enable shared irq\n"); + } +} + +static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) +{ + int ret; + u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN; + + /* Disable IRQs first */ + ret = arm_smmu_write_reg_sync(smmu,
[PATCH v8 2/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74
From: Linu Cherian Cavium ThunderX2 SMMU implementation doesn't support page 1 register space and PAGE0_REGS_ONLY option is enabled as an errata workaround. This option when turned on, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. SMMU resource size checks are now based on SMMU option PAGE0_REGS_ONLY, since resource size can be either 64k/128k. For this, arm_smmu_device_dt_probe/acpi_probe has been moved before platform_get_resource call, so that SMMU options are set beforehand. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt |1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |6 ++ drivers/iommu/arm-smmu-v3.c| 68 ++- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 10f2ddd..4693a32 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,7 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index be57550..6ecc48c 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -49,6 +49,12 @@ the PCIe specification. - hisilicon,broken-prefetch-cmd : Avoid sending CMD_PREFETCH_* commands to the SMMU. +- cavium,cn9900-broken-page1-regspace +: Replaces all page 1 offsets used for EVTQ_PROD/CONS, + PRIQ_PROD/CONS register access with page 0 offsets. + Set for Caviun ThunderX2 silicon that doesn't support + SMMU page1 register space. + ** Example smmu@2b40 { diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 380969a..5de258f 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -597,6 +597,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1) u32 options; struct arm_smmu_cmdqcmdq; @@ -663,9 +664,20 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium,cn9900-broken-page1-regspace"}, { 0, NULL}, }; +static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset, +struct arm_smmu_device *smmu) +{ + if ((offset > SZ_64K) && + (smmu->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY)) + offset -= SZ_64K; + + return smmu->base + offset; +} + static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); @@ -1961,8 +1973,8 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu, return -ENOMEM; } - q->prod_reg = smmu->base + prod_off; - q->cons_reg = smmu->base + cons_off; + q->prod_reg = arm_smmu_page1_fixup(prod_off, smmu); + q->cons_reg = arm_smmu_page1_fixup(cons_off, smmu); q->ent_dwords = dwords; q->q_base = Q_BASE_RWA; @@ -2363,8 +2375,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) /* Event queue */ writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE); - writel_relaxed(smmu->evtq.q.prod, smmu->base + ARM_SMMU_EVTQ_PROD); - writel_relaxed(smmu->evtq.q.cons, smmu->base + ARM_SMMU_EVTQ_CONS); + writel_relaxed(smmu->evtq.q.prod, + arm_smmu_page1_fixup(ARM_SMMU_EVTQ_PROD, smmu)); + writel_relaxed(smmu->evtq.q.cons, + arm_smmu_page1_fixup(ARM_SMMU_EVTQ_CONS, smmu)); enables |= CR0_EVTQEN; ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0, @@ -2379,9 +2393,9 @@ static int arm_s
[PATCH v8 1/3] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model
From: Linu Cherian Cavium ThunderX2 implementation doesn't support second page in SMMU register space. Hence, resource size is set as 64k for this model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/acpi/arm64/iort.c | 15 ++- 1 files changed, 14 insertions(+), 1 deletions(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf9..c166f3e 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -828,6 +828,18 @@ static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node) return num_res; } +static unsigned long arm_smmu_v3_resource_size(struct acpi_iort_smmu_v3 *smmu) +{ + /* +* Override the size, for Cavium ThunderX2 implementation +* which doesn't support the page 1 SMMU register space. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + return SZ_64K; + + return SZ_128K; +} + static void __init arm_smmu_v3_init_resources(struct resource *res, struct acpi_iort_node *node) { @@ -838,7 +850,8 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, smmu = (struct acpi_iort_smmu_v3 *)node->node_data; res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + + arm_smmu_v3_resource_size(smmu) - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; -- 1.7.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v7 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. This patch addresses the issue by checking if any interrupt sources are using same irq number, then they are registered as shared irqs. Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt |1 + drivers/iommu/arm-smmu-v3.c| 29 + 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 4693a32..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -63,6 +63,7 @@ stable kernels. | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | | Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 4e80205..d2db01f 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2232,6 +2232,25 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) devm_add_action(dev, arm_smmu_free_msis, dev); } +static int get_irq_flags(struct arm_smmu_device *smmu, int irq) +{ + int match_count = 0; + + if (irq == smmu->evtq.q.irq) + match_count++; + if (irq == smmu->cmdq.q.irq) + match_count++; + if (irq == smmu->gerr_irq) + match_count++; + if (irq == smmu->priq.q.irq) + match_count++; + + if (match_count > 1) + return IRQF_SHARED | IRQF_ONESHOT; + + return IRQF_ONESHOT; +} + static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) { int ret, irq; @@ -2252,7 +2271,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (irq) { ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_evtq_thread, - IRQF_ONESHOT, + get_irq_flags(smmu, irq), "arm-smmu-v3-evtq", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable evtq irq\n"); @@ -2261,7 +2280,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->cmdq.q.irq; if (irq) { ret = devm_request_irq(smmu->dev, irq, - arm_smmu_cmdq_sync_handler, 0, + arm_smmu_cmdq_sync_handler, + get_irq_flags(smmu, irq), "arm-smmu-v3-cmdq-sync", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n"); @@ -2270,7 +2290,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->gerr_irq; if (irq) { ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler, - 0, "arm-smmu-v3-gerror", smmu); + get_irq_flags(smmu, irq), + "arm-smmu-v3-gerror", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable gerror irq\n"); } @@ -2280,7 +2301,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (irq) { ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_priq_thread, - IRQF_ONESHOT, + get_irq_flags(smmu, irq), "arm-smmu-v3-priq", smmu); if (ret < 0) -- 1.7.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v7 2/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74
From: Linu Cherian Cavium ThunderX2 SMMU implementation doesn't support page 1 register space and PAGE0_REGS_ONLY option is enabled as an errata workaround. This option when turned on, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. SMMU resource size checks are now based on SMMU option PAGE0_REGS_ONLY, since resource size can be either 64k/128k. For this, arm_smmu_device_dt_probe/acpi_probe has been moved before platform_get_resource call, so that SMMU options are set beforehand. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt |1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |6 ++ drivers/iommu/arm-smmu-v3.c| 64 +++- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 10f2ddd..4693a32 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,7 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index be57550..607e270 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -49,6 +49,12 @@ the PCIe specification. - hisilicon,broken-prefetch-cmd : Avoid sending CMD_PREFETCH_* commands to the SMMU. +- cavium,cn9900-broken-page1-regspace +: Replaces all page 1 offsets used for EVTQ_PROD/CONS, + PRIQ_PROD/CONS register access with page 0 offsets. + Set for Caviun ThunderX2 silicon that doesn't support + SMMU page1 register space. + ** Example smmu@2b40 { diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 380969a..4e80205 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -412,6 +412,9 @@ #define MSI_IOVA_BASE 0x800 #define MSI_IOVA_LENGTH0x10 +#define ARM_SMMU_PAGE0_REGS_ONLY(smmu) \ + ((smmu)->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY) + static bool disable_bypass; module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, @@ -597,6 +600,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY(1 << 1) u32 options; struct arm_smmu_cmdqcmdq; @@ -663,9 +667,19 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium,cn9900-broken-page1-regspace"}, { 0, NULL}, }; +static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset, +struct arm_smmu_device *smmu) +{ + if (offset > SZ_64K && ARM_SMMU_PAGE0_REGS_ONLY(smmu)) + offset -= SZ_64K; + + return smmu->base + offset; +} + static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); @@ -1961,8 +1975,8 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu, return -ENOMEM; } - q->prod_reg = smmu->base + prod_off; - q->cons_reg = smmu->base + cons_off; + q->prod_reg = arm_smmu_page1_fixup(prod_off, smmu); + q->cons_reg = arm_smmu_page1_fixup(cons_off, smmu); q->ent_dwords = dwords; q->q_base = Q_BASE_RWA; @@ -2363,8 +2377,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) /* Event queue */ writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE); - writel_relaxed(smmu->evtq.q.prod, smmu->base + ARM_SMMU_EVTQ_PROD); - writel_re
[PATCH v7 1/3] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model
From: Linu Cherian Cavium ThunderX2 implementation doesn't support second page in SMMU register space. Hence, resource size is set as 64k for this model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/acpi/arm64/iort.c | 10 +- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf9..bba2b59 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -833,12 +833,20 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, { struct acpi_iort_smmu_v3 *smmu; int num_res = 0; + unsigned long size = SZ_128K; /* Retrieve SMMUv3 specific data */ smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* +* Override the size, for Cavium ThunderX2 implementation +* which doesn't support the page 1 SMMU register space. +*/ + if (smmu->model == ACPI_IORT_SMMU_CAVIUM_CN99XX) + size = SZ_64K; + res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + size - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; -- 1.7.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v7 0/3] Cavium ThunderX2 SMMUv3 errata workarounds
Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines and also MSI for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on patchset. https://www.spinics.net/lists/arm-kernel/msg578443.html Changes since v6: - Changed device tree compatible string to vendor specific. - Rebased on Robin's latest "Update SMMU models for IORT rev. C" v2 patch. https://www.spinics.net/lists/arm-kernel/msg582809.html Changes since v5: - Rebased on Robin's "Update SMMU models for IORT rev. C" patch. https://www.spinics.net/lists/arm-kernel/msg580728.html - Replaced ACPI_IORT_SMMU_V3_CAVIUM_CN99XX macro with ACPI_IORT_SMMU_CAVIUM_CN99XX Changes since v4: - Replaced all page1 offset macros ARM_SMMU_EVTQ/PRIQ_PROD/CONS with arm_smmu_page1_fixup(ARM_SMMU_EVTQ/PRIQ_PROD/CONS, smmu) Changes since v3: - Merged patches 1, 2 and 4 of Version 3. - Modified the page1_offset_adjust() and get_irq_flags() implementation as suggested by Robin. Changes since v2: - Updated "Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt" document with new SMMU option used to enable errata workaround. Changes since v1: - Since the use of MIDR register is rejected and SMMU_IIDR is broken on this silicon, as suggested by Will Deacon modified the patches to use ThunderX2 SMMUv3 IORT model number to enable errata workaround. Geetha Sowjanya (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Linu Cherian (2): ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74 Documentation/arm64/silicon-errata.txt |2 + .../devicetree/bindings/iommu/arm,smmu-v3.txt |6 ++ drivers/acpi/arm64/iort.c | 10 ++- drivers/iommu/arm-smmu-v3.c| 93 4 files changed, 91 insertions(+), 20 deletions(-) ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v6 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. This patch addresses the issue by checking if any interrupt sources are using same irq number, then they are registered as shared irqs. Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt | 1 + drivers/iommu/arm-smmu-v3.c| 29 + 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 4693a32..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -63,6 +63,7 @@ stable kernels. | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | | Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index c519927c..69d8506 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2232,6 +2232,25 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) devm_add_action(dev, arm_smmu_free_msis, dev); } +static int get_irq_flags(struct arm_smmu_device *smmu, int irq) +{ + int match_count = 0; + + if (irq == smmu->evtq.q.irq) + match_count++; + if (irq == smmu->cmdq.q.irq) + match_count++; + if (irq == smmu->gerr_irq) + match_count++; + if (irq == smmu->priq.q.irq) + match_count++; + + if (match_count > 1) + return IRQF_SHARED | IRQF_ONESHOT; + + return IRQF_ONESHOT; +} + static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) { int ret, irq; @@ -2252,7 +2271,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (irq) { ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_evtq_thread, - IRQF_ONESHOT, + get_irq_flags(smmu, irq), "arm-smmu-v3-evtq", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable evtq irq\n"); @@ -2261,7 +2280,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->cmdq.q.irq; if (irq) { ret = devm_request_irq(smmu->dev, irq, - arm_smmu_cmdq_sync_handler, 0, + arm_smmu_cmdq_sync_handler, + get_irq_flags(smmu, irq), "arm-smmu-v3-cmdq-sync", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n"); @@ -2270,7 +2290,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->gerr_irq; if (irq) { ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler, - 0, "arm-smmu-v3-gerror", smmu); + get_irq_flags(smmu, irq), + "arm-smmu-v3-gerror", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable gerror irq\n"); } @@ -2280,7 +2301,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (irq) { ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_priq_thread, - IRQF_ONESHOT, + get_irq_flags(smmu, irq), "arm-smmu-v3-priq", smmu); if (ret < 0) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v6 1/3] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model
From: Linu Cherian Cavium ThunderX2 implementation doesn't support second page in SMMU register space. Hence, resource size is set as 64k for this model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/acpi/arm64/iort.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf9..bba2b59 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -833,12 +833,20 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, { struct acpi_iort_smmu_v3 *smmu; int num_res = 0; + unsigned long size = SZ_128K; /* Retrieve SMMUv3 specific data */ smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* +* Override the size, for Cavium ThunderX2 implementation +* which doesn't support the page 1 SMMU register space. +*/ + if (smmu->model == ACPI_IORT_SMMU_CAVIUM_CN99XX) + size = SZ_64K; + res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + size - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v6 2/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74
From: Linu Cherian Cavium ThunderX2 SMMU implementation doesn't support page 1 register space and PAGE0_REGS_ONLY option is enabled as an errata workaround. This option when turned on, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. SMMU resource size checks are now based on SMMU option PAGE0_REGS_ONLY, since resource size can be either 64k/128k. For this, arm_smmu_device_dt_probe/acpi_probe has been moved before platform_get_resource call, so that SMMU options are set beforehand. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt | 1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 ++ drivers/iommu/arm-smmu-v3.c| 64 +- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 10f2ddd..4693a32 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,7 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index be57550..e6da62b 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -49,6 +49,12 @@ the PCIe specification. - hisilicon,broken-prefetch-cmd : Avoid sending CMD_PREFETCH_* commands to the SMMU. +- cavium-cn99xx,broken-page1-regspace +: Replaces all page 1 offsets used for EVTQ_PROD/CONS, + PRIQ_PROD/CONS register access with page 0 offsets. + Set for Caviun ThunderX2 silicon that doesn't support + SMMU page1 register space. + ** Example smmu@2b40 { diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 380969a..c519927c 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -412,6 +412,9 @@ #define MSI_IOVA_BASE 0x800 #define MSI_IOVA_LENGTH0x10 +#define ARM_SMMU_PAGE0_REGS_ONLY(smmu) \ + ((smmu)->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY) + static bool disable_bypass; module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, @@ -597,6 +600,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY(1 << 1) u32 options; struct arm_smmu_cmdqcmdq; @@ -663,9 +667,19 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium-cn99xx,broken-page1-regspace"}, { 0, NULL}, }; +static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset, +struct arm_smmu_device *smmu) +{ + if (offset > SZ_64K && ARM_SMMU_PAGE0_REGS_ONLY(smmu)) + offset -= SZ_64K; + + return smmu->base + offset; +} + static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); @@ -1961,8 +1975,8 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu, return -ENOMEM; } - q->prod_reg = smmu->base + prod_off; - q->cons_reg = smmu->base + cons_off; + q->prod_reg = arm_smmu_page1_fixup(prod_off, smmu); + q->cons_reg = arm_smmu_page1_fixup(cons_off, smmu); q->ent_dwords = dwords; q->q_base = Q_BASE_RWA; @@ -2363,8 +2377,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) /* Event queue */ writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE); - writel_relaxed(smmu->evtq.q.prod, smmu->base + ARM_SMMU_EVTQ_PROD); - writel_re
[v6 0/3] Cavium ThunderX2 SMMUv3 errata workarounds
From: Linu Cherian Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines and also MSI for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on patchset. https://www.spinics.net/lists/arm-kernel/msg578443.html Changes since v5: - Rebased on Robin's "Update SMMU models for IORT rev. C" patch. https://www.spinics.net/lists/arm-kernel/msg580728.html - Replaced ACPI_IORT_SMMU_V3_CAVIUM_CN99XX macro with ACPI_IORT_SMMU_CAVIUM_CN99XX Changes since v4: - Replaced all page1 offset macros ARM_SMMU_EVTQ/PRIQ_PROD/CONS with arm_smmu_page1_fixup(ARM_SMMU_EVTQ/PRIQ_PROD/CONS, smmu) Changes since v3: - Merged patches 1, 2 and 4 of Version 3. - Modified the page1_offset_adjust() and get_irq_flags() implementation as suggested by Robin. Changes since v2: - Updated "Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt" document with new SMMU option used to enable errata workaround. Changes since v1: - Since the use of MIDR register is rejected and SMMU_IIDR is broken on this silicon, as suggested by Will Deacon modified the patches to use ThunderX2 SMMUv3 IORT model number to enable errata workaround. Geetha Sowjanya (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Linu Cherian (2): ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74 Documentation/arm64/silicon-errata.txt | 2 + .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 ++ drivers/acpi/arm64/iort.c | 10 ++- drivers/iommu/arm-smmu-v3.c| 93 +- 4 files changed, 91 insertions(+), 20 deletions(-) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v5 3/4] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74
From: Linu Cherian Cavium ThunderX2 SMMU implementation doesn't support page 1 register space and PAGE0_REGS_ONLY option is enabled as an errata workaround. This option when turned on, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. SMMU resource size checks are now based on SMMU option PAGE0_REGS_ONLY, since resource size can be either 64k/128k. For this, arm_smmu_device_dt_probe/acpi_probe has been moved before platform_get_resource call, so that SMMU options are set beforehand. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt | 1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 ++ drivers/iommu/arm-smmu-v3.c| 64 +- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 10f2ddd..4693a32 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,7 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index be57550..e6da62b 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -49,6 +49,12 @@ the PCIe specification. - hisilicon,broken-prefetch-cmd : Avoid sending CMD_PREFETCH_* commands to the SMMU. +- cavium-cn99xx,broken-page1-regspace +: Replaces all page 1 offsets used for EVTQ_PROD/CONS, + PRIQ_PROD/CONS register access with page 0 offsets. + Set for Caviun ThunderX2 silicon that doesn't support + SMMU page1 register space. + ** Example smmu@2b40 { diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 380969a..5836b72 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -412,6 +412,9 @@ #define MSI_IOVA_BASE 0x800 #define MSI_IOVA_LENGTH0x10 +#define ARM_SMMU_PAGE0_REGS_ONLY(smmu) \ + ((smmu)->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY) + static bool disable_bypass; module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, @@ -597,6 +600,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY(1 << 1) u32 options; struct arm_smmu_cmdqcmdq; @@ -663,9 +667,19 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium-cn99xx,broken-page1-regspace"}, { 0, NULL}, }; +static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset, +struct arm_smmu_device *smmu) +{ + if (offset > SZ_64K && ARM_SMMU_PAGE0_REGS_ONLY(smmu)) + offset -= SZ_64K; + + return smmu->base + offset; +} + static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); @@ -1961,8 +1975,8 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu, return -ENOMEM; } - q->prod_reg = smmu->base + prod_off; - q->cons_reg = smmu->base + cons_off; + q->prod_reg = arm_smmu_page1_fixup(prod_off, smmu); + q->cons_reg = arm_smmu_page1_fixup(cons_off, smmu); q->ent_dwords = dwords; q->q_base = Q_BASE_RWA; @@ -2363,8 +2377,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) /* Event queue */ writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE); - writel_relaxed(smmu->evtq.q.prod, smmu->base + ARM_SMMU_EVTQ_PROD); - writel_re
[v5 4/4] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. This patch addresses the issue by checking if any interrupt sources are using same irq number, then they are registered as shared irqs. Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt | 1 + drivers/iommu/arm-smmu-v3.c| 29 + 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 4693a32..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -63,6 +63,7 @@ stable kernels. | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | | Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 5836b72..6ae5d3b 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2232,6 +2232,25 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) devm_add_action(dev, arm_smmu_free_msis, dev); } +static int get_irq_flags(struct arm_smmu_device *smmu, int irq) +{ + int match_count = 0; + + if (irq == smmu->evtq.q.irq) + match_count++; + if (irq == smmu->cmdq.q.irq) + match_count++; + if (irq == smmu->gerr_irq) + match_count++; + if (irq == smmu->priq.q.irq) + match_count++; + + if (match_count > 1) + return IRQF_SHARED | IRQF_ONESHOT; + + return IRQF_ONESHOT; +} + static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) { int ret, irq; @@ -2252,7 +2271,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (irq) { ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_evtq_thread, - IRQF_ONESHOT, + get_irq_flags(smmu, irq), "arm-smmu-v3-evtq", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable evtq irq\n"); @@ -2261,7 +2280,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->cmdq.q.irq; if (irq) { ret = devm_request_irq(smmu->dev, irq, - arm_smmu_cmdq_sync_handler, 0, + arm_smmu_cmdq_sync_handler, + get_irq_flags(smmu, irq), "arm-smmu-v3-cmdq-sync", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n"); @@ -2270,7 +2290,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->gerr_irq; if (irq) { ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler, - 0, "arm-smmu-v3-gerror", smmu); + get_irq_flags(smmu, irq), + "arm-smmu-v3-gerror", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable gerror irq\n"); } @@ -2280,7 +2301,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (irq) { ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_priq_thread, - IRQF_ONESHOT, + get_irq_flags(smmu, irq), "arm-smmu-v3-priq", smmu); if (ret < 0) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v5 2/4] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model
From: Linu Cherian Cavium ThunderX2 implementation doesn't support second page in SMMU register space. Hence, resource size is set as 64k for this model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/acpi/arm64/iort.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf9..23c5350 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -833,12 +833,20 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, { struct acpi_iort_smmu_v3 *smmu; int num_res = 0; + unsigned long size = SZ_128K; /* Retrieve SMMUv3 specific data */ smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* +* Override the size, for Cavium ThunderX2 implementation +* which doesn't support the page 1 SMMU register space. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + size = SZ_64K; + res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + size - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v5 0/4] Cavium ThunderX2 SMMUv3 errata workarounds
From: Linu Cherian Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines and also MSI for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on patchset. https://www.spinics.net/lists/arm-kernel/msg578443.html Changes since v4: - Replaced all page1 offset macros ARM_SMMU_EVTQ/PRIQ_PROD/CONS with arm_smmu_page1_fixup(ARM_SMMU_EVTQ/PRIQ_PROD/CONS, smmu) Changes since v3: - Merged patches 1, 2 and 4 of Version 3. - Modified the page1_offset_adjust() and get_irq_flags() implementation as suggested by Robin. Changes since v2: - Updated "Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt" document with new SMMU option used to enable errata workaround. Changes since v1: - Since the use of MIDR register is rejected and SMMU_IIDR is broken on this silicon, as suggested by Will Deacon modified the patches to use ThunderX2 SMMUv3 IORT model number to enable errata workaround. Geetha Sowjanya (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Linu Cherian (3): ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition. ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74 Documentation/arm64/silicon-errata.txt | 2 + .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 ++ drivers/acpi/arm64/iort.c | 10 ++- drivers/iommu/arm-smmu-v3.c| 93 +- include/acpi/actbl2.h | 2 + 5 files changed, 93 insertions(+), 20 deletions(-) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v5 1/4] ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition.
From: Linu Cherian Add SMMUv3 model definition for ThunderX2. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- include/acpi/actbl2.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index faa9f2c..76a6f5d 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -779,6 +779,8 @@ struct acpi_iort_smmu { #define ACPI_IORT_SMMU_CORELINK_MMU400 0x0002 /* ARM Corelink MMU-400 */ #define ACPI_IORT_SMMU_CORELINK_MMU500 0x0003 /* ARM Corelink MMU-500 */ +#define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX 0x0002 /* Cavium ThunderX2 SMMUv3 */ + /* Masks for Flags field above */ #define ACPI_IORT_SMMU_DVM_SUPPORTED(1) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v4 4/4] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. This patch addresses the issue by checking if any interrupt sources are using same irq number, then they are registered as shared irqs. Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt | 1 + drivers/iommu/arm-smmu-v3.c| 29 + 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 4693a32..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -63,6 +63,7 @@ stable kernels. | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | | Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 1e986a0..a1c09f4 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2236,6 +2236,25 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) devm_add_action(dev, arm_smmu_free_msis, dev); } +static int get_irq_flags(struct arm_smmu_device *smmu, int irq) +{ + int match_count = 0; + + if (irq == smmu->evtq.q.irq) + match_count++; + if (irq == smmu->cmdq.q.irq) + match_count++; + if (irq == smmu->gerr_irq) + match_count++; + if (irq == smmu->priq.q.irq) + match_count++; + + if (match_count > 1) + return IRQF_SHARED | IRQF_ONESHOT; + + return IRQF_ONESHOT; +} + static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) { int ret, irq; @@ -2256,7 +2275,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (irq) { ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_evtq_thread, - IRQF_ONESHOT, + get_irq_flags(smmu, irq), "arm-smmu-v3-evtq", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable evtq irq\n"); @@ -2265,7 +2284,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->cmdq.q.irq; if (irq) { ret = devm_request_irq(smmu->dev, irq, - arm_smmu_cmdq_sync_handler, 0, + arm_smmu_cmdq_sync_handler, + get_irq_flags(smmu, irq), "arm-smmu-v3-cmdq-sync", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n"); @@ -2274,7 +2294,8 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->gerr_irq; if (irq) { ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler, - 0, "arm-smmu-v3-gerror", smmu); + get_irq_flags(smmu, irq), + "arm-smmu-v3-gerror", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable gerror irq\n"); } @@ -2284,7 +2305,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (irq) { ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_priq_thread, - IRQF_ONESHOT, + get_irq_flags(smmu, irq), "arm-smmu-v3-priq", smmu); if (ret < 0) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v4 3/4] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74
From: Linu Cherian Cavium ThunderX2 SMMU implementation doesn't support page 1 register space and PAGE0_REGS_ONLY option is enabled as an errata workaround. This option when turned on, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. SMMU resource size checks are now based on SMMU option PAGE0_REGS_ONLY, since resource size can be either 64k/128k. For this, arm_smmu_device_dt_probe/acpi_probe has been moved before platform_get_resource call, so that SMMU options are set beforehand. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt | 1 + .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 ++ drivers/iommu/arm-smmu-v3.c| 80 -- 3 files changed, 66 insertions(+), 21 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 10f2ddd..4693a32 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,7 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index be57550..e6da62b 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -49,6 +49,12 @@ the PCIe specification. - hisilicon,broken-prefetch-cmd : Avoid sending CMD_PREFETCH_* commands to the SMMU. +- cavium-cn99xx,broken-page1-regspace +: Replaces all page 1 offsets used for EVTQ_PROD/CONS, + PRIQ_PROD/CONS register access with page 0 offsets. + Set for Caviun ThunderX2 silicon that doesn't support + SMMU page1 register space. + ** Example smmu@2b40 { diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 380969a..1e986a0 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -176,15 +176,15 @@ #define ARM_SMMU_CMDQ_CONS 0x9c #define ARM_SMMU_EVTQ_BASE 0xa0 -#define ARM_SMMU_EVTQ_PROD 0x100a8 -#define ARM_SMMU_EVTQ_CONS 0x100ac +#define ARM_SMMU_EVTQ_PROD(smmu) (page1_offset_adjust(0x100a8, smmu)) +#define ARM_SMMU_EVTQ_CONS(smmu) (page1_offset_adjust(0x100ac, smmu)) #define ARM_SMMU_EVTQ_IRQ_CFG0 0xb0 #define ARM_SMMU_EVTQ_IRQ_CFG1 0xb8 #define ARM_SMMU_EVTQ_IRQ_CFG2 0xbc #define ARM_SMMU_PRIQ_BASE 0xc0 -#define ARM_SMMU_PRIQ_PROD 0x100c8 -#define ARM_SMMU_PRIQ_CONS 0x100cc +#define ARM_SMMU_PRIQ_PROD(smmu) (page1_offset_adjust(0x100c8, smmu)) +#define ARM_SMMU_PRIQ_CONS(smmu) (page1_offset_adjust(0x100cc, smmu)) #define ARM_SMMU_PRIQ_IRQ_CFG0 0xd0 #define ARM_SMMU_PRIQ_IRQ_CFG1 0xd8 #define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc @@ -412,6 +412,9 @@ #define MSI_IOVA_BASE 0x800 #define MSI_IOVA_LENGTH0x10 +#define ARM_SMMU_PAGE0_REGS_ONLY(smmu) \ + ((smmu)->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY) + static bool disable_bypass; module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, @@ -597,6 +600,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY(1 << 1) u32 options; struct arm_smmu_cmdqcmdq; @@ -663,9 +667,19 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium-cn99xx,broken-page1-regspace"}, { 0, NULL}, }; +static inline unsigned long page1_offset_adjust( + unsigned long off, struct arm_smmu_device *smmu) +{ + if (off > SZ_64K && ARM_SMMU_PAGE0_REGS_ONLY(smmu)) + return (off - SZ_64K); + + return off; +} + static struct arm_smmu_domain *to_smmu_domain(struct i
[v4 2/4] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model
From: Linu Cherian Cavium ThunderX2 implementation doesn't support second page in SMMU register space. Hence, resource size is set as 64k for this model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/acpi/arm64/iort.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf9..23c5350 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -833,12 +833,20 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, { struct acpi_iort_smmu_v3 *smmu; int num_res = 0; + unsigned long size = SZ_128K; /* Retrieve SMMUv3 specific data */ smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* +* Override the size, for Cavium ThunderX2 implementation +* which doesn't support the page 1 SMMU register space. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + size = SZ_64K; + res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + size - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v4 1/4] ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition.
From: Linu Cherian Add SMMUv3 model definition for ThunderX2. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- include/acpi/actbl2.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index faa9f2c..76a6f5d 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -779,6 +779,8 @@ struct acpi_iort_smmu { #define ACPI_IORT_SMMU_CORELINK_MMU400 0x0002 /* ARM Corelink MMU-400 */ #define ACPI_IORT_SMMU_CORELINK_MMU500 0x0003 /* ARM Corelink MMU-500 */ +#define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX 0x0002 /* Cavium ThunderX2 SMMUv3 */ + /* Masks for Flags field above */ #define ACPI_IORT_SMMU_DVM_SUPPORTED(1) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[v4 0/4] Cavium ThunderX2 SMMUv3 errata workarounds
From: Linu Cherian Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines and also MSI for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on patchset. https://www.spinics.net/lists/arm-kernel/msg578443.html Changes from v3: - Merged patches 1, 2 and 4 of Version 3. - Modified the page1_offset_adjust() and get_irq_flags() implementation as suggested by Robin. Changes from v2: Updated "Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt" document with new SMMU option used to enable errata workaround. Changes from v1: Since the use of MIDR register is rejected and SMMU_IIDR is broken on this silicon, as suggested by Will Deacon modified the patches to use ThunderX2 SMMUv3 IORT model number to enable errata workaround. Geetha Sowjanya (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Linu Cherian (3): ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition. ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74 Documentation/arm64/silicon-errata.txt | 2 + .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 ++ drivers/acpi/arm64/iort.c | 10 +- drivers/iommu/arm-smmu-v3.c| 109 - include/acpi/actbl2.h | 2 + 5 files changed, 103 insertions(+), 26 deletions(-) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 7/7] arm64: Documentation: Add Cavium ThunderX2 SMMUv3 erratas
From: Linu Cherian Add Cavium ThunderX2 SMMUv3 erratas to the errata list. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 10f2ddd..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,8 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 6/7] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. This patch addresses the issue by checking if any interrupt sources are using same irq number, then they are registered as shared irqs. Signed-off-by: Geetha Sowjanya --- drivers/iommu/arm-smmu-v3.c | 32 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 016b702..46428e7 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2236,10 +2236,30 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) devm_add_action(dev, arm_smmu_free_msis, dev); } +static int get_irq_flags(struct arm_smmu_device *smmu, int irq) +{ + int match_count = 0; + + if (irq == smmu->evtq.q.irq) + match_count++; + if (irq == smmu->cmdq.q.irq) + match_count++; + if (irq == smmu->gerr_irq) + match_count++; + if (irq == smmu->priq.q.irq) + match_count++; + + if (match_count > 1) + return IRQF_SHARED | IRQF_ONESHOT; + + return 0; +} + static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) { int ret, irq; u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN; + u32 irqflags = 0; /* Disable IRQs first */ ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL, @@ -2254,9 +2274,10 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) /* Request interrupt lines */ irq = smmu->evtq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_evtq_thread, - IRQF_ONESHOT, + IRQF_ONESHOT | irqflags, "arm-smmu-v3-evtq", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable evtq irq\n"); @@ -2264,8 +2285,9 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->cmdq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_irq(smmu->dev, irq, - arm_smmu_cmdq_sync_handler, 0, + arm_smmu_cmdq_sync_handler, irqflags, "arm-smmu-v3-cmdq-sync", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n"); @@ -2273,8 +2295,9 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->gerr_irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler, - 0, "arm-smmu-v3-gerror", smmu); + irqflags, "arm-smmu-v3-gerror", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable gerror irq\n"); } @@ -2282,9 +2305,10 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (smmu->features & ARM_SMMU_FEAT_PRI) { irq = smmu->priq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_priq_thread, - IRQF_ONESHOT, + IRQF_ONESHOT | irqflags, "arm-smmu-v3-priq", smmu); if (ret < 0) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 5/7] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model
From: Linu Cherian Cavium ThunderX2 implementation doesn't support second page in SMMU register space. Hence, resource size is set as 64k for this model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/acpi/arm64/iort.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf9..23c5350 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -833,12 +833,20 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, { struct acpi_iort_smmu_v3 *smmu; int num_res = 0; + unsigned long size = SZ_128K; /* Retrieve SMMUv3 specific data */ smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* +* Override the size, for Cavium ThunderX2 implementation +* which doesn't support the page 1 SMMU register space. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + size = SZ_64K; + res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + size - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 4/7] iommu/arm-smmu-v3: For ACPI based device probing, set PAGE0_REGS_ONLY option for ThunderX2 SMMUv3 implementation.
From: Linu Cherian Enable PAGE0_REGS_ONLY option for Cavium ThunderX2 SMMUv3 model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/iommu/arm-smmu-v3.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index f027676..8f7d8ad 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2625,6 +2625,14 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) } #ifdef CONFIG_ACPI +static void acpi_smmu_get_options(u32 model, struct arm_smmu_device *smmu) +{ + if (model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + smmu->options |= ARM_SMMU_OPT_PAGE0_REGS_ONLY; + + dev_notice(smmu->dev, "option mask 0x%x\n", smmu->options); +} + static int arm_smmu_device_acpi_probe(struct platform_device *pdev, struct arm_smmu_device *smmu) { @@ -2637,6 +2645,8 @@ static int arm_smmu_device_acpi_probe(struct platform_device *pdev, /* Retrieve SMMUv3 specific data */ iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + acpi_smmu_get_options(iort_smmu->model, smmu); + if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE) smmu->features |= ARM_SMMU_FEAT_COHERENCY; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 2/7] iommu/arm-smmu-v3: Do resource size checks based on SMMU
From: Linu Cherian With implementations supporting only page 0 register space, resource size can be 64k as well and hence perform size checks based on SMMU option PAGE0_REGS_ONLY. For this, arm_smmu_device_dt_probe/acpi_probe has been moved before platform_get_resource call, so that SMMU options are set beforehand. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/iommu/arm-smmu-v3.c | 26 +- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 107b4a6..f027676 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2672,6 +2672,14 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev, return ret; } +static unsigned long arm_smmu_resource_size(struct arm_smmu_device *smmu) +{ + if (ARM_SMMU_PAGE0_REGS_ONLY(smmu)) + return SZ_64K; + else + return SZ_128K; +} + static int arm_smmu_device_probe(struct platform_device *pdev) { int irq, ret; @@ -2688,9 +2696,17 @@ static int arm_smmu_device_probe(struct platform_device *pdev) } smmu->dev = dev; + if (dev->of_node) { + ret = arm_smmu_device_dt_probe(pdev, smmu); + } else { + ret = arm_smmu_device_acpi_probe(pdev, smmu); + if (ret == -ENODEV) + return ret; + } + /* Base address */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (resource_size(res) + 1 < SZ_128K) { + if (resource_size(res) + 1 < arm_smmu_resource_size(smmu)) { dev_err(dev, "MMIO region too small (%pr)\n", res); return -EINVAL; } @@ -2717,14 +2733,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev) if (irq > 0) smmu->gerr_irq = irq; - if (dev->of_node) { - ret = arm_smmu_device_dt_probe(pdev, smmu); - } else { - ret = arm_smmu_device_acpi_probe(pdev, smmu); - if (ret == -ENODEV) - return ret; - } - /* Set bypass mode according to firmware probing result */ bypass = !!ret; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 3/7] ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition.
From: Linu Cherian Add SMMUv3 model definition for ThunderX2. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- include/acpi/actbl2.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index faa9f2c..76a6f5d 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -779,6 +779,8 @@ struct acpi_iort_smmu { #define ACPI_IORT_SMMU_CORELINK_MMU400 0x0002 /* ARM Corelink MMU-400 */ #define ACPI_IORT_SMMU_CORELINK_MMU500 0x0003 /* ARM Corelink MMU-500 */ +#define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX 0x0002 /* Cavium ThunderX2 SMMUv3 */ + /* Masks for Flags field above */ #define ACPI_IORT_SMMU_DVM_SUPPORTED(1) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 0/7] Cavium ThunderX2 SMMUv3 errata workarounds
From: Linu Cherian Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines and also MSI for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on patchset. https://www.spinics.net/lists/arm-kernel/msg578443.html Changes from v1: Since the use of MIDR register is rejected and SMMU_IIDR is broken on this silicon, as suggested by Will Deacon modified the patches to use ThunderX2 SMMUv3 IORT model number to enable errata workaround. Changes from v2: Updated "Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt" document with new SMMU option used to enable errata workaround. Geetha Sowjanya (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Linu Cherian (6): iommu/arm-smmu-v3: Introduce smmu option PAGE0_REGS_ONLY for ThunderX2 errata#74. iommu/arm-smmu-v3: Do resource size checks based on SMMU option PAGE0_REGS_ONLY ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition. iommu/arm-smmu-v3: For ACPI based device probing, set PAGE0_REGS_ONLY option for ThunderX2 SMMUv3 implementations. ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model arm64: Documentation: Add Cavium ThunderX2 SMMUv3 erratas Documentation/arm64/silicon-errata.txt | 2 + drivers/acpi/arm64/iort.c | 10 ++- drivers/iommu/arm-smmu-v3.c| 122 ++--- include/acpi/actbl2.h | 2 + 4 files changed, 110 insertions(+), 26 deletions(-) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3 1/7] iommu/arm-smmu-v3: Introduce SMMU option PAGE0_REGS_ONLY for ThunderX2 errata #74
From: Linu Cherian Cavium ThunderX2 SMMU implementation doesn't support page 1 register space and PAGE0_REGS_ONLY option will be enabled as an errata workaround. This option when turned on, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- .../devicetree/bindings/iommu/arm,smmu-v3.txt | 6 +++ drivers/iommu/arm-smmu-v3.c| 44 -- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt index be57550..e6da62b 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu-v3.txt @@ -49,6 +49,12 @@ the PCIe specification. - hisilicon,broken-prefetch-cmd : Avoid sending CMD_PREFETCH_* commands to the SMMU. +- cavium-cn99xx,broken-page1-regspace +: Replaces all page 1 offsets used for EVTQ_PROD/CONS, + PRIQ_PROD/CONS register access with page 0 offsets. + Set for Caviun ThunderX2 silicon that doesn't support + SMMU page1 register space. + ** Example smmu@2b40 { diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 380969a..107b4a6 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -176,15 +176,15 @@ #define ARM_SMMU_CMDQ_CONS 0x9c #define ARM_SMMU_EVTQ_BASE 0xa0 -#define ARM_SMMU_EVTQ_PROD 0x100a8 -#define ARM_SMMU_EVTQ_CONS 0x100ac +#define ARM_SMMU_EVTQ_PROD(smmu) (page1_offset_adjust(0x100a8, smmu)) +#define ARM_SMMU_EVTQ_CONS(smmu) (page1_offset_adjust(0x100ac, smmu)) #define ARM_SMMU_EVTQ_IRQ_CFG0 0xb0 #define ARM_SMMU_EVTQ_IRQ_CFG1 0xb8 #define ARM_SMMU_EVTQ_IRQ_CFG2 0xbc #define ARM_SMMU_PRIQ_BASE 0xc0 -#define ARM_SMMU_PRIQ_PROD 0x100c8 -#define ARM_SMMU_PRIQ_CONS 0x100cc +#define ARM_SMMU_PRIQ_PROD(smmu) (page1_offset_adjust(0x100c8, smmu)) +#define ARM_SMMU_PRIQ_CONS(smmu) (page1_offset_adjust(0x100cc, smmu)) #define ARM_SMMU_PRIQ_IRQ_CFG0 0xd0 #define ARM_SMMU_PRIQ_IRQ_CFG1 0xd8 #define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc @@ -412,6 +412,9 @@ #define MSI_IOVA_BASE 0x800 #define MSI_IOVA_LENGTH0x10 +#define ARM_SMMU_PAGE0_REGS_ONLY(smmu) \ + ((smmu)->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY) + static bool disable_bypass; module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, @@ -597,6 +600,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY(1 << 1) u32 options; struct arm_smmu_cmdqcmdq; @@ -663,9 +667,19 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium-cn99xx,broken-page1-regspace"}, { 0, NULL}, }; +static inline unsigned long page1_offset_adjust( + unsigned long off, struct arm_smmu_device *smmu) +{ + if (!ARM_SMMU_PAGE0_REGS_ONLY(smmu)) + return off; + else + return (off - SZ_64K); +} + static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); @@ -1986,8 +2000,10 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu) return ret; /* evtq */ - ret = arm_smmu_init_one_queue(smmu, &smmu->evtq.q, ARM_SMMU_EVTQ_PROD, - ARM_SMMU_EVTQ_CONS, EVTQ_ENT_DWORDS); + ret = arm_smmu_init_one_queue(smmu, &smmu->evtq.q, + ARM_SMMU_EVTQ_PROD(smmu), + ARM_SMMU_EVTQ_CONS(smmu), + EVTQ_ENT_DWORDS); if (ret) return ret; @@ -1995,8 +2011,10 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu) if (!(smmu->features & ARM_SMMU_FEAT_PRI)) return 0; - return arm_smmu_init_one_queue(smmu, &smmu->priq.q, ARM_SMMU_PRIQ_PROD, - ARM_SMMU_PRIQ_CONS, PRIQ_ENT_DWORDS); + return arm_smmu_init_one_queue(smmu, &smmu->priq.q, + ARM_
[PATCH v2 4/7] iommu/arm-smmu-v3: For ACPI based device probing, set PAGE0_REGS_ONLY option for ThunderX2 SMMUv3 implementation.
From: Linu Cherian Enable PAGE0_REGS_ONLY option for Cavium ThunderX2 SMMUv3 model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/iommu/arm-smmu-v3.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index f027676..8f7d8ad 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2625,6 +2625,14 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) } #ifdef CONFIG_ACPI +static void acpi_smmu_get_options(u32 model, struct arm_smmu_device *smmu) +{ + if (model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + smmu->options |= ARM_SMMU_OPT_PAGE0_REGS_ONLY; + + dev_notice(smmu->dev, "option mask 0x%x\n", smmu->options); +} + static int arm_smmu_device_acpi_probe(struct platform_device *pdev, struct arm_smmu_device *smmu) { @@ -2637,6 +2645,8 @@ static int arm_smmu_device_acpi_probe(struct platform_device *pdev, /* Retrieve SMMUv3 specific data */ iort_smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + acpi_smmu_get_options(iort_smmu->model, smmu); + if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE) smmu->features |= ARM_SMMU_FEAT_COHERENCY; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 7/7] arm64: Documentation: Add Cavium ThunderX2 SMMUv3 erratas
From: Linu Cherian Add Cavium ThunderX2 SMMUv3 erratas to the errata list. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- Documentation/arm64/silicon-errata.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 10f2ddd..42422f6 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,8 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 3/7] ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition.
From: Linu Cherian Add SMMUv3 model definition for ThunderX2. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- include/acpi/actbl2.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index faa9f2c..76a6f5d 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -779,6 +779,8 @@ struct acpi_iort_smmu { #define ACPI_IORT_SMMU_CORELINK_MMU400 0x0002 /* ARM Corelink MMU-400 */ #define ACPI_IORT_SMMU_CORELINK_MMU500 0x0003 /* ARM Corelink MMU-500 */ +#define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX 0x0002 /* Cavium ThunderX2 SMMUv3 */ + /* Masks for Flags field above */ #define ACPI_IORT_SMMU_DVM_SUPPORTED(1) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 5/7] ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model
From: Linu Cherian Cavium ThunderX2 implementation doesn't support second page in SMMU register space. Hence, resource size is set as 64k for this model. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/acpi/arm64/iort.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf9..23c5350 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -833,12 +833,20 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, { struct acpi_iort_smmu_v3 *smmu; int num_res = 0; + unsigned long size = SZ_128K; /* Retrieve SMMUv3 specific data */ smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* +* Override the size, for Cavium ThunderX2 implementation +* which doesn't support the page 1 SMMU register space. +*/ + if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX) + size = SZ_64K; + res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + size - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 6/7] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126
From: Geetha Sowjanya Cavium ThunderX2 SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. This patch addresses the issue by checking if any interrupt sources are using same irq number, then they are registered as shared irqs. Signed-off-by: Geetha Sowjanya --- drivers/iommu/arm-smmu-v3.c | 32 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 016b702..46428e7 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2236,10 +2236,30 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) devm_add_action(dev, arm_smmu_free_msis, dev); } +static int get_irq_flags(struct arm_smmu_device *smmu, int irq) +{ + int match_count = 0; + + if (irq == smmu->evtq.q.irq) + match_count++; + if (irq == smmu->cmdq.q.irq) + match_count++; + if (irq == smmu->gerr_irq) + match_count++; + if (irq == smmu->priq.q.irq) + match_count++; + + if (match_count > 1) + return IRQF_SHARED | IRQF_ONESHOT; + + return 0; +} + static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) { int ret, irq; u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN; + u32 irqflags = 0; /* Disable IRQs first */ ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL, @@ -2254,9 +2274,10 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) /* Request interrupt lines */ irq = smmu->evtq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_evtq_thread, - IRQF_ONESHOT, + IRQF_ONESHOT | irqflags, "arm-smmu-v3-evtq", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable evtq irq\n"); @@ -2264,8 +2285,9 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->cmdq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_irq(smmu->dev, irq, - arm_smmu_cmdq_sync_handler, 0, + arm_smmu_cmdq_sync_handler, irqflags, "arm-smmu-v3-cmdq-sync", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n"); @@ -2273,8 +2295,9 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->gerr_irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler, - 0, "arm-smmu-v3-gerror", smmu); + irqflags, "arm-smmu-v3-gerror", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable gerror irq\n"); } @@ -2282,9 +2305,10 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (smmu->features & ARM_SMMU_FEAT_PRI) { irq = smmu->priq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_priq_thread, - IRQF_ONESHOT, + IRQF_ONESHOT | irqflags, "arm-smmu-v3-priq", smmu); if (ret < 0) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 2/7] iommu/arm-smmu-v3: Do resource size checks based on SMMU
From: Linu Cherian With implementations supporting only page 0 register space, resource size can be 64k as well and hence perform size checks based on SMMU option PAGE0_REGS_ONLY. For this, arm_smmu_device_dt_probe/acpi_probe has been moved before platform_get_resource call, so that SMMU options are set beforehand. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/iommu/arm-smmu-v3.c | 26 +- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 107b4a6..f027676 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2672,6 +2672,14 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev, return ret; } +static unsigned long arm_smmu_resource_size(struct arm_smmu_device *smmu) +{ + if (ARM_SMMU_PAGE0_REGS_ONLY(smmu)) + return SZ_64K; + else + return SZ_128K; +} + static int arm_smmu_device_probe(struct platform_device *pdev) { int irq, ret; @@ -2688,9 +2696,17 @@ static int arm_smmu_device_probe(struct platform_device *pdev) } smmu->dev = dev; + if (dev->of_node) { + ret = arm_smmu_device_dt_probe(pdev, smmu); + } else { + ret = arm_smmu_device_acpi_probe(pdev, smmu); + if (ret == -ENODEV) + return ret; + } + /* Base address */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (resource_size(res) + 1 < SZ_128K) { + if (resource_size(res) + 1 < arm_smmu_resource_size(smmu)) { dev_err(dev, "MMIO region too small (%pr)\n", res); return -EINVAL; } @@ -2717,14 +2733,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev) if (irq > 0) smmu->gerr_irq = irq; - if (dev->of_node) { - ret = arm_smmu_device_dt_probe(pdev, smmu); - } else { - ret = arm_smmu_device_acpi_probe(pdev, smmu); - if (ret == -ENODEV) - return ret; - } - /* Set bypass mode according to firmware probing result */ bypass = !!ret; -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 1/7] iommu/arm-smmu-v3: Introduce SMMU option PAGE0_REGS_ONLY
From: Linu Cherian Cavium ThunderX2 SMMU implementation doesn't support page 1 register space and PAGE0_REGS_ONLY option will be enabled as an errata workaround. This option when turned on, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. Signed-off-by: Linu Cherian Signed-off-by: Geetha Sowjanya --- drivers/iommu/arm-smmu-v3.c | 44 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 380969a..107b4a6 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -176,15 +176,15 @@ #define ARM_SMMU_CMDQ_CONS 0x9c #define ARM_SMMU_EVTQ_BASE 0xa0 -#define ARM_SMMU_EVTQ_PROD 0x100a8 -#define ARM_SMMU_EVTQ_CONS 0x100ac +#define ARM_SMMU_EVTQ_PROD(smmu) (page1_offset_adjust(0x100a8, smmu)) +#define ARM_SMMU_EVTQ_CONS(smmu) (page1_offset_adjust(0x100ac, smmu)) #define ARM_SMMU_EVTQ_IRQ_CFG0 0xb0 #define ARM_SMMU_EVTQ_IRQ_CFG1 0xb8 #define ARM_SMMU_EVTQ_IRQ_CFG2 0xbc #define ARM_SMMU_PRIQ_BASE 0xc0 -#define ARM_SMMU_PRIQ_PROD 0x100c8 -#define ARM_SMMU_PRIQ_CONS 0x100cc +#define ARM_SMMU_PRIQ_PROD(smmu) (page1_offset_adjust(0x100c8, smmu)) +#define ARM_SMMU_PRIQ_CONS(smmu) (page1_offset_adjust(0x100cc, smmu)) #define ARM_SMMU_PRIQ_IRQ_CFG0 0xd0 #define ARM_SMMU_PRIQ_IRQ_CFG1 0xd8 #define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc @@ -412,6 +412,9 @@ #define MSI_IOVA_BASE 0x800 #define MSI_IOVA_LENGTH0x10 +#define ARM_SMMU_PAGE0_REGS_ONLY(smmu) \ + ((smmu)->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY) + static bool disable_bypass; module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, @@ -597,6 +600,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) +#define ARM_SMMU_OPT_PAGE0_REGS_ONLY(1 << 1) u32 options; struct arm_smmu_cmdqcmdq; @@ -663,9 +667,19 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, + { ARM_SMMU_OPT_PAGE0_REGS_ONLY, "cavium-cn99xx,broken-page1-regspace"}, { 0, NULL}, }; +static inline unsigned long page1_offset_adjust( + unsigned long off, struct arm_smmu_device *smmu) +{ + if (!ARM_SMMU_PAGE0_REGS_ONLY(smmu)) + return off; + else + return (off - SZ_64K); +} + static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); @@ -1986,8 +2000,10 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu) return ret; /* evtq */ - ret = arm_smmu_init_one_queue(smmu, &smmu->evtq.q, ARM_SMMU_EVTQ_PROD, - ARM_SMMU_EVTQ_CONS, EVTQ_ENT_DWORDS); + ret = arm_smmu_init_one_queue(smmu, &smmu->evtq.q, + ARM_SMMU_EVTQ_PROD(smmu), + ARM_SMMU_EVTQ_CONS(smmu), + EVTQ_ENT_DWORDS); if (ret) return ret; @@ -1995,8 +2011,10 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu) if (!(smmu->features & ARM_SMMU_FEAT_PRI)) return 0; - return arm_smmu_init_one_queue(smmu, &smmu->priq.q, ARM_SMMU_PRIQ_PROD, - ARM_SMMU_PRIQ_CONS, PRIQ_ENT_DWORDS); + return arm_smmu_init_one_queue(smmu, &smmu->priq.q, + ARM_SMMU_PRIQ_PROD(smmu), + ARM_SMMU_PRIQ_CONS(smmu), + PRIQ_ENT_DWORDS); } static int arm_smmu_init_l1_strtab(struct arm_smmu_device *smmu) @@ -2363,8 +2381,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) /* Event queue */ writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE); - writel_relaxed(smmu->evtq.q.prod, smmu->base + ARM_SMMU_EVTQ_PROD); - writel_relaxed(smmu->evtq.q.cons, smmu->base + ARM_SMMU_EVTQ_CONS); + writel_relaxed(smmu->evtq.q.prod, smmu->base + + ARM_SMMU_EVTQ_PROD(smmu)); + writel_relaxed(smmu->evtq.q.cons, smmu->base + + ARM_SMMU_EVTQ_CONS(smmu)); enables |= CR0_EVTQEN; ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0, @@ -2379,9 +2399,9 @@ static int arm_smm
[PATCH v2 0/7] Cavium ThunderX2 SMMUv3 errata workarounds
From: Linu Cherian Cavium ThunderX2 SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines and also MSI for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on patchset. https://www.spinics.net/lists/arm-kernel/msg578443.html Changes from v1: Since the use of MIDR register is rejected and SMMU_IIDR is broken on this silicon, as suggested by Will Deacon modified the patches to use ThunderX2 SMMUv3 IORT model number to enable errata workaround. Geetha Sowjanya (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Linu Cherian (6): iommu/arm-smmu-v3: Introduce smmu option PAGE0_REGS_ONLY for ThunderX2 errata#74. iommu/arm-smmu-v3: Do resource size checks based on SMMU option PAGE0_REGS_ONLY ACPICA: IORT: Add Cavium ThunderX2 SMMUv3 model definition. iommu/arm-smmu-v3: For ACPI based device probing, set PAGE0_REGS_ONLY option for ThunderX2 SMMUv3 implementations. ACPI/IORT: Fixup SMMUv3 resource size for Cavium ThunderX2 SMMUv3 model arm64: Documentation: Add Cavium ThunderX2 SMMUv3 erratas Documentation/arm64/silicon-errata.txt | 2 + drivers/acpi/arm64/iort.c | 10 ++- drivers/iommu/arm-smmu-v3.c| 122 ++--- include/acpi/actbl2.h | 2 + 4 files changed, 110 insertions(+), 26 deletions(-) -- 1.8.3.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2
From: Geetha Cavium 99xx SMMU doesn't support MSI and also doesn't have unique irq lines for gerror, eventq and cmdq-sync. This patch addresses the issue by checking if any interrupt sources are using same irq number, then they are registered as shared irqs. Signed-off-by: Geetha --- Documentation/arm64/silicon-errata.txt | 1 + drivers/iommu/arm-smmu-v3.c| 32 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 629e2ce..cc15f25 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -62,6 +62,7 @@ stable kernels. | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | | Cavium | ThunderX2 SMMUv3| #74 | N/A | +| Cavium | ThunderX2 SMMUv3| #126| N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index ee23ccd..eb55d38 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2211,10 +2211,30 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) devm_add_action(dev, arm_smmu_free_msis, dev); } +static int get_irq_flags(struct arm_smmu_device *smmu, int irq) +{ + int match_count = 0; + + if (irq == smmu->evtq.q.irq) + match_count++; + if (irq == smmu->cmdq.q.irq) + match_count++; + if (irq == smmu->gerr_irq) + match_count++; + if (irq == smmu->priq.q.irq) + match_count++; + + if (match_count > 1) + return IRQF_SHARED | IRQF_ONESHOT; + + return 0; +} + static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) { int ret, irq; u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN; + u32 irqflags = 0; /* Disable IRQs first */ ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL, @@ -2229,9 +2249,10 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) /* Request interrupt lines */ irq = smmu->evtq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_evtq_thread, - IRQF_ONESHOT, + IRQF_ONESHOT | irqflags, "arm-smmu-v3-evtq", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable evtq irq\n"); @@ -2239,8 +2260,9 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->cmdq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_irq(smmu->dev, irq, - arm_smmu_cmdq_sync_handler, 0, + arm_smmu_cmdq_sync_handler, irqflags, "arm-smmu-v3-cmdq-sync", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n"); @@ -2248,8 +2270,9 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) irq = smmu->gerr_irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler, - 0, "arm-smmu-v3-gerror", smmu); + irqflags, "arm-smmu-v3-gerror", smmu); if (ret < 0) dev_warn(smmu->dev, "failed to enable gerror irq\n"); } @@ -2257,9 +2280,10 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (smmu->features & ARM_SMMU_FEAT_PRI) { irq = smmu->priq.q.irq; if (irq) { + irqflags = get_irq_flags(smmu, irq); ret = devm_request_threaded_irq(smmu->dev, irq, NULL, arm_smmu_priq_thread, - IRQF_ONESHOT, + IRQF_ONESHOT | irqflags, "arm-smmu-v3-priq", smmu); if (ret < 0) -- 1.9.1 ___ iomm
[PATCH 2/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74
From: Linu Cherian Cavium 99xx SMMU implementation doesn't support page 1 register space. Based on silicon id, ARM_SMMU_PAGE0_REGS_ONLY macro is set as an errata workaround. This macro when set, replaces all page 1 offsets used for EVTQ_PROD/CONS, PRIQ_PROD/CONS register access with page 0 offsets. Signed-off-by: Linu Cherian Signed-off-by: Geetha --- Documentation/arm64/silicon-errata.txt | 1 + drivers/acpi/arm64/iort.c | 14 +- drivers/iommu/arm-smmu-v3.c| 32 +++- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 2f66683..629e2ce 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -61,6 +61,7 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A | +| Cavium | ThunderX2 SMMUv3| #74 | N/A | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | || | | | diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 4a5bb96..a074ce9 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -25,6 +25,7 @@ #include #include #include +#include #define IORT_TYPE_MASK(type) (1 << (type)) #define IORT_MSI_TYPE (1 << ACPI_IORT_NODE_ITS_GROUP) @@ -669,12 +670,23 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, { struct acpi_iort_smmu_v3 *smmu; int num_res = 0; + u32 cpu_model; + unsigned long size = SZ_128K; /* Retrieve SMMUv3 specific data */ smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* +* Override the size, for Cavium CN99xx implementations +* which doesn't support the page 1 SMMU register space. +*/ + cpu_model = read_cpuid_id() & MIDR_CPU_MODEL_MASK; + if (cpu_model == MIDR_THUNDERX_99XX || + cpu_model == MIDR_BRCM_VULCAN) + size = SZ_64K; + res[num_res].start = smmu->base_address; - res[num_res].end = smmu->base_address + SZ_128K - 1; + res[num_res].end = smmu->base_address + size - 1; res[num_res].flags = IORESOURCE_MEM; num_res++; diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 1dcd154..ee23ccd 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -38,6 +38,7 @@ #include #include +#include #include "io-pgtable.h" @@ -176,15 +177,15 @@ #define ARM_SMMU_CMDQ_CONS 0x9c #define ARM_SMMU_EVTQ_BASE 0xa0 -#define ARM_SMMU_EVTQ_PROD 0x100a8 -#define ARM_SMMU_EVTQ_CONS 0x100ac +#define ARM_SMMU_EVTQ_PROD (page1_offset_adjust(0x100a8)) +#define ARM_SMMU_EVTQ_CONS (page1_offset_adjust(0x100ac)) #define ARM_SMMU_EVTQ_IRQ_CFG0 0xb0 #define ARM_SMMU_EVTQ_IRQ_CFG1 0xb8 #define ARM_SMMU_EVTQ_IRQ_CFG2 0xbc #define ARM_SMMU_PRIQ_BASE 0xc0 -#define ARM_SMMU_PRIQ_PROD 0x100c8 -#define ARM_SMMU_PRIQ_CONS 0x100cc +#define ARM_SMMU_PRIQ_PROD (page1_offset_adjust(0x100c8)) +#define ARM_SMMU_PRIQ_CONS (page1_offset_adjust(0x100cc)) #define ARM_SMMU_PRIQ_IRQ_CFG0 0xd0 #define ARM_SMMU_PRIQ_IRQ_CFG1 0xd8 #define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc @@ -412,6 +413,10 @@ #define MSI_IOVA_BASE 0x800 #define MSI_IOVA_LENGTH0x10 +#define ARM_SMMU_PAGE0_REGS_ONLY \ + (((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_THUNDERX_99XX) \ + || ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) == MIDR_BRCM_VULCAN)) + static bool disable_bypass; module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, @@ -660,6 +665,15 @@ struct arm_smmu_option_prop { { 0, NULL}, }; +static inline unsigned long page1_offset_adjust( + unsigned long off) +{ + if (!ARM_SMMU_PAGE0_REGS_ONLY) + return off; + else + return (off - SZ_64K); +} + static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) { return container_of(dom, struct arm_smmu_domain, domain); @@ -2631,6 +2645,14 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev, return ret; } +static unsigned long arm_smmu_resource_size(void) +{ + if (ARM_SMMU_PAGE0_REGS_ONLY) + return SZ_64K; + else + ret
[PATCH 1/3] arm64: Add MIDR values for Cavium cn99xx SoCs
From: Geetha Add MIDR values for Cavium cn99xx SoCs Signed-off-by: Geetha --- arch/arm64/include/asm/cputype.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index fc50271..066fad0 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -85,6 +85,7 @@ #define CAVIUM_CPU_PART_THUNDERX 0x0A1 #define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2 +#define CAVIUM_CPU_PART_THUNDERX_99XX 0x0AF #define BRCM_CPU_PART_VULCAN 0x516 @@ -94,6 +95,8 @@ #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) +#define MIDR_THUNDERX_99XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_99XX) +#define MIDR_BRCM_VULCAN MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN) #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) #ifndef __ASSEMBLY__ -- 1.9.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 0/3] Cavium ThunderX2 SMMUv3 errata workarounds
From: Geetha Cavium CN99xx SMMUv3 implementation has two Silicon Erratas. 1. Errata ID #74 SMMU register alias Page 1 is not implemented 2. Errata ID #126 SMMU doesnt support unique IRQ lines for gerror, eventq and cmdq-sync The following patchset does software workaround for these two erratas. This series is based on RFC patch. https://www.spinics.net/lists/arm-kernel/msg575739.html As suggested by Will Deacon, code is modified to use silicon id to enable errata#74 workaround. Linu Cherian (1): iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #74 Geetha (2): arm64: Add MIDR values for Cavium cn99xx SoCs iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Documentation/arm64/silicon-errata.txt | 2 ++ arch/arm64/include/asm/cputype.h | 3 ++ drivers/acpi/arm64/iort.c | 14 +++- drivers/iommu/arm-smmu-v3.c| 64 +- 4 files changed, 73 insertions(+), 10 deletions(-) -- 1.9.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH] iommu/arm-smmu-v3: Increase SMMU CMD queue poll timeout
From: Geetha When large memory is being unmapped, huge no of tlb invalidation cmds are submitted followed by a SYNC command. This sometimes hits CMD queue full and poll on queue drain is being timedout throwing error message 'CMD_SYNC timeout'. Although there is no functional issue, error message confuses user. Hence increased poll timeout to 500us Signed-off-by: Geetha --- drivers/iommu/arm-smmu-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 591bb96..1dcd154 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -407,7 +407,7 @@ #define PRIQ_1_ADDR_MASK 0xfUL /* High-level queue structures */ -#define ARM_SMMU_POLL_TIMEOUT_US 100 +#define ARM_SMMU_POLL_TIMEOUT_US 500 #define MSI_IOVA_BASE 0x800 #define MSI_IOVA_LENGTH0x10 -- 1.9.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v3] arm64: SMMU-v2: Workaround for Cavium ThunderX erratum 28168
From: Tirumalesh Chalamarla This patch implements Cavium ThunderX erratum 28168. PCI requires stores complete in order. Due to erratum #28168 PCI-inbound MSI-X store to the interrupt controller are delivered to the interrupt controller before older PCI-inbound memory stores are committed. Doing a sync on SMMU will make sure all prior data transfers are completed before invoking ISR. changes from v2: - added entry in Documentation/arm64/silicon-errata.txt - moved registration of the preflow_handler into msi_domain_ops.msi_finish() handler. - create linux/arm.smmu.h to expose smmu API. Signed-off-by: Tirumalesh Chalamarla --- Documentation/arm64/silicon-errata.txt | 1 + arch/arm64/Kconfig | 12 arch/arm64/include/asm/cpucaps.h | 3 +- arch/arm64/kernel/cpu_errata.c | 16 +++ drivers/iommu/arm-smmu.c | 22 +++ drivers/irqchip/irq-gic-v3-its-pci-msi.c | 48 +++- include/linux/arm-smmu.h | 8 ++ 7 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 include/linux/arm-smmu.h diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 405da11..1311f90 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -61,5 +61,6 @@ stable kernels. | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | | Cavium | ThunderX SMMUv2 | #27704 | N/A| +| Cavium | ThunderX PCI| #28168 | CAVIUM_ERRATUM_28168 | || | | | | Freescale/NXP | LS2080A/LS1043A | A-008585| FSL_ERRATUM_A008585 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 969ef88..cb647f4 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -474,6 +474,18 @@ config CAVIUM_ERRATUM_27456 If unsure, say Y. +config CAVIUM_ERRATUM_28168 + bool "Cavium erratum 28168: Make sure DMA data transfer is done before MSIX" + depends on ARM64 && ARM_SMMU + default y + select IRQ_PREFLOW_FASTEOI + help +Due to erratum #28168 PCI-inbound MSI-X store to the interrupt +controller are delivered to the interrupt controller before older +PCI-inbound memory stores are committed. Doing a sync on SMMU +will make sure all prior data transfers are done before invoking ISR. + +If unsure, say Y. endmenu diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index 87b4465..6975a01 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -34,7 +34,8 @@ #define ARM64_HAS_32BIT_EL013 #define ARM64_HYP_OFFSET_LOW 14 #define ARM64_MISMATCHED_CACHE_LINE_SIZE 15 +#define ARM64_WORKAROUND_CAVIUM_28168 16 -#define ARM64_NCAPS16 +#define ARM64_NCAPS17 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index b75e917..fac6d74 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -123,6 +123,22 @@ static int cpu_enable_trap_ctr_access(void *__unused) MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00), }, #endif +#ifdef CONFIG_CAVIUM_ERRATUM_28168 + { + /* Cavium ThunderX, T88 pass 1.x - 2.1 */ + .desc = "Cavium erratum 28168", + .capability = ARM64_WORKAROUND_CAVIUM_28168, + MIDR_RANGE(MIDR_THUNDERX, 0x00, + (1 << MIDR_VARIANT_SHIFT) | 1), + }, + { + /* Cavium ThunderX, T81 pass 1.0 */ + .desc = "Cavium erratum 28168", + .capability = ARM64_WORKAROUND_CAVIUM_28168, + MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00), + }, +#endif + { .desc = "Mismatched cache line size", .capability = ARM64_MISMATCHED_CACHE_LINE_SIZE, diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 06167da..451b393 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -49,6 +49,8 @@ #include #include +#include + #include "io-pgtable.h" @@ -577,6 +579,26 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu) } } +#ifdef CONFIG_CAVIUM_ERRATUM_28168 +/* + * Cavium ThunderX erratum 28168 + * + * Due to erratum #28168 PCI-inbound MSI-X store to the interrupt + * controller are delivered to the interrupt controller before older + * PCI-inbound memory stores are committed. Doing a sync on SMMU + * will make sure all prior data transfers are completed before + * invoking ISR. + * +
[PATCH v2] arm64: SMMU-v2: Workaround for Cavium ThunderX erratum 28168
From: Tirumalesh Chalamarla This patch implements Cavium ThunderX erratum 28168. PCI requires stores complete in order. Due to erratum #28168 PCI-inbound MSI-X store to the interrupt controller are delivered to the interrupt controller before older PCI-inbound memory stores are committed. Doing a sync on SMMU will make sure all prior data transfers are completed before invoking ISR. Signed-off-by: Tirumalesh Chalamarla Signed-off-by: Geetha sowjanya --- arch/arm64/Kconfig | 11 +++ arch/arm64/Kconfig.platforms|1 + arch/arm64/include/asm/cpufeature.h |3 ++- arch/arm64/kernel/cpu_errata.c | 16 drivers/iommu/arm-smmu.c| 24 drivers/irqchip/irq-gic-common.h|1 + drivers/irqchip/irq-gic-v3.c| 19 +++ 7 files changed, 74 insertions(+), 1 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 30398db..751972c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -474,6 +474,17 @@ config CAVIUM_ERRATUM_27456 If unsure, say Y. +config CAVIUM_ERRATUM_28168 + bool "Cavium erratum 28168: Make sure DMA data transfer is done before MSIX" + depends on ARCH_THUNDER && ARM64 + default y + help +Due to erratum #28168 PCI-inbound MSI-X store to the interrupt +controller are delivered to the interrupt controller before older +PCI-inbound memory stores are committed. Doing a sync on SMMU +will make sure all prior data transfers are done before invoking ISR. + +If unsure, say Y. endmenu diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index cfbdf02..2ac4ac6 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -185,6 +185,7 @@ config ARCH_SPRD config ARCH_THUNDER bool "Cavium Inc. Thunder SoC Family" + select IRQ_PREFLOW_FASTEOI help This enables support for Cavium's Thunder Family of SoCs. diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 758d74f..821fc3c 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -40,8 +40,9 @@ #define ARM64_HAS_32BIT_EL013 #define ARM64_HYP_OFFSET_LOW 14 #define ARM64_MISMATCHED_CACHE_LINE_SIZE 15 +#define ARM64_WORKAROUND_CAVIUM_28168 16 -#define ARM64_NCAPS16 +#define ARM64_NCAPS17 #ifndef __ASSEMBLY__ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 0150394..0841a12 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -122,6 +122,22 @@ static void cpu_enable_trap_ctr_access(void *__unused) MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00), }, #endif +#ifdef CONFIG_CAVIUM_ERRATUM_28168 + { + /* Cavium ThunderX, T88 pass 1.x - 2.1 */ + .desc = "Cavium erratum 28168", + .capability = ARM64_WORKAROUND_CAVIUM_28168, + MIDR_RANGE(MIDR_THUNDERX, 0x00, + (1 << MIDR_VARIANT_SHIFT) | 1), + }, + { + /* Cavium ThunderX, T81 pass 1.0 */ + .desc = "Cavium erratum 28168", + .capability = ARM64_WORKAROUND_CAVIUM_28168, + MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00), + }, +#endif + { .desc = "Mismatched cache line size", .capability = ARM64_MISMATCHED_CACHE_LINE_SIZE, diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index c841eb7..1b4555c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -570,6 +570,30 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu) } } +/* + * Cavium ThunderX erratum 28168 + * + * Due to erratum #28168 PCI-inbound MSI-X store to the interrupt + * controller are delivered to the interrupt controller before older + * PCI-inbound memory stores are committed. Doing a sync on SMMU + * will make sure all prior data transfers are completed before + * invoking ISR. + * + */ +void cavium_arm_smmu_tlb_sync(struct device *dev) +{ + struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct arm_smmu_device *smmu; + + smmu = fwspec_smmu(fwspec); + if (!smmu) + return; + __arm_smmu_tlb_sync(smmu); + +} +EXPORT_SYMBOL(cavium_arm_smmu_tlb_sync); + + static void arm_smmu_tlb_sync(void *cookie) { struct arm_smmu_domain *smmu_domain = cookie; diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h index 205e5fd..4e88f55 100644 --- a/drivers/irqchip/irq-gic-common.h +++ b/drivers/irqchip/irq-gic-common.h @@ -38,4 +38,5 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *qu
[PATCH] arm64: SMMU-v2: Workaround for Cavium ThunderX erratum 28168
From: Tirumalesh Chalamarla This patch implements Cavium ThunderX erratum 28168. PCI requires stores complete in order. Due to erratum #28168 PCI-inbound MSI-X store to the interrupt controller are delivered to the interrupt controller before older PCI-inbound memory stores are committed. Doing a sync on SMMU will make sure all prior transactions are completed. Signed-off-by: Tirumalesh Chalamarla Signed-off-by: Geetha sowjanya --- arch/arm64/Kconfig | 11 +++ drivers/iommu/arm-smmu.c | 38 ++ drivers/irqchip/irq-gic-common.h |1 + drivers/irqchip/irq-gic-v3-its.c | 22 ++ kernel/irq/chip.c|4 5 files changed, 76 insertions(+), 0 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 30398db..57f5c9b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -474,6 +474,17 @@ config CAVIUM_ERRATUM_27456 If unsure, say Y. +config CAVIUM_ERRATUM_28168 + bool "Cavium erratum 28168: Make sure ITS and SMMU TLB are in sync" + default y + help +Due to erratum #28168 PCI-inbound MSI-X store to the interrupt +controller are delivered to the interrupt controller before older +PCI-inbound memory stores are committed. Doing a sync on SMMU +will make sure all prior transactions are completed. + +If unsure, say Y. + endmenu diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 9740846..20a61c6 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -378,6 +378,7 @@ struct arm_smmu_device { unsigned int*irqs; u32 cavium_id_base; /* Specific to Cavium */ + spinlock_t tlb_lock; }; enum arm_smmu_context_fmt { @@ -576,9 +577,39 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu) static void arm_smmu_tlb_sync(void *cookie) { struct arm_smmu_domain *smmu_domain = cookie; + struct arm_smmu_device *smmu = smmu_domain->smmu; + unsigned long flags; + + spin_lock_irqsave(&smmu->tlb_lock, flags); __arm_smmu_tlb_sync(smmu_domain->smmu); + spin_unlock_irqrestore(&smmu->tlb_lock, flags) } +/* + * Cavium ThunderX erratum 28168 + * + * Due to erratum #28168 PCI-inbound MSI-X store to the interrupt + * controller are delivered to the interrupt controller before older + * PCI-inbound memory stores are committed. Doing a sync on SMMU + * will make sure all prior transactions are completed. + * + */ +void cavium_smmu_tlb_sync(struct device *dev) +{ + struct arm_smmu_device *smmu; + struct arm_smmu_master_cfg *cfg; + unsigned long flags; + + smmu = find_smmu_for_device(dev); + if (!smmu) + return; + + spin_lock_irqsave(&smmu->tlb_lock, flags); +__arm_smmu_tlb_sync(smmu); + spin_unlock_irqrestore(&smmu->tlb_lock, flags) +} +EXPORT_SYMBOL(cavium_smmu_tlb_sync); + static void arm_smmu_tlb_inv_context(void *cookie) { struct arm_smmu_domain *smmu_domain = cookie; @@ -586,6 +617,7 @@ static void arm_smmu_tlb_inv_context(void *cookie) struct arm_smmu_device *smmu = smmu_domain->smmu; bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; void __iomem *base; + unsigned long flags; if (stage1) { base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); @@ -597,7 +629,9 @@ static void arm_smmu_tlb_inv_context(void *cookie) base + ARM_SMMU_GR0_TLBIVMID); } + spin_lock_irqsave(&smmu->tlb_lock, flags); __arm_smmu_tlb_sync(smmu); + spin_unlock_irqrestore(&smmu->tlb_lock, flags) } static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, @@ -1562,6 +1596,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) void __iomem *gr0_base = ARM_SMMU_GR0(smmu); void __iomem *cb_base; int i; + unsigned long flags; u32 reg, major; /* clear global FSR */ @@ -1633,7 +1668,9 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) reg |= sCR0_VMID16EN; /* Push the button */ + spin_lock_irqsave(&smmu->tlb_lock, flags) __arm_smmu_tlb_sync(smmu); + spin_unlock_irqrestore(&smmu->tlb_lock, flags) writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); } @@ -2001,6 +2038,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) } } + spin_lock_init(&smmu->tlb_lock); of_iommu_set_ops(dev->of_node, &arm_smmu_ops); platform_set_drvdata(pdev, smmu); arm_smmu_device_reset(smmu); diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h ind
[PATCH] iommu: arm-smmu-v2: Enable 16 bit ASID
Support up to 16 bit ASID. This patch enables 16 bit ASID when supported. Signed-off-by: Geetha sowjanya Acked-by: Tirumalesh Chalamarla --- drivers/iommu/arm-smmu.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index c841eb7..9740846 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -258,6 +258,9 @@ enum arm_smmu_s2cr_privcfg { #define TTBCR2_SEP_SHIFT 15 #define TTBCR2_SEP_UPSTREAM(0x7 << TTBCR2_SEP_SHIFT) +#define TTBCR2_AS_SHIFT4 +#define TTBCR2_AS_ENABLE (1 << TTBCR2_AS_SHIFT) + #define TTBRn_ASID_SHIFT 48 #define FSR_MULTI (1 << 31) @@ -773,6 +776,9 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr; reg2 = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32; reg2 |= TTBCR2_SEP_UPSTREAM; + /* Enable 16 bit ASID if 16 bit VMID is supported */ + if (smmu->features & ARM_SMMU_FEAT_VMID16) + reg |= TTBCR2_AS_ENABLE; } if (smmu->version > ARM_SMMU_V1) writel_relaxed(reg2, cb_base + ARM_SMMU_CB_TTBCR2); -- 1.7.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu