aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTirumalesh Chalamarla <tchalamarla@caviumnetworks.com>2016-02-23 13:19:00 -0500
committerWill Deacon <will.deacon@arm.com>2016-05-03 13:23:00 -0400
commit4e3e9b6997b24383264031198bf8905b3746221e (patch)
treeb9bebc338895a53bfa86682531794d74221f0ee9
parentf55532a0c0b8bb6148f4e07853b876ef73bc69ca (diff)
iommu/arm-smmu: Add support for 16 bit VMID
This patch adds support for 16-bit VMIDs on implementations of SMMUv2 that support it. Signed-off-by: Tirumalesh Chalamarla <tchalamarla@caviumnetworks.com> [will: commit messsage and comments] Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/iommu/arm-smmu.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 2409e3bd3df2..25e884a75f6b 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -94,6 +94,7 @@
94#define sCR0_VMIDPNE (1 << 11) 94#define sCR0_VMIDPNE (1 << 11)
95#define sCR0_PTM (1 << 12) 95#define sCR0_PTM (1 << 12)
96#define sCR0_FB (1 << 13) 96#define sCR0_FB (1 << 13)
97#define sCR0_VMID16EN (1 << 31)
97#define sCR0_BSU_SHIFT 14 98#define sCR0_BSU_SHIFT 14
98#define sCR0_BSU_MASK 0x3 99#define sCR0_BSU_MASK 0x3
99 100
@@ -141,6 +142,7 @@
141#define ID2_PTFS_4K (1 << 12) 142#define ID2_PTFS_4K (1 << 12)
142#define ID2_PTFS_16K (1 << 13) 143#define ID2_PTFS_16K (1 << 13)
143#define ID2_PTFS_64K (1 << 14) 144#define ID2_PTFS_64K (1 << 14)
145#define ID2_VMID16 (1 << 15)
144 146
145/* Global TLB invalidation */ 147/* Global TLB invalidation */
146#define ARM_SMMU_GR0_TLBIVMID 0x64 148#define ARM_SMMU_GR0_TLBIVMID 0x64
@@ -193,6 +195,8 @@
193#define ARM_SMMU_GR1_CBA2R(n) (0x800 + ((n) << 2)) 195#define ARM_SMMU_GR1_CBA2R(n) (0x800 + ((n) << 2))
194#define CBA2R_RW64_32BIT (0 << 0) 196#define CBA2R_RW64_32BIT (0 << 0)
195#define CBA2R_RW64_64BIT (1 << 0) 197#define CBA2R_RW64_64BIT (1 << 0)
198#define CBA2R_VMID_SHIFT 16
199#define CBA2R_VMID_MASK 0xffff
196 200
197/* Translation context bank */ 201/* Translation context bank */
198#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1)) 202#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1))
@@ -305,6 +309,7 @@ struct arm_smmu_device {
305#define ARM_SMMU_FEAT_TRANS_S2 (1 << 3) 309#define ARM_SMMU_FEAT_TRANS_S2 (1 << 3)
306#define ARM_SMMU_FEAT_TRANS_NESTED (1 << 4) 310#define ARM_SMMU_FEAT_TRANS_NESTED (1 << 4)
307#define ARM_SMMU_FEAT_TRANS_OPS (1 << 5) 311#define ARM_SMMU_FEAT_TRANS_OPS (1 << 5)
312#define ARM_SMMU_FEAT_VMID16 (1 << 6)
308 u32 features; 313 u32 features;
309 314
310#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0) 315#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
@@ -734,16 +739,15 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
734 cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); 739 cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
735 740
736 if (smmu->version > ARM_SMMU_V1) { 741 if (smmu->version > ARM_SMMU_V1) {
737 /*
738 * CBA2R.
739 * *Must* be initialised before CBAR thanks to VMID16
740 * architectural oversight affected some implementations.
741 */
742#ifdef CONFIG_64BIT 742#ifdef CONFIG_64BIT
743 reg = CBA2R_RW64_64BIT; 743 reg = CBA2R_RW64_64BIT;
744#else 744#else
745 reg = CBA2R_RW64_32BIT; 745 reg = CBA2R_RW64_32BIT;
746#endif 746#endif
747 /* 16-bit VMIDs live in CBA2R */
748 if (smmu->features & ARM_SMMU_FEAT_VMID16)
749 reg |= ARM_SMMU_CB_VMID(cfg) << CBA2R_VMID_SHIFT;
750
747 writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx)); 751 writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx));
748 } 752 }
749 753
@@ -759,7 +763,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
759 if (stage1) { 763 if (stage1) {
760 reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) | 764 reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
761 (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); 765 (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
762 } else { 766 } else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) {
767 /* 8-bit VMIDs live in CBAR */
763 reg |= ARM_SMMU_CB_VMID(cfg) << CBAR_VMID_SHIFT; 768 reg |= ARM_SMMU_CB_VMID(cfg) << CBAR_VMID_SHIFT;
764 } 769 }
765 writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx)); 770 writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx));
@@ -1529,6 +1534,9 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
1529 /* Don't upgrade barriers */ 1534 /* Don't upgrade barriers */
1530 reg &= ~(sCR0_BSU_MASK << sCR0_BSU_SHIFT); 1535 reg &= ~(sCR0_BSU_MASK << sCR0_BSU_SHIFT);
1531 1536
1537 if (smmu->features & ARM_SMMU_FEAT_VMID16)
1538 reg |= sCR0_VMID16EN;
1539
1532 /* Push the button */ 1540 /* Push the button */
1533 __arm_smmu_tlb_sync(smmu); 1541 __arm_smmu_tlb_sync(smmu);
1534 writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); 1542 writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
@@ -1679,6 +1687,9 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1679 size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK); 1687 size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
1680 smmu->pa_size = size; 1688 smmu->pa_size = size;
1681 1689
1690 if (id & ID2_VMID16)
1691 smmu->features |= ARM_SMMU_FEAT_VMID16;
1692
1682 /* 1693 /*
1683 * What the page table walker can address actually depends on which 1694 * What the page table walker can address actually depends on which
1684 * descriptor format is in use, but since a) we don't know that yet, 1695 * descriptor format is in use, but since a) we don't know that yet,