aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/arm-smmu.c
diff options
context:
space:
mode:
authorRobin Murphy <Robin.Murphy@arm.com>2014-08-28 12:51:59 -0400
committerWill Deacon <will.deacon@arm.com>2014-09-16 14:15:21 -0400
commit093604033361928f7f355b4d1766d0179ae747fb (patch)
tree91192007b6599c617df941af559c2d5390e385e5 /drivers/iommu/arm-smmu.c
parent28d6007ba2fd344164e01ef300af7f621e9e6b0d (diff)
iommu/arm-smmu: fix architecture version detection
The SMMU driver was relying on a quirk of MMU-500 r2px to identify the correct architecture version. Since this does not apply to other implementations, make the architecture version for each supported implementation explicit. While we're at it, remove the unnecessary #ifdef since the dependencies for CONFIG_ARM_SMMU already imply CONFIG_OF. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r--drivers/iommu/arm-smmu.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 27fd3d7ba886..c00f483e106f 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -331,6 +331,11 @@ module_param_named(force_stage, force_stage, int, S_IRUGO | S_IWUSR);
331MODULE_PARM_DESC(force_stage, 331MODULE_PARM_DESC(force_stage,
332 "Force SMMU mappings to be installed at a particular stage of translation. A value of '1' or '2' forces the corresponding stage. All other values are ignored (i.e. no stage is forced). Note that selecting a specific stage will disable support for nested translation."); 332 "Force SMMU mappings to be installed at a particular stage of translation. A value of '1' or '2' forces the corresponding stage. All other values are ignored (i.e. no stage is forced). Note that selecting a specific stage will disable support for nested translation.");
333 333
334enum arm_smmu_arch_version {
335 ARM_SMMU_V1 = 1,
336 ARM_SMMU_V2,
337};
338
334struct arm_smmu_smr { 339struct arm_smmu_smr {
335 u8 idx; 340 u8 idx;
336 u16 mask; 341 u16 mask;
@@ -365,7 +370,7 @@ struct arm_smmu_device {
365 370
366#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0) 371#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
367 u32 options; 372 u32 options;
368 int version; 373 enum arm_smmu_arch_version version;
369 374
370 u32 num_context_banks; 375 u32 num_context_banks;
371 u32 num_s2_context_banks; 376 u32 num_s2_context_banks;
@@ -737,7 +742,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
737 742
738 /* CBAR */ 743 /* CBAR */
739 reg = cfg->cbar; 744 reg = cfg->cbar;
740 if (smmu->version == 1) 745 if (smmu->version == ARM_SMMU_V1)
741 reg |= cfg->irptndx << CBAR_IRPTNDX_SHIFT; 746 reg |= cfg->irptndx << CBAR_IRPTNDX_SHIFT;
742 747
743 /* 748 /*
@@ -752,7 +757,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
752 } 757 }
753 writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx)); 758 writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx));
754 759
755 if (smmu->version > 1) { 760 if (smmu->version > ARM_SMMU_V1) {
756 /* CBA2R */ 761 /* CBA2R */
757#ifdef CONFIG_64BIT 762#ifdef CONFIG_64BIT
758 reg = CBA2R_RW64_64BIT; 763 reg = CBA2R_RW64_64BIT;
@@ -825,7 +830,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
825 * TTBCR 830 * TTBCR
826 * We use long descriptor, with inner-shareable WBWA tables in TTBR0. 831 * We use long descriptor, with inner-shareable WBWA tables in TTBR0.
827 */ 832 */
828 if (smmu->version > 1) { 833 if (smmu->version > ARM_SMMU_V1) {
829 if (PAGE_SIZE == SZ_4K) 834 if (PAGE_SIZE == SZ_4K)
830 reg = TTBCR_TG0_4K; 835 reg = TTBCR_TG0_4K;
831 else 836 else
@@ -922,7 +927,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
922 goto out_unlock; 927 goto out_unlock;
923 928
924 cfg->cbndx = ret; 929 cfg->cbndx = ret;
925 if (smmu->version == 1) { 930 if (smmu->version == ARM_SMMU_V1) {
926 cfg->irptndx = atomic_inc_return(&smmu->irptndx); 931 cfg->irptndx = atomic_inc_return(&smmu->irptndx);
927 cfg->irptndx %= smmu->num_context_irqs; 932 cfg->irptndx %= smmu->num_context_irqs;
928 } else { 933 } else {
@@ -1733,10 +1738,6 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1733 u32 id; 1738 u32 id;
1734 1739
1735 dev_notice(smmu->dev, "probing hardware configuration...\n"); 1740 dev_notice(smmu->dev, "probing hardware configuration...\n");
1736
1737 /* Primecell ID */
1738 id = readl_relaxed(gr0_base + ARM_SMMU_GR0_PIDR2);
1739 smmu->version = ((id >> PIDR2_ARCH_SHIFT) & PIDR2_ARCH_MASK) + 1;
1740 dev_notice(smmu->dev, "SMMUv%d with:\n", smmu->version); 1741 dev_notice(smmu->dev, "SMMUv%d with:\n", smmu->version);
1741 1742
1742 /* ID0 */ 1743 /* ID0 */
@@ -1853,7 +1854,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1853 size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK); 1854 size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
1854 smmu->s2_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, size); 1855 smmu->s2_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, size);
1855 1856
1856 if (smmu->version == 1) { 1857 if (smmu->version == ARM_SMMU_V1) {
1857 smmu->s1_input_size = 32; 1858 smmu->s1_input_size = 32;
1858 } else { 1859 } else {
1859#ifdef CONFIG_64BIT 1860#ifdef CONFIG_64BIT
@@ -1884,8 +1885,18 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1884 return 0; 1885 return 0;
1885} 1886}
1886 1887
1888static struct of_device_id arm_smmu_of_match[] = {
1889 { .compatible = "arm,smmu-v1", .data = (void *)ARM_SMMU_V1 },
1890 { .compatible = "arm,smmu-v2", .data = (void *)ARM_SMMU_V2 },
1891 { .compatible = "arm,mmu-400", .data = (void *)ARM_SMMU_V1 },
1892 { .compatible = "arm,mmu-500", .data = (void *)ARM_SMMU_V2 },
1893 { },
1894};
1895MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
1896
1887static int arm_smmu_device_dt_probe(struct platform_device *pdev) 1897static int arm_smmu_device_dt_probe(struct platform_device *pdev)
1888{ 1898{
1899 const struct of_device_id *of_id;
1889 struct resource *res; 1900 struct resource *res;
1890 struct arm_smmu_device *smmu; 1901 struct arm_smmu_device *smmu;
1891 struct device *dev = &pdev->dev; 1902 struct device *dev = &pdev->dev;
@@ -1900,6 +1911,9 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
1900 } 1911 }
1901 smmu->dev = dev; 1912 smmu->dev = dev;
1902 1913
1914 of_id = of_match_node(arm_smmu_of_match, dev->of_node);
1915 smmu->version = (enum arm_smmu_arch_version)of_id->data;
1916
1903 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1917 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1904 smmu->base = devm_ioremap_resource(dev, res); 1918 smmu->base = devm_ioremap_resource(dev, res);
1905 if (IS_ERR(smmu->base)) 1919 if (IS_ERR(smmu->base))
@@ -1964,7 +1978,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
1964 1978
1965 parse_driver_options(smmu); 1979 parse_driver_options(smmu);
1966 1980
1967 if (smmu->version > 1 && 1981 if (smmu->version > ARM_SMMU_V1 &&
1968 smmu->num_context_banks != smmu->num_context_irqs) { 1982 smmu->num_context_banks != smmu->num_context_irqs) {
1969 dev_err(dev, 1983 dev_err(dev,
1970 "found only %d context interrupt(s) but %d required\n", 1984 "found only %d context interrupt(s) but %d required\n",
@@ -2045,17 +2059,6 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
2045 return 0; 2059 return 0;
2046} 2060}
2047 2061
2048#ifdef CONFIG_OF
2049static struct of_device_id arm_smmu_of_match[] = {
2050 { .compatible = "arm,smmu-v1", },
2051 { .compatible = "arm,smmu-v2", },
2052 { .compatible = "arm,mmu-400", },
2053 { .compatible = "arm,mmu-500", },
2054 { },
2055};
2056MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
2057#endif
2058
2059static struct platform_driver arm_smmu_driver = { 2062static struct platform_driver arm_smmu_driver = {
2060 .driver = { 2063 .driver = {
2061 .owner = THIS_MODULE, 2064 .owner = THIS_MODULE,