* [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 @ 2017-06-23 5:58 Geetha sowjanya 2017-06-23 11:39 ` Lorenzo Pieralisi 0 siblings, 1 reply; 5+ messages in thread From: Geetha sowjanya @ 2017-06-23 5:58 UTC (permalink / raw) To: will.deacon-5wv7dgnIgG8, robin.murphy-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, sudeep.holla-5wv7dgnIgG8, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA Cc: robh-DgEjT+Ai2ygdnm+yROfE0A, Charles.Garcia-Tobin-5wv7dgnIgG8, Geetha Sowjanya, geethasowjanya.akula-Re5JQEeQqe8AvxtiuMwx3w, jcm-H+wXaHxf7aLQT0dZR+AlfA, linu.cherian-YGCgFSpz5w/QT0dZR+AlfA, rjw-LthD3rsA81gm4RdzfppkhA, robert.moore-ral2JQCrhuEAvxtiuMwx3w, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-acpi-u79uwXL29TY76Z2rM5mHXA, robert.richter-YGCgFSpz5w/QT0dZR+AlfA, lv.zheng-ral2JQCrhuEAvxtiuMwx3w, catalin.marinas-5wv7dgnIgG8, Geetha sowjanya, sgoutham-YGCgFSpz5w/QT0dZR+AlfA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devel-E0kO6a4B6psdnm+yROfE0A From: Geetha Sowjanya <geethasowjanya.akula-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org> 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 <gakula-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org> --- 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->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", + ACPI_EDGE_SENSITIVE, + &res[num_res++]); + } } static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 2dea4a9..fd5a48c 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -605,6 +605,7 @@ struct arm_smmu_device { struct arm_smmu_priq priq; int gerr_irq; + int combined_irq; unsigned long ias; /* IPA */ unsigned long oas; /* PA */ @@ -1314,6 +1315,24 @@ static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev) return IRQ_HANDLED; } +static irqreturn_t arm_smmu_combined_irq_thread(int irq, void *dev) +{ + struct arm_smmu_device *smmu = dev; + + arm_smmu_evtq_thread(irq, dev); + if (smmu->features & ARM_SMMU_FEAT_PRI) + arm_smmu_priq_thread(irq, dev); + + return IRQ_HANDLED; +} + +static irqreturn_t arm_smmu_combined_irq_handler(int irq, void *dev) +{ + arm_smmu_gerror_handler(irq, dev); + arm_smmu_cmdq_sync_handler(irq, dev); + return IRQ_WAKE_THREAD; +} + /* IO_PGTABLE API */ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu) { @@ -2230,18 +2249,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 +2294,41 @@ 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 int arm_smmu_setup_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; + } + + irq = smmu->combined_irq; + if (irq) { + /* + * Cavium ThunderX2 implementation doesn't not support unique + * irq lines. Use single irq line for all the SMMUv3 interrupts. + */ + ret = devm_request_threaded_irq(smmu->dev, irq, + arm_smmu_combined_irq_handler, + arm_smmu_combined_irq_thread, + IRQF_ONESHOT, + "arm-smmu-v3-combined-irq", smmu); + if (ret < 0) + dev_warn(smmu->dev, "failed to enable combined irq\n"); + } else + arm_smmu_setup_unique_irqs(smmu); + + if (smmu->features & ARM_SMMU_FEAT_PRI) + irqen_flags |= IRQ_CTRL_PRIQ_IRQEN; /* Enable interrupt generation on the SMMU */ ret = arm_smmu_write_reg_sync(smmu, irqen_flags, @@ -2724,22 +2765,27 @@ static int arm_smmu_device_probe(struct platform_device *pdev) return PTR_ERR(smmu->base); /* Interrupt lines */ - irq = platform_get_irq_byname(pdev, "eventq"); - if (irq > 0) - smmu->evtq.q.irq = irq; - irq = platform_get_irq_byname(pdev, "priq"); + irq = platform_get_irq_byname(pdev, "combined"); if (irq > 0) - smmu->priq.q.irq = irq; + smmu->combined_irq = irq; + else { + irq = platform_get_irq_byname(pdev, "eventq"); + if (irq > 0) + smmu->evtq.q.irq = irq; - irq = platform_get_irq_byname(pdev, "cmdq-sync"); - if (irq > 0) - smmu->cmdq.q.irq = irq; + irq = platform_get_irq_byname(pdev, "priq"); + if (irq > 0) + smmu->priq.q.irq = irq; - irq = platform_get_irq_byname(pdev, "gerror"); - if (irq > 0) - smmu->gerr_irq = irq; + irq = platform_get_irq_byname(pdev, "cmdq-sync"); + if (irq > 0) + smmu->cmdq.q.irq = irq; + irq = platform_get_irq_byname(pdev, "gerror"); + if (irq > 0) + smmu->gerr_irq = irq; + } /* Probe the h/w */ ret = arm_smmu_device_hw_probe(smmu); if (ret) -- 1.7.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 2017-06-23 5:58 [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Geetha sowjanya @ 2017-06-23 11:39 ` Lorenzo Pieralisi 0 siblings, 0 replies; 5+ messages in thread From: Lorenzo Pieralisi @ 2017-06-23 11:39 UTC (permalink / raw) To: Geetha sowjanya Cc: will.deacon, robin.murphy, hanjun.guo, sudeep.holla, iommu, robert.moore, lv.zheng, rjw, jcm, linux-kernel, robert.richter, catalin.marinas, sgoutham, linux-arm-kernel, linux-acpi, geethasowjanya.akula, devel, linu.cherian, Charles.Garcia-Tobin, robh, Geetha Sowjanya On Fri, Jun 23, 2017 at 11:28:05AM +0530, Geetha sowjanya wrote: [...] > --- 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++]); I think you should add a check to make sure ALL gsiv are the same in the IORT table, if they are not the combined IRQ must not be registered. Ideally we should add a patch that adds a return value to the iommu_init_resource callback (ie so that we can prevent allocating the platform device on error return value) but we are late -rc6 and I won't be able to read mailing lists next week so it is a bit tight, adding the check above should be quick to do. Lorenzo > + 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", > + ACPI_EDGE_SENSITIVE, > + &res[num_res++]); > + > + if (smmu->sync_gsiv) > + acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync", > + ACPI_EDGE_SENSITIVE, > + &res[num_res++]); > + } > } > > static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node) > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c > index 2dea4a9..fd5a48c 100644 > --- a/drivers/iommu/arm-smmu-v3.c > +++ b/drivers/iommu/arm-smmu-v3.c > @@ -605,6 +605,7 @@ struct arm_smmu_device { > struct arm_smmu_priq priq; > > int gerr_irq; > + int combined_irq; > > unsigned long ias; /* IPA */ > unsigned long oas; /* PA */ > @@ -1314,6 +1315,24 @@ static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev) > return IRQ_HANDLED; > } > > +static irqreturn_t arm_smmu_combined_irq_thread(int irq, void *dev) > +{ > + struct arm_smmu_device *smmu = dev; > + > + arm_smmu_evtq_thread(irq, dev); > + if (smmu->features & ARM_SMMU_FEAT_PRI) > + arm_smmu_priq_thread(irq, dev); > + > + return IRQ_HANDLED; > +} > + > +static irqreturn_t arm_smmu_combined_irq_handler(int irq, void *dev) > +{ > + arm_smmu_gerror_handler(irq, dev); > + arm_smmu_cmdq_sync_handler(irq, dev); > + return IRQ_WAKE_THREAD; > +} > + > /* IO_PGTABLE API */ > static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu) > { > @@ -2230,18 +2249,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 +2294,41 @@ 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 int arm_smmu_setup_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; > + } > + > + irq = smmu->combined_irq; > + if (irq) { > + /* > + * Cavium ThunderX2 implementation doesn't not support unique > + * irq lines. Use single irq line for all the SMMUv3 interrupts. > + */ > + ret = devm_request_threaded_irq(smmu->dev, irq, > + arm_smmu_combined_irq_handler, > + arm_smmu_combined_irq_thread, > + IRQF_ONESHOT, > + "arm-smmu-v3-combined-irq", smmu); > + if (ret < 0) > + dev_warn(smmu->dev, "failed to enable combined irq\n"); > + } else > + arm_smmu_setup_unique_irqs(smmu); > + > + if (smmu->features & ARM_SMMU_FEAT_PRI) > + irqen_flags |= IRQ_CTRL_PRIQ_IRQEN; > > /* Enable interrupt generation on the SMMU */ > ret = arm_smmu_write_reg_sync(smmu, irqen_flags, > @@ -2724,22 +2765,27 @@ static int arm_smmu_device_probe(struct platform_device *pdev) > return PTR_ERR(smmu->base); > > /* Interrupt lines */ > - irq = platform_get_irq_byname(pdev, "eventq"); > - if (irq > 0) > - smmu->evtq.q.irq = irq; > > - irq = platform_get_irq_byname(pdev, "priq"); > + irq = platform_get_irq_byname(pdev, "combined"); > if (irq > 0) > - smmu->priq.q.irq = irq; > + smmu->combined_irq = irq; > + else { > + irq = platform_get_irq_byname(pdev, "eventq"); > + if (irq > 0) > + smmu->evtq.q.irq = irq; > > - irq = platform_get_irq_byname(pdev, "cmdq-sync"); > - if (irq > 0) > - smmu->cmdq.q.irq = irq; > + irq = platform_get_irq_byname(pdev, "priq"); > + if (irq > 0) > + smmu->priq.q.irq = irq; > > - irq = platform_get_irq_byname(pdev, "gerror"); > - if (irq > 0) > - smmu->gerr_irq = irq; > + irq = platform_get_irq_byname(pdev, "cmdq-sync"); > + if (irq > 0) > + smmu->cmdq.q.irq = irq; > > + irq = platform_get_irq_byname(pdev, "gerror"); > + if (irq > 0) > + smmu->gerr_irq = irq; > + } > /* Probe the h/w */ > ret = arm_smmu_device_hw_probe(smmu); > if (ret) > -- > 1.7.1 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v9 0/3] Cavium ThunderX2 SMMUv3 errata workarounds
@ 2017-06-22 12:05 Geetha sowjanya
[not found] ` <1498133138-20244-1-git-send-email-gakula-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Geetha sowjanya @ 2017-06-22 12:05 UTC (permalink / raw)
To: will.deacon-5wv7dgnIgG8, robin.murphy-5wv7dgnIgG8,
lorenzo.pieralisi-5wv7dgnIgG8, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
sudeep.holla-5wv7dgnIgG8,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: robh-DgEjT+Ai2ygdnm+yROfE0A, Charles.Garcia-Tobin-5wv7dgnIgG8,
Geetha sowjanya, geethasowjanya.akula-Re5JQEeQqe8AvxtiuMwx3w,
jcm-H+wXaHxf7aLQT0dZR+AlfA, linu.cherian-YGCgFSpz5w/QT0dZR+AlfA,
rjw-LthD3rsA81gm4RdzfppkhA, robert.moore-ral2JQCrhuEAvxtiuMwx3w,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
robert.richter-YGCgFSpz5w/QT0dZR+AlfA,
lv.zheng-ral2JQCrhuEAvxtiuMwx3w, catalin.marinas-5wv7dgnIgG8,
sgoutham-YGCgFSpz5w/QT0dZR+AlfA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devel-E0kO6a4B6psdnm+yROfE0A
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(-)
^ permalink raw reply [flat|nested] 5+ messages in thread[parent not found: <1498133138-20244-1-git-send-email-gakula-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>]
* [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 [not found] ` <1498133138-20244-1-git-send-email-gakula-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org> @ 2017-06-22 12:05 ` Geetha sowjanya 2017-06-22 18:22 ` Will Deacon 0 siblings, 1 reply; 5+ messages in thread From: Geetha sowjanya @ 2017-06-22 12:05 UTC (permalink / raw) To: will.deacon-5wv7dgnIgG8, robin.murphy-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, sudeep.holla-5wv7dgnIgG8, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA Cc: robh-DgEjT+Ai2ygdnm+yROfE0A, Charles.Garcia-Tobin-5wv7dgnIgG8, Geetha Sowjanya, geethasowjanya.akula-Re5JQEeQqe8AvxtiuMwx3w, jcm-H+wXaHxf7aLQT0dZR+AlfA, linu.cherian-YGCgFSpz5w/QT0dZR+AlfA, rjw-LthD3rsA81gm4RdzfppkhA, robert.moore-ral2JQCrhuEAvxtiuMwx3w, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-acpi-u79uwXL29TY76Z2rM5mHXA, robert.richter-YGCgFSpz5w/QT0dZR+AlfA, lv.zheng-ral2JQCrhuEAvxtiuMwx3w, catalin.marinas-5wv7dgnIgG8, Geetha sowjanya, sgoutham-YGCgFSpz5w/QT0dZR+AlfA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devel-E0kO6a4B6psdnm+yROfE0A From: Geetha Sowjanya <geethasowjanya.akula-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org> 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 <gakula-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org> --- 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", + ACPI_EDGE_SENSITIVE, + &res[num_res++]); + + if (smmu->sync_gsiv) + acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync", + ACPI_EDGE_SENSITIVE, + &res[num_res++]); + } } static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 2dea4a9..0f83f7d 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -605,6 +605,7 @@ struct arm_smmu_device { struct arm_smmu_priq priq; int gerr_irq; + int combined_irq; unsigned long ias; /* IPA */ unsigned long oas; /* PA */ @@ -1314,6 +1315,29 @@ static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev) return IRQ_HANDLED; } +static irqreturn_t arm_smmu_combined_irq_thread(int irq, void *dev) +{ + struct arm_smmu_device *smmu = dev; + + arm_smmu_evtq_thread(irq, dev); + if (smmu->features & ARM_SMMU_FEAT_PRI) + arm_smmu_priq_thread(irq, dev); + + return IRQ_HANDLED; +} + +static irqreturn_t arm_smmu_combined_irq_handler(int irq, void *dev) +{ + irqreturn_t ret; + + ret = arm_smmu_gerror_handler(irq, dev); + if (ret == IRQ_NONE) { + arm_smmu_cmdq_sync_handler(irq, dev); + return IRQ_WAKE_THREAD; + } + return ret; +} + /* IO_PGTABLE API */ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu) { @@ -2230,18 +2254,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 +2299,41 @@ 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 int arm_smmu_setup_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; + } + + irq = smmu->combined_irq; + if (irq) { + /* + * Cavium ThunderX2 implementation doesn't not support unique + * irq lines. Use single irq line for all the SMMUv3 interrupts. + */ + ret = devm_request_threaded_irq(smmu->dev, irq, + arm_smmu_combined_irq_handler, + arm_smmu_combined_irq_thread, + IRQF_ONESHOT, + "arm-smmu-v3-combined-irq", smmu); + if (ret < 0) + dev_warn(smmu->dev, "failed to enable combined irq\n"); + } else + arm_smmu_setup_unique_irqs(smmu); + + if (smmu->features & ARM_SMMU_FEAT_PRI) + irqen_flags |= IRQ_CTRL_PRIQ_IRQEN; /* Enable interrupt generation on the SMMU */ ret = arm_smmu_write_reg_sync(smmu, irqen_flags, @@ -2724,22 +2770,27 @@ static int arm_smmu_device_probe(struct platform_device *pdev) return PTR_ERR(smmu->base); /* Interrupt lines */ - irq = platform_get_irq_byname(pdev, "eventq"); - if (irq > 0) - smmu->evtq.q.irq = irq; - irq = platform_get_irq_byname(pdev, "priq"); + irq = platform_get_irq_byname(pdev, "combined"); if (irq > 0) - smmu->priq.q.irq = irq; + smmu->combined_irq = irq; + else { + irq = platform_get_irq_byname(pdev, "eventq"); + if (irq > 0) + smmu->evtq.q.irq = irq; - irq = platform_get_irq_byname(pdev, "cmdq-sync"); - if (irq > 0) - smmu->cmdq.q.irq = irq; + irq = platform_get_irq_byname(pdev, "priq"); + if (irq > 0) + smmu->priq.q.irq = irq; - irq = platform_get_irq_byname(pdev, "gerror"); - if (irq > 0) - smmu->gerr_irq = irq; + irq = platform_get_irq_byname(pdev, "cmdq-sync"); + if (irq > 0) + smmu->cmdq.q.irq = irq; + irq = platform_get_irq_byname(pdev, "gerror"); + if (irq > 0) + smmu->gerr_irq = irq; + } /* Probe the h/w */ ret = arm_smmu_device_hw_probe(smmu); if (ret) -- 1.7.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 2017-06-22 12:05 ` [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Geetha sowjanya @ 2017-06-22 18:22 ` Will Deacon 2017-06-23 6:21 ` Geetha Akula 0 siblings, 1 reply; 5+ messages in thread From: Will Deacon @ 2017-06-22 18:22 UTC (permalink / raw) To: Geetha sowjanya Cc: robin.murphy, lorenzo.pieralisi, hanjun.guo, sudeep.holla, iommu, robert.moore, lv.zheng, rjw, jcm, linux-kernel, robert.richter, catalin.marinas, sgoutham, linux-arm-kernel, linux-acpi, geethasowjanya.akula, devel, linu.cherian, Charles.Garcia-Tobin, robh, Geetha Sowjanya Hi Geetha, On Thu, Jun 22, 2017 at 05:35:38PM +0530, Geetha sowjanya wrote: > From: Geetha Sowjanya <geethasowjanya.akula@cavium.com> > > 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 <gakula@caviumnetworks.com> > --- > 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(-) Thanks, this looks much better. Two things to change below, and I'd like to see Lorenzo ack the iort changes. > 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. Please make it clear that: * 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 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", > + ACPI_EDGE_SENSITIVE, > + &res[num_res++]); > + > + if (smmu->sync_gsiv) > + acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync", > + ACPI_EDGE_SENSITIVE, > + &res[num_res++]); > + } > } > > static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node) > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c > index 2dea4a9..0f83f7d 100644 > --- a/drivers/iommu/arm-smmu-v3.c > +++ b/drivers/iommu/arm-smmu-v3.c > @@ -605,6 +605,7 @@ struct arm_smmu_device { > struct arm_smmu_priq priq; > > int gerr_irq; > + int combined_irq; > > unsigned long ias; /* IPA */ > unsigned long oas; /* PA */ > @@ -1314,6 +1315,29 @@ static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev) > return IRQ_HANDLED; > } > > +static irqreturn_t arm_smmu_combined_irq_thread(int irq, void *dev) > +{ > + struct arm_smmu_device *smmu = dev; > + > + arm_smmu_evtq_thread(irq, dev); > + if (smmu->features & ARM_SMMU_FEAT_PRI) > + arm_smmu_priq_thread(irq, dev); > + > + return IRQ_HANDLED; > +} > + > +static irqreturn_t arm_smmu_combined_irq_handler(int irq, void *dev) > +{ > + irqreturn_t ret; > + > + ret = arm_smmu_gerror_handler(irq, dev); > + if (ret == IRQ_NONE) { I don't think you can play that trick if the irq is an edge-triggered interrupt, since you could lose an interrupt that fired whilst we were in the handler. The easiest thing is to always run the gerror and cmdq_sync handlers, and then always return IRQ_WAKE_THREAD. Will ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 2017-06-22 18:22 ` Will Deacon @ 2017-06-23 6:21 ` Geetha Akula 0 siblings, 0 replies; 5+ messages in thread From: Geetha Akula @ 2017-06-23 6:21 UTC (permalink / raw) To: Will Deacon Cc: Geetha sowjanya, Robin Murphy, Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla, Linux IOMMU, Robert Moore, Lv Zheng, Rafael J. Wysocki, jcm, linux-kernel, Robert Richter, Catalin Marinas, Sunil Goutham, linux-arm-kernel, linux-acpi, devel, Linu Cherian, Charles Garcia-Tobin, Rob Herring, Geetha Sowjanya <geet> On Thu, Jun 22, 2017 at 11:52 PM, Will Deacon <will.deacon@arm.com> wrote: > Hi Geetha, > > On Thu, Jun 22, 2017 at 05:35:38PM +0530, Geetha sowjanya wrote: >> From: Geetha Sowjanya <geethasowjanya.akula@cavium.com> >> >> 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 <gakula@caviumnetworks.com> >> --- >> 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(-) > > Thanks, this looks much better. Two things to change below, and I'd like to > see Lorenzo ack the iort changes. Thanks Will. I have resend the patch with suggested changes. Geetha. > >> 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. > > Please make it clear that: > > * 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 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", >> + ACPI_EDGE_SENSITIVE, >> + &res[num_res++]); >> + >> + if (smmu->sync_gsiv) >> + acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync", >> + ACPI_EDGE_SENSITIVE, >> + &res[num_res++]); >> + } >> } >> >> static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node) >> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c >> index 2dea4a9..0f83f7d 100644 >> --- a/drivers/iommu/arm-smmu-v3.c >> +++ b/drivers/iommu/arm-smmu-v3.c >> @@ -605,6 +605,7 @@ struct arm_smmu_device { >> struct arm_smmu_priq priq; >> >> int gerr_irq; >> + int combined_irq; >> >> unsigned long ias; /* IPA */ >> unsigned long oas; /* PA */ >> @@ -1314,6 +1315,29 @@ static irqreturn_t arm_smmu_gerror_handler(int irq, void *dev) >> return IRQ_HANDLED; >> } >> >> +static irqreturn_t arm_smmu_combined_irq_thread(int irq, void *dev) >> +{ >> + struct arm_smmu_device *smmu = dev; >> + >> + arm_smmu_evtq_thread(irq, dev); >> + if (smmu->features & ARM_SMMU_FEAT_PRI) >> + arm_smmu_priq_thread(irq, dev); >> + >> + return IRQ_HANDLED; >> +} >> + >> +static irqreturn_t arm_smmu_combined_irq_handler(int irq, void *dev) >> +{ >> + irqreturn_t ret; >> + >> + ret = arm_smmu_gerror_handler(irq, dev); >> + if (ret == IRQ_NONE) { > > I don't think you can play that trick if the irq is an edge-triggered > interrupt, since you could lose an interrupt that fired whilst we were > in the handler. > > The easiest thing is to always run the gerror and cmdq_sync handlers, and > then always return IRQ_WAKE_THREAD. > > Will ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-06-23 11:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-23 5:58 [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Geetha sowjanya
2017-06-23 11:39 ` Lorenzo Pieralisi
-- strict thread matches above, loose matches on Subject: below --
2017-06-22 12:05 [PATCH v9 0/3] Cavium ThunderX2 SMMUv3 errata workarounds Geetha sowjanya
[not found] ` <1498133138-20244-1-git-send-email-gakula-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
2017-06-22 12:05 ` [PATCH v9 3/3] iommu/arm-smmu-v3: Add workaround for Cavium ThunderX2 erratum #126 Geetha sowjanya
2017-06-22 18:22 ` Will Deacon
2017-06-23 6:21 ` Geetha Akula
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).