1 /* 2 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include <cdefs.h> 9 #include <drivers/arm/smmu_v3.h> 10 #include <lib/mmio.h> 11 12 /* SMMU poll number of retries */ 13 #define SMMU_POLL_RETRY 1000000 14 15 static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask, 16 uint32_t value) 17 { 18 uint32_t reg_val, retries = SMMU_POLL_RETRY; 19 20 do { 21 reg_val = mmio_read_32(smmu_reg); 22 if ((reg_val & mask) == value) 23 return 0; 24 } while (--retries != 0U); 25 26 ERROR("Failed to poll SMMUv3 register @%p\n", (void *)smmu_reg); 27 ERROR("Read value 0x%x, expected 0x%x\n", reg_val, 28 value == 0U ? reg_val & ~mask : reg_val | mask); 29 return -1; 30 } 31 32 /* 33 * Initialize the SMMU by invalidating all secure caches and TLBs. 34 * Abort all incoming transactions in order to implement a default 35 * deny policy on reset 36 */ 37 int __init smmuv3_init(uintptr_t smmu_base) 38 { 39 /* 40 * Invalidation of secure caches and TLBs is required only if the SMMU 41 * supports secure state. If not, it's implementation defined as to how 42 * SMMU_S_INIT register is accessed. 43 */ 44 if ((mmio_read_32(smmu_base + SMMU_S_IDR1) & 45 SMMU_S_IDR1_SECURE_IMPL) != 0U) { 46 47 /* Initiate invalidation */ 48 mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL); 49 50 /* Wait for global invalidation operation to finish */ 51 return smmuv3_poll(smmu_base + SMMU_S_INIT, 52 SMMU_S_INIT_INV_ALL, 0U); 53 } 54 return 0; 55 } 56