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