aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2018-03-26 08:35:14 -0400
committerWill Deacon <will.deacon@arm.com>2018-03-27 09:12:06 -0400
commit6619c9138533597dc0ff52155d263f14e8578ca2 (patch)
treedc5c5dad0a9696b3e0c0ae8a4e2811a3e62859c0 /drivers/iommu
parent6c89928ff7a0f7b4ebc2ac1acab9f99d5f50ed75 (diff)
iommu/arm-smmu-v3: Support 52-bit physical address
Implement SMMUv3.1 support for 52-bit physical addresses. Since a 52-bit OAS implies 64KB translation granule support, permitting level 1 block entries there is simple, and the rest is just extending address fields. Tested-by: Nate Watterson <nwatters@codeaurora.org> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/arm-smmu-v3.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index ae6049bddd73..b73a5950eb65 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -91,6 +91,7 @@
91#define IDR5_OAS_42_BIT 3 91#define IDR5_OAS_42_BIT 3
92#define IDR5_OAS_44_BIT 4 92#define IDR5_OAS_44_BIT 4
93#define IDR5_OAS_48_BIT 5 93#define IDR5_OAS_48_BIT 5
94#define IDR5_OAS_52_BIT 6
94 95
95#define ARM_SMMU_CR0 0x20 96#define ARM_SMMU_CR0 0x20
96#define CR0_CMDQEN (1 << 3) 97#define CR0_CMDQEN (1 << 3)
@@ -147,7 +148,7 @@
147 148
148#define ARM_SMMU_STRTAB_BASE 0x80 149#define ARM_SMMU_STRTAB_BASE 0x80
149#define STRTAB_BASE_RA (1UL << 62) 150#define STRTAB_BASE_RA (1UL << 62)
150#define STRTAB_BASE_ADDR_MASK GENMASK_ULL(47, 6) 151#define STRTAB_BASE_ADDR_MASK GENMASK_ULL(51, 6)
151 152
152#define ARM_SMMU_STRTAB_BASE_CFG 0x88 153#define ARM_SMMU_STRTAB_BASE_CFG 0x88
153#define STRTAB_BASE_CFG_FMT GENMASK(17, 16) 154#define STRTAB_BASE_CFG_FMT GENMASK(17, 16)
@@ -175,7 +176,7 @@
175#define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc 176#define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc
176 177
177/* Common MSI config fields */ 178/* Common MSI config fields */
178#define MSI_CFG0_ADDR_MASK GENMASK_ULL(47, 2) 179#define MSI_CFG0_ADDR_MASK GENMASK_ULL(51, 2)
179#define MSI_CFG2_SH GENMASK(5, 4) 180#define MSI_CFG2_SH GENMASK(5, 4)
180#define MSI_CFG2_MEMATTR GENMASK(3, 0) 181#define MSI_CFG2_MEMATTR GENMASK(3, 0)
181 182
@@ -194,7 +195,7 @@
194 Q_IDX(q, p) * (q)->ent_dwords) 195 Q_IDX(q, p) * (q)->ent_dwords)
195 196
196#define Q_BASE_RWA (1UL << 62) 197#define Q_BASE_RWA (1UL << 62)
197#define Q_BASE_ADDR_MASK GENMASK_ULL(47, 5) 198#define Q_BASE_ADDR_MASK GENMASK_ULL(51, 5)
198#define Q_BASE_LOG2SIZE GENMASK(4, 0) 199#define Q_BASE_LOG2SIZE GENMASK(4, 0)
199 200
200/* 201/*
@@ -209,7 +210,7 @@
209 210
210#define STRTAB_L1_DESC_DWORDS 1 211#define STRTAB_L1_DESC_DWORDS 1
211#define STRTAB_L1_DESC_SPAN GENMASK_ULL(4, 0) 212#define STRTAB_L1_DESC_SPAN GENMASK_ULL(4, 0)
212#define STRTAB_L1_DESC_L2PTR_MASK GENMASK_ULL(47, 6) 213#define STRTAB_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 6)
213 214
214#define STRTAB_STE_DWORDS 8 215#define STRTAB_STE_DWORDS 8
215#define STRTAB_STE_0_V (1UL << 0) 216#define STRTAB_STE_0_V (1UL << 0)
@@ -221,7 +222,7 @@
221 222
222#define STRTAB_STE_0_S1FMT GENMASK_ULL(5, 4) 223#define STRTAB_STE_0_S1FMT GENMASK_ULL(5, 4)
223#define STRTAB_STE_0_S1FMT_LINEAR 0 224#define STRTAB_STE_0_S1FMT_LINEAR 0
224#define STRTAB_STE_0_S1CTXPTR_MASK GENMASK_ULL(47, 6) 225#define STRTAB_STE_0_S1CTXPTR_MASK GENMASK_ULL(51, 6)
225#define STRTAB_STE_0_S1CDMAX GENMASK_ULL(63, 59) 226#define STRTAB_STE_0_S1CDMAX GENMASK_ULL(63, 59)
226 227
227#define STRTAB_STE_1_S1C_CACHE_NC 0UL 228#define STRTAB_STE_1_S1C_CACHE_NC 0UL
@@ -253,7 +254,7 @@
253#define STRTAB_STE_2_S2PTW (1UL << 54) 254#define STRTAB_STE_2_S2PTW (1UL << 54)
254#define STRTAB_STE_2_S2R (1UL << 58) 255#define STRTAB_STE_2_S2R (1UL << 58)
255 256
256#define STRTAB_STE_3_S2TTB_MASK GENMASK_ULL(47, 4) 257#define STRTAB_STE_3_S2TTB_MASK GENMASK_ULL(51, 4)
257 258
258/* Context descriptor (stage-1 only) */ 259/* Context descriptor (stage-1 only) */
259#define CTXDESC_CD_DWORDS 8 260#define CTXDESC_CD_DWORDS 8
@@ -287,7 +288,7 @@
287#define CTXDESC_CD_0_ASET (1UL << 47) 288#define CTXDESC_CD_0_ASET (1UL << 47)
288#define CTXDESC_CD_0_ASID GENMASK_ULL(63, 48) 289#define CTXDESC_CD_0_ASID GENMASK_ULL(63, 48)
289 290
290#define CTXDESC_CD_1_TTB0_MASK GENMASK_ULL(47, 4) 291#define CTXDESC_CD_1_TTB0_MASK GENMASK_ULL(51, 4)
291 292
292/* Convert between AArch64 (CPU) TCR format and SMMU CD format */ 293/* Convert between AArch64 (CPU) TCR format and SMMU CD format */
293#define ARM_SMMU_TCR2CD(tcr, fld) FIELD_PREP(CTXDESC_CD_0_TCR_##fld, \ 294#define ARM_SMMU_TCR2CD(tcr, fld) FIELD_PREP(CTXDESC_CD_0_TCR_##fld, \
@@ -317,7 +318,7 @@
317#define CMDQ_TLBI_0_ASID GENMASK_ULL(63, 48) 318#define CMDQ_TLBI_0_ASID GENMASK_ULL(63, 48)
318#define CMDQ_TLBI_1_LEAF (1UL << 0) 319#define CMDQ_TLBI_1_LEAF (1UL << 0)
319#define CMDQ_TLBI_1_VA_MASK GENMASK_ULL(63, 12) 320#define CMDQ_TLBI_1_VA_MASK GENMASK_ULL(63, 12)
320#define CMDQ_TLBI_1_IPA_MASK GENMASK_ULL(47, 12) 321#define CMDQ_TLBI_1_IPA_MASK GENMASK_ULL(51, 12)
321 322
322#define CMDQ_PRI_0_SSID GENMASK_ULL(31, 12) 323#define CMDQ_PRI_0_SSID GENMASK_ULL(31, 12)
323#define CMDQ_PRI_0_SID GENMASK_ULL(63, 32) 324#define CMDQ_PRI_0_SID GENMASK_ULL(63, 32)
@@ -331,7 +332,7 @@
331#define CMDQ_SYNC_0_MSH GENMASK_ULL(23, 22) 332#define CMDQ_SYNC_0_MSH GENMASK_ULL(23, 22)
332#define CMDQ_SYNC_0_MSIATTR GENMASK_ULL(27, 24) 333#define CMDQ_SYNC_0_MSIATTR GENMASK_ULL(27, 24)
333#define CMDQ_SYNC_0_MSIDATA GENMASK_ULL(63, 32) 334#define CMDQ_SYNC_0_MSIDATA GENMASK_ULL(63, 32)
334#define CMDQ_SYNC_1_MSIADDR_MASK GENMASK_ULL(47, 2) 335#define CMDQ_SYNC_1_MSIADDR_MASK GENMASK_ULL(51, 2)
335 336
336/* Event queue */ 337/* Event queue */
337#define EVTQ_ENT_DWORDS 4 338#define EVTQ_ENT_DWORDS 4
@@ -1622,7 +1623,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
1622 return -ENOMEM; 1623 return -ENOMEM;
1623 1624
1624 domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; 1625 domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
1625 domain->geometry.aperture_end = (1UL << ias) - 1; 1626 domain->geometry.aperture_end = (1UL << pgtbl_cfg.ias) - 1;
1626 domain->geometry.force_aperture = true; 1627 domain->geometry.force_aperture = true;
1627 1628
1628 ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg); 1629 ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg);
@@ -2644,11 +2645,6 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
2644 if (reg & IDR5_GRAN4K) 2645 if (reg & IDR5_GRAN4K)
2645 smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G; 2646 smmu->pgsize_bitmap |= SZ_4K | SZ_2M | SZ_1G;
2646 2647
2647 if (arm_smmu_ops.pgsize_bitmap == -1UL)
2648 arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap;
2649 else
2650 arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap;
2651
2652 /* Output address size */ 2648 /* Output address size */
2653 switch (FIELD_GET(IDR5_OAS, reg)) { 2649 switch (FIELD_GET(IDR5_OAS, reg)) {
2654 case IDR5_OAS_32_BIT: 2650 case IDR5_OAS_32_BIT:
@@ -2666,6 +2662,10 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
2666 case IDR5_OAS_44_BIT: 2662 case IDR5_OAS_44_BIT:
2667 smmu->oas = 44; 2663 smmu->oas = 44;
2668 break; 2664 break;
2665 case IDR5_OAS_52_BIT:
2666 smmu->oas = 52;
2667 smmu->pgsize_bitmap |= 1ULL << 42; /* 4TB */
2668 break;
2669 default: 2669 default:
2670 dev_info(smmu->dev, 2670 dev_info(smmu->dev,
2671 "unknown output address size. Truncating to 48-bit\n"); 2671 "unknown output address size. Truncating to 48-bit\n");
@@ -2674,6 +2674,11 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
2674 smmu->oas = 48; 2674 smmu->oas = 48;
2675 } 2675 }
2676 2676
2677 if (arm_smmu_ops.pgsize_bitmap == -1UL)
2678 arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap;
2679 else
2680 arm_smmu_ops.pgsize_bitmap |= smmu->pgsize_bitmap;
2681
2677 /* Set the DMA mask for our table walker */ 2682 /* Set the DMA mask for our table walker */
2678 if (dma_set_mask_and_coherent(smmu->dev, DMA_BIT_MASK(smmu->oas))) 2683 if (dma_set_mask_and_coherent(smmu->dev, DMA_BIT_MASK(smmu->oas)))
2679 dev_warn(smmu->dev, 2684 dev_warn(smmu->dev,