11154586bSJeenu Viswambharan /* 26d5f0631SAntonio Nino Diaz * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. 31154586bSJeenu Viswambharan * 41154586bSJeenu Viswambharan * SPDX-License-Identifier: BSD-3-Clause 51154586bSJeenu Viswambharan */ 61154586bSJeenu Viswambharan 7*c9263e62SDaniel Boulby #include <cdefs.h> 81154586bSJeenu Viswambharan #include <mmio.h> 91154586bSJeenu Viswambharan #include <smmu_v3.h> 106d5f0631SAntonio Nino Diaz #include <stdbool.h> 111154586bSJeenu Viswambharan 12*c9263e62SDaniel Boulby static inline uint32_t __init smmuv3_read_s_idr1(uintptr_t base) 131154586bSJeenu Viswambharan { 141154586bSJeenu Viswambharan return mmio_read_32(base + SMMU_S_IDR1); 151154586bSJeenu Viswambharan } 161154586bSJeenu Viswambharan 17*c9263e62SDaniel Boulby static inline uint32_t __init smmuv3_read_s_init(uintptr_t base) 181154586bSJeenu Viswambharan { 191154586bSJeenu Viswambharan return mmio_read_32(base + SMMU_S_INIT); 201154586bSJeenu Viswambharan } 211154586bSJeenu Viswambharan 22*c9263e62SDaniel Boulby static inline void __init smmuv3_write_s_init(uintptr_t base, uint32_t value) 231154586bSJeenu Viswambharan { 241154586bSJeenu Viswambharan mmio_write_32(base + SMMU_S_INIT, value); 251154586bSJeenu Viswambharan } 261154586bSJeenu Viswambharan 276d5f0631SAntonio Nino Diaz /* Test for pending invalidate */ 286d5f0631SAntonio Nino Diaz static inline bool smmuv3_inval_pending(uintptr_t base) 296d5f0631SAntonio Nino Diaz { 306d5f0631SAntonio Nino Diaz return (smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK) != 0U; 316d5f0631SAntonio Nino Diaz } 326d5f0631SAntonio Nino Diaz 331154586bSJeenu Viswambharan /* 341154586bSJeenu Viswambharan * Initialize the SMMU by invalidating all secure caches and TLBs. 351154586bSJeenu Viswambharan * 361154586bSJeenu Viswambharan * Returns 0 on success, and -1 on failure. 371154586bSJeenu Viswambharan */ 38*c9263e62SDaniel Boulby int __init smmuv3_init(uintptr_t smmu_base) 391154586bSJeenu Viswambharan { 401154586bSJeenu Viswambharan uint32_t idr1_reg; 411154586bSJeenu Viswambharan 421154586bSJeenu Viswambharan /* 431154586bSJeenu Viswambharan * Invalidation of secure caches and TLBs is required only if the SMMU 441154586bSJeenu Viswambharan * supports secure state. If not, it's implementation defined as to how 451154586bSJeenu Viswambharan * SMMU_S_INIT register is accessed. 461154586bSJeenu Viswambharan */ 471154586bSJeenu Viswambharan idr1_reg = smmuv3_read_s_idr1(smmu_base); 486d5f0631SAntonio Nino Diaz if (((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) & 496d5f0631SAntonio Nino Diaz SMMU_S_IDR1_SECURE_IMPL_MASK) == 0U) { 501154586bSJeenu Viswambharan return -1; 511154586bSJeenu Viswambharan } 521154586bSJeenu Viswambharan 531154586bSJeenu Viswambharan /* Initiate invalidation, and wait for it to finish */ 541154586bSJeenu Viswambharan smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK); 556d5f0631SAntonio Nino Diaz while (smmuv3_inval_pending(smmu_base)) 561154586bSJeenu Viswambharan ; 571154586bSJeenu Viswambharan 581154586bSJeenu Viswambharan return 0; 591154586bSJeenu Viswambharan } 60