diff options
author | Tirumalesh Chalamarla <tchalamarla@caviumnetworks.com> | 2016-02-23 13:19:00 -0500 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2016-05-03 13:23:00 -0400 |
commit | 4e3e9b6997b24383264031198bf8905b3746221e (patch) | |
tree | b9bebc338895a53bfa86682531794d74221f0ee9 | |
parent | f55532a0c0b8bb6148f4e07853b876ef73bc69ca (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.c | 23 |
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, |