diff options
Diffstat (limited to 'drivers/arm/smmu/smmu_v3.c')
-rw-r--r-- | drivers/arm/smmu/smmu_v3.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c index a082a8107..de47febf6 100644 --- a/drivers/arm/smmu/smmu_v3.c +++ b/drivers/arm/smmu/smmu_v3.c @@ -13,7 +13,7 @@ /* SMMU poll number of retries */ #define SMMU_POLL_TIMEOUT_US U(1000) -static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask, +static int smmuv3_poll(uintptr_t smmu_reg, uint32_t mask, uint32_t value) { uint32_t reg_val; @@ -94,3 +94,45 @@ int __init smmuv3_init(uintptr_t smmu_base) return smmuv3_poll(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL, 0U); } + +int smmuv3_ns_set_abort_all(uintptr_t smmu_base) +{ + /* Attribute update has completed when SMMU_GBPA.Update bit is 0 */ + if (smmuv3_poll(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE, 0U) != 0U) + return -1; + + /* + * Set GBPA's ABORT bit. Other GBPA fields are presumably ignored then, so + * simply preserve their value. + */ + mmio_setbits_32(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE | SMMU_GBPA_ABORT); + if (smmuv3_poll(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE, 0U) != 0U) + return -1; + + /* Disable the SMMU to engage the GBPA fields previously configured. */ + mmio_clrbits_32(smmu_base + SMMU_CR0, SMMU_CR0_SMMUEN); + if (smmuv3_poll(smmu_base + SMMU_CR0ACK, SMMU_CR0_SMMUEN, 0U) != 0U) + return -1; + + return 0; +} + +int smmuv3_ns_set_bypass_all(uintptr_t smmu_base) +{ + /* Attribute update has completed when SMMU_GBPA.Update bit is 0 */ + if (smmuv3_poll(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE, 0U) != 0U) + return -1; + + /* Clear GBPA's ABORT bit. Other GBPA fields are preserved. */ + mmio_clrsetbits_32(smmu_base + SMMU_GBPA, + SMMU_GBPA_ABORT, SMMU_GBPA_UPDATE); + if (smmuv3_poll(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE, 0U) != 0U) + return -1; + + /* Disable the SMMU to engage the GBPA fields previously configured. */ + mmio_clrbits_32(smmu_base + SMMU_CR0, SMMU_CR0_SMMUEN); + if (smmuv3_poll(smmu_base + SMMU_CR0ACK, SMMU_CR0_SMMUEN, 0U) != 0U) + return -1; + + return 0; +} |