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