diff options
author | Peng Fan <van.freenix@gmail.com> | 2016-05-03 09:50:30 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2016-05-03 13:23:04 -0400 |
commit | 3ca3712a42f9e632eb41da94ca4eab4f1fb06fcb (patch) | |
tree | 091456c97c6d9c926df6bf5bf6800a59533f9c35 /drivers/iommu/arm-smmu.c | |
parent | b7862e3559f9ab4aaa258dcb846986601a7ca0b8 (diff) |
iommu/arm-smmu: Clear cache lock bit of ACR
According MMU-500r2 TRM, section 3.7.1 Auxiliary Control registers,
You can modify ACTLR only when the ACR.CACHE_LOCK bit is 0.
So before clearing ARM_MMU500_ACTLR_CPRE of each context bank,
need clear CACHE_LOCK bit of ACR register first.
Since CACHE_LOCK bit is only present in MMU-500r2 onwards,
need to check the major number of IDR7.
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Peng Fan <van.freenix@gmail.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.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 72dea314f9a1..2fb9c33a4a08 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -98,6 +98,9 @@ | |||
98 | #define sCR0_BSU_SHIFT 14 | 98 | #define sCR0_BSU_SHIFT 14 |
99 | #define sCR0_BSU_MASK 0x3 | 99 | #define sCR0_BSU_MASK 0x3 |
100 | 100 | ||
101 | /* Auxiliary Configuration register */ | ||
102 | #define ARM_SMMU_GR0_sACR 0x10 | ||
103 | |||
101 | /* Identification registers */ | 104 | /* Identification registers */ |
102 | #define ARM_SMMU_GR0_ID0 0x20 | 105 | #define ARM_SMMU_GR0_ID0 0x20 |
103 | #define ARM_SMMU_GR0_ID1 0x24 | 106 | #define ARM_SMMU_GR0_ID1 0x24 |
@@ -146,6 +149,9 @@ | |||
146 | #define ID2_PTFS_64K (1 << 14) | 149 | #define ID2_PTFS_64K (1 << 14) |
147 | #define ID2_VMID16 (1 << 15) | 150 | #define ID2_VMID16 (1 << 15) |
148 | 151 | ||
152 | #define ID7_MAJOR_SHIFT 4 | ||
153 | #define ID7_MAJOR_MASK 0xf | ||
154 | |||
149 | /* Global TLB invalidation */ | 155 | /* Global TLB invalidation */ |
150 | #define ARM_SMMU_GR0_TLBIVMID 0x64 | 156 | #define ARM_SMMU_GR0_TLBIVMID 0x64 |
151 | #define ARM_SMMU_GR0_TLBIALLNSNH 0x68 | 157 | #define ARM_SMMU_GR0_TLBIALLNSNH 0x68 |
@@ -237,6 +243,8 @@ | |||
237 | 243 | ||
238 | #define ARM_MMU500_ACTLR_CPRE (1 << 1) | 244 | #define ARM_MMU500_ACTLR_CPRE (1 << 1) |
239 | 245 | ||
246 | #define ARM_MMU500_ACR_CACHE_LOCK (1 << 26) | ||
247 | |||
240 | #define CB_PAR_F (1 << 0) | 248 | #define CB_PAR_F (1 << 0) |
241 | 249 | ||
242 | #define ATSR_ACTIVE (1 << 0) | 250 | #define ATSR_ACTIVE (1 << 0) |
@@ -1531,7 +1539,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) | |||
1531 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 1539 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); |
1532 | void __iomem *cb_base; | 1540 | void __iomem *cb_base; |
1533 | int i = 0; | 1541 | int i = 0; |
1534 | u32 reg; | 1542 | u32 reg, major; |
1535 | 1543 | ||
1536 | /* clear global FSR */ | 1544 | /* clear global FSR */ |
1537 | reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR); | 1545 | reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR); |
@@ -1544,6 +1552,19 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) | |||
1544 | writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_S2CR(i)); | 1552 | writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_S2CR(i)); |
1545 | } | 1553 | } |
1546 | 1554 | ||
1555 | /* | ||
1556 | * Before clearing ARM_MMU500_ACTLR_CPRE, need to | ||
1557 | * clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK | ||
1558 | * bit is only present in MMU-500r2 onwards. | ||
1559 | */ | ||
1560 | reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7); | ||
1561 | major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK; | ||
1562 | if ((smmu->model == ARM_MMU500) && (major >= 2)) { | ||
1563 | reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sACR); | ||
1564 | reg &= ~ARM_MMU500_ACR_CACHE_LOCK; | ||
1565 | writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR); | ||
1566 | } | ||
1567 | |||
1547 | /* Make sure all context banks are disabled and clear CB_FSR */ | 1568 | /* Make sure all context banks are disabled and clear CB_FSR */ |
1548 | for (i = 0; i < smmu->num_context_banks; ++i) { | 1569 | for (i = 0; i < smmu->num_context_banks; ++i) { |
1549 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, i); | 1570 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, i); |