1 /* 2 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <cdefs.h> 8 #include <stdbool.h> 9 10 #include <drivers/arm/smmu_v3.h> 11 #include <lib/mmio.h> 12 13 static inline uint32_t __init smmuv3_read_s_idr1(uintptr_t base) 14 { 15 return mmio_read_32(base + SMMU_S_IDR1); 16 } 17 18 static inline uint32_t __init smmuv3_read_s_init(uintptr_t base) 19 { 20 return mmio_read_32(base + SMMU_S_INIT); 21 } 22 23 static inline void __init smmuv3_write_s_init(uintptr_t base, uint32_t value) 24 { 25 mmio_write_32(base + SMMU_S_INIT, value); 26 } 27 28 /* Test for pending invalidate */ 29 static inline bool smmuv3_inval_pending(uintptr_t base) 30 { 31 return (smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK) != 0U; 32 } 33 34 /* 35 * Initialize the SMMU by invalidating all secure caches and TLBs. 36 * 37 * Returns 0 on success, and -1 on failure. 38 */ 39 int __init smmuv3_init(uintptr_t smmu_base) 40 { 41 uint32_t idr1_reg; 42 43 /* 44 * Invalidation of secure caches and TLBs is required only if the SMMU 45 * supports secure state. If not, it's implementation defined as to how 46 * SMMU_S_INIT register is accessed. 47 */ 48 idr1_reg = smmuv3_read_s_idr1(smmu_base); 49 if (((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) & 50 SMMU_S_IDR1_SECURE_IMPL_MASK) == 0U) { 51 return -1; 52 } 53 54 /* Initiate invalidation, and wait for it to finish */ 55 smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK); 56 while (smmuv3_inval_pending(smmu_base)) 57 ; 58 59 return 0; 60 } 61