aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Makarov <aleksey.makarov@linaro.org>2017-01-19 09:36:36 -0500
committerWill Deacon <will.deacon@arm.com>2017-01-26 13:16:57 -0500
commitdc0eaa4e19a7db1cb046b3979945536fdc914517 (patch)
tree3fb525e11e5b3d227befaa667d9b7ec5312bd880
parent65e251a4634c5644efca6f7e15803f0962d8943d (diff)
iommu/arm-smmu: Support for Extended Stream ID (16 bit)
It is the time we have the real 16-bit Stream ID user, which is the ThunderX. Its IO topology uses 1:1 map for Requester ID to Stream ID translation for each root complex which allows to get full 16-bit Stream ID. Firmware assigns bus IDs that are greater than 128 (0x80) to some buses under PEM (external PCIe interface). Eventually SMMU drops devices on that buses because their Stream ID is out of range: pci 0006:90:00.0: stream ID 0x9000 out of range for SMMU (0x7fff) To fix above issue enable the Extended Stream ID optional feature when available. Reviewed-by: Tomasz Nowicki <tomasz.nowicki@caviumnetworks.com> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org> Tested-by: Tomasz Nowicki <tomasz.nowicki@caviumnetworks.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/iommu/arm-smmu.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a60cded8a6ed..93b9177d4dfd 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -24,6 +24,7 @@
24 * - v7/v8 long-descriptor format 24 * - v7/v8 long-descriptor format
25 * - Non-secure access to the SMMU 25 * - Non-secure access to the SMMU
26 * - Context fault reporting 26 * - Context fault reporting
27 * - Extended Stream ID (16 bit)
27 */ 28 */
28 29
29#define pr_fmt(fmt) "arm-smmu: " fmt 30#define pr_fmt(fmt) "arm-smmu: " fmt
@@ -87,6 +88,7 @@
87#define sCR0_CLIENTPD (1 << 0) 88#define sCR0_CLIENTPD (1 << 0)
88#define sCR0_GFRE (1 << 1) 89#define sCR0_GFRE (1 << 1)
89#define sCR0_GFIE (1 << 2) 90#define sCR0_GFIE (1 << 2)
91#define sCR0_EXIDENABLE (1 << 3)
90#define sCR0_GCFGFRE (1 << 4) 92#define sCR0_GCFGFRE (1 << 4)
91#define sCR0_GCFGFIE (1 << 5) 93#define sCR0_GCFGFIE (1 << 5)
92#define sCR0_USFCFG (1 << 10) 94#define sCR0_USFCFG (1 << 10)
@@ -126,6 +128,7 @@
126#define ID0_NUMIRPT_MASK 0xff 128#define ID0_NUMIRPT_MASK 0xff
127#define ID0_NUMSIDB_SHIFT 9 129#define ID0_NUMSIDB_SHIFT 9
128#define ID0_NUMSIDB_MASK 0xf 130#define ID0_NUMSIDB_MASK 0xf
131#define ID0_EXIDS (1 << 8)
129#define ID0_NUMSMRG_SHIFT 0 132#define ID0_NUMSMRG_SHIFT 0
130#define ID0_NUMSMRG_MASK 0xff 133#define ID0_NUMSMRG_MASK 0xff
131 134
@@ -169,6 +172,7 @@
169#define ARM_SMMU_GR0_S2CR(n) (0xc00 + ((n) << 2)) 172#define ARM_SMMU_GR0_S2CR(n) (0xc00 + ((n) << 2))
170#define S2CR_CBNDX_SHIFT 0 173#define S2CR_CBNDX_SHIFT 0
171#define S2CR_CBNDX_MASK 0xff 174#define S2CR_CBNDX_MASK 0xff
175#define S2CR_EXIDVALID (1 << 10)
172#define S2CR_TYPE_SHIFT 16 176#define S2CR_TYPE_SHIFT 16
173#define S2CR_TYPE_MASK 0x3 177#define S2CR_TYPE_MASK 0x3
174enum arm_smmu_s2cr_type { 178enum arm_smmu_s2cr_type {
@@ -351,6 +355,7 @@ struct arm_smmu_device {
351#define ARM_SMMU_FEAT_FMT_AARCH64_64K (1 << 9) 355#define ARM_SMMU_FEAT_FMT_AARCH64_64K (1 << 9)
352#define ARM_SMMU_FEAT_FMT_AARCH32_L (1 << 10) 356#define ARM_SMMU_FEAT_FMT_AARCH32_L (1 << 10)
353#define ARM_SMMU_FEAT_FMT_AARCH32_S (1 << 11) 357#define ARM_SMMU_FEAT_FMT_AARCH32_S (1 << 11)
358#define ARM_SMMU_FEAT_EXIDS (1 << 12)
354 u32 features; 359 u32 features;
355 360
356#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0) 361#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
@@ -1048,7 +1053,7 @@ static void arm_smmu_write_smr(struct arm_smmu_device *smmu, int idx)
1048 struct arm_smmu_smr *smr = smmu->smrs + idx; 1053 struct arm_smmu_smr *smr = smmu->smrs + idx;
1049 u32 reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT; 1054 u32 reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT;
1050 1055
1051 if (smr->valid) 1056 if (!(smmu->features & ARM_SMMU_FEAT_EXIDS) && smr->valid)
1052 reg |= SMR_VALID; 1057 reg |= SMR_VALID;
1053 writel_relaxed(reg, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_SMR(idx)); 1058 writel_relaxed(reg, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_SMR(idx));
1054} 1059}
@@ -1060,6 +1065,9 @@ static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
1060 (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT | 1065 (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
1061 (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT; 1066 (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT;
1062 1067
1068 if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
1069 smmu->smrs[idx].valid)
1070 reg |= S2CR_EXIDVALID;
1063 writel_relaxed(reg, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_S2CR(idx)); 1071 writel_relaxed(reg, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_S2CR(idx));
1064} 1072}
1065 1073
@@ -1070,6 +1078,34 @@ static void arm_smmu_write_sme(struct arm_smmu_device *smmu, int idx)
1070 arm_smmu_write_smr(smmu, idx); 1078 arm_smmu_write_smr(smmu, idx);
1071} 1079}
1072 1080
1081/*
1082 * The width of SMR's mask field depends on sCR0_EXIDENABLE, so this function
1083 * should be called after sCR0 is written.
1084 */
1085static void arm_smmu_test_smr_masks(struct arm_smmu_device *smmu)
1086{
1087 void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
1088 u32 smr;
1089
1090 if (!smmu->smrs)
1091 return;
1092
1093 /*
1094 * SMR.ID bits may not be preserved if the corresponding MASK
1095 * bits are set, so check each one separately. We can reject
1096 * masters later if they try to claim IDs outside these masks.
1097 */
1098 smr = smmu->streamid_mask << SMR_ID_SHIFT;
1099 writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
1100 smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
1101 smmu->streamid_mask = smr >> SMR_ID_SHIFT;
1102
1103 smr = smmu->streamid_mask << SMR_MASK_SHIFT;
1104 writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
1105 smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
1106 smmu->smr_mask_mask = smr >> SMR_MASK_SHIFT;
1107}
1108
1073static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask) 1109static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
1074{ 1110{
1075 struct arm_smmu_smr *smrs = smmu->smrs; 1111 struct arm_smmu_smr *smrs = smmu->smrs;
@@ -1648,6 +1684,9 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
1648 if (smmu->features & ARM_SMMU_FEAT_VMID16) 1684 if (smmu->features & ARM_SMMU_FEAT_VMID16)
1649 reg |= sCR0_VMID16EN; 1685 reg |= sCR0_VMID16EN;
1650 1686
1687 if (smmu->features & ARM_SMMU_FEAT_EXIDS)
1688 reg |= sCR0_EXIDENABLE;
1689
1651 /* Push the button */ 1690 /* Push the button */
1652 __arm_smmu_tlb_sync(smmu); 1691 __arm_smmu_tlb_sync(smmu);
1653 writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); 1692 writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
@@ -1735,11 +1774,14 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1735 "\t(IDR0.CTTW overridden by FW configuration)\n"); 1774 "\t(IDR0.CTTW overridden by FW configuration)\n");
1736 1775
1737 /* Max. number of entries we have for stream matching/indexing */ 1776 /* Max. number of entries we have for stream matching/indexing */
1738 size = 1 << ((id >> ID0_NUMSIDB_SHIFT) & ID0_NUMSIDB_MASK); 1777 if (smmu->version == ARM_SMMU_V2 && id & ID0_EXIDS) {
1778 smmu->features |= ARM_SMMU_FEAT_EXIDS;
1779 size = 1 << 16;
1780 } else {
1781 size = 1 << ((id >> ID0_NUMSIDB_SHIFT) & ID0_NUMSIDB_MASK);
1782 }
1739 smmu->streamid_mask = size - 1; 1783 smmu->streamid_mask = size - 1;
1740 if (id & ID0_SMS) { 1784 if (id & ID0_SMS) {
1741 u32 smr;
1742
1743 smmu->features |= ARM_SMMU_FEAT_STREAM_MATCH; 1785 smmu->features |= ARM_SMMU_FEAT_STREAM_MATCH;
1744 size = (id >> ID0_NUMSMRG_SHIFT) & ID0_NUMSMRG_MASK; 1786 size = (id >> ID0_NUMSMRG_SHIFT) & ID0_NUMSMRG_MASK;
1745 if (size == 0) { 1787 if (size == 0) {
@@ -1748,21 +1790,6 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1748 return -ENODEV; 1790 return -ENODEV;
1749 } 1791 }
1750 1792
1751 /*
1752 * SMR.ID bits may not be preserved if the corresponding MASK
1753 * bits are set, so check each one separately. We can reject
1754 * masters later if they try to claim IDs outside these masks.
1755 */
1756 smr = smmu->streamid_mask << SMR_ID_SHIFT;
1757 writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
1758 smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
1759 smmu->streamid_mask = smr >> SMR_ID_SHIFT;
1760
1761 smr = smmu->streamid_mask << SMR_MASK_SHIFT;
1762 writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
1763 smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
1764 smmu->smr_mask_mask = smr >> SMR_MASK_SHIFT;
1765
1766 /* Zero-initialised to mark as invalid */ 1793 /* Zero-initialised to mark as invalid */
1767 smmu->smrs = devm_kcalloc(smmu->dev, size, sizeof(*smmu->smrs), 1794 smmu->smrs = devm_kcalloc(smmu->dev, size, sizeof(*smmu->smrs),
1768 GFP_KERNEL); 1795 GFP_KERNEL);
@@ -1770,8 +1797,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1770 return -ENOMEM; 1797 return -ENOMEM;
1771 1798
1772 dev_notice(smmu->dev, 1799 dev_notice(smmu->dev,
1773 "\tstream matching with %lu register groups, mask 0x%x", 1800 "\tstream matching with %lu register groups", size);
1774 size, smmu->smr_mask_mask);
1775 } 1801 }
1776 /* s2cr->type == 0 means translation, so initialise explicitly */ 1802 /* s2cr->type == 0 means translation, so initialise explicitly */
1777 smmu->s2crs = devm_kmalloc_array(smmu->dev, size, sizeof(*smmu->s2crs), 1803 smmu->s2crs = devm_kmalloc_array(smmu->dev, size, sizeof(*smmu->s2crs),
@@ -2094,6 +2120,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
2094 iommu_register_instance(dev->fwnode, &arm_smmu_ops); 2120 iommu_register_instance(dev->fwnode, &arm_smmu_ops);
2095 platform_set_drvdata(pdev, smmu); 2121 platform_set_drvdata(pdev, smmu);
2096 arm_smmu_device_reset(smmu); 2122 arm_smmu_device_reset(smmu);
2123 arm_smmu_test_smr_masks(smmu);
2097 2124
2098 /* Oh, for a proper bus abstraction */ 2125 /* Oh, for a proper bus abstraction */
2099 if (!iommu_present(&platform_bus_type)) 2126 if (!iommu_present(&platform_bus_type))