Skip to content

Commit

Permalink
Merge tag 'arm-smmu-updates' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/will/linux into arm/smmu

Arm SMMU updates for 5.9

- Support for SMMU-500 implementation in Marvell Armada-AP806 SoC

- Support for SMMU-500 implementation in NVIDIA Tegra194 SoC

- DT compatible string updates

- Remove unused IOMMU_SYS_CACHE_ONLY flag
  • Loading branch information
Joerg Roedel committed Jul 22, 2020
2 parents 9ebcfad + aa7ec73 commit ee79e5f
Show file tree
Hide file tree
Showing 11 changed files with 403 additions and 30 deletions.
3 changes: 3 additions & 0 deletions Documentation/arm64/silicon-errata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ stable kernels.
| Cavium | ThunderX2 Core | #219 | CAVIUM_TX2_ERRATUM_219 |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
| Marvell | ARM-MMU-500 | #582743 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
Expand Down
31 changes: 30 additions & 1 deletion Documentation/devicetree/bindings/iommu/arm,smmu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,18 @@ properties:
- enum:
- qcom,sc7180-smmu-500
- qcom,sdm845-smmu-500
- qcom,sm8150-smmu-500
- qcom,sm8250-smmu-500
- const: arm,mmu-500
- description: Marvell SoCs implementing "arm,mmu-500"
items:
- const: marvell,ap806-smmu-500
- const: arm,mmu-500
- description: NVIDIA SoCs that program two ARM MMU-500s identically
items:
- enum:
- nvidia,tegra194-smmu
- const: nvidia,smmu-500
- items:
- const: arm,mmu-500
- const: arm,smmu-v2
Expand All @@ -55,7 +66,8 @@ properties:
- cavium,smmu-v2

reg:
maxItems: 1
minItems: 1
maxItems: 2

'#global-interrupts':
description: The number of global interrupts exposed by the device.
Expand Down Expand Up @@ -138,6 +150,23 @@ required:

additionalProperties: false

allOf:
- if:
properties:
compatible:
contains:
enum:
- nvidia,tegra194-smmu
then:
properties:
reg:
minItems: 2
maxItems: 2
else:
properties:
reg:
maxItems: 1

examples:
- |+
/* SMMU with stream matching or stream indexing */
Expand Down
2 changes: 2 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -16810,8 +16810,10 @@ F: drivers/i2c/busses/i2c-tegra.c

TEGRA IOMMU DRIVERS
M: Thierry Reding <thierry.reding@gmail.com>
R: Krishna Reddy <vdumpa@nvidia.com>
L: linux-tegra@vger.kernel.org
S: Supported
F: drivers/iommu/arm-smmu-nvidia.c
F: drivers/iommu/tegra*

TEGRA KBC DRIVER
Expand Down
2 changes: 1 addition & 1 deletion drivers/iommu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ obj-$(CONFIG_AMD_IOMMU) += amd/iommu.o amd/init.o amd/quirks.o
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd/debugfs.o
obj-$(CONFIG_AMD_IOMMU_V2) += amd/iommu_v2.o
obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o arm-smmu-qcom.o
obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
obj-$(CONFIG_DMAR_TABLE) += intel/dmar.o
obj-$(CONFIG_INTEL_IOMMU) += intel/iommu.o intel/pasid.o
Expand Down
60 changes: 55 additions & 5 deletions drivers/iommu/arm-smmu-impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,57 @@ static const struct arm_smmu_impl arm_mmu500_impl = {
.reset = arm_mmu500_reset,
};

static u64 mrvl_mmu500_readq(struct arm_smmu_device *smmu, int page, int off)
{
/*
* Marvell Armada-AP806 erratum #582743.
* Split all the readq to double readl
*/
return hi_lo_readq_relaxed(arm_smmu_page(smmu, page) + off);
}

static void mrvl_mmu500_writeq(struct arm_smmu_device *smmu, int page, int off,
u64 val)
{
/*
* Marvell Armada-AP806 erratum #582743.
* Split all the writeq to double writel
*/
hi_lo_writeq_relaxed(val, arm_smmu_page(smmu, page) + off);
}

static int mrvl_mmu500_cfg_probe(struct arm_smmu_device *smmu)
{

/*
* Armada-AP806 erratum #582743.
* Hide the SMMU_IDR2.PTFSv8 fields to sidestep the AArch64
* formats altogether and allow using 32 bits access on the
* interconnect.
*/
smmu->features &= ~(ARM_SMMU_FEAT_FMT_AARCH64_4K |
ARM_SMMU_FEAT_FMT_AARCH64_16K |
ARM_SMMU_FEAT_FMT_AARCH64_64K);

return 0;
}

static const struct arm_smmu_impl mrvl_mmu500_impl = {
.read_reg64 = mrvl_mmu500_readq,
.write_reg64 = mrvl_mmu500_writeq,
.cfg_probe = mrvl_mmu500_cfg_probe,
.reset = arm_mmu500_reset,
};


struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
{
const struct device_node *np = smmu->dev->of_node;

/*
* We will inevitably have to combine model-specific implementation
* quirks with platform-specific integration quirks, but everything
* we currently support happens to work out as straightforward
* mutually-exclusive assignments.
* Set the impl for model-specific implementation quirks first,
* such that platform integration quirks can pick it up and
* inherit from it if necessary.
*/
switch (smmu->model) {
case ARM_MMU500:
Expand All @@ -168,12 +209,21 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
break;
}

/* This is implicitly MMU-400 */
if (of_property_read_bool(np, "calxeda,smmu-secure-config-access"))
smmu->impl = &calxeda_impl;

if (of_device_is_compatible(np, "nvidia,tegra194-smmu"))
return nvidia_smmu_impl_init(smmu);

if (of_device_is_compatible(np, "qcom,sdm845-smmu-500") ||
of_device_is_compatible(np, "qcom,sc7180-smmu-500"))
of_device_is_compatible(np, "qcom,sc7180-smmu-500") ||
of_device_is_compatible(np, "qcom,sm8150-smmu-500") ||
of_device_is_compatible(np, "qcom,sm8250-smmu-500"))
return qcom_smmu_impl_init(smmu);

if (of_device_is_compatible(np, "marvell,ap806-smmu-500"))
smmu->impl = &mrvl_mmu500_impl;

return smmu;
}
Loading

0 comments on commit ee79e5f

Please sign in to comment.