11154586bSJeenu Viswambharan /* 2*6d5f0631SAntonio 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 71154586bSJeenu Viswambharan #include <mmio.h> 81154586bSJeenu Viswambharan #include <smmu_v3.h> 9*6d5f0631SAntonio Nino Diaz #include <stdbool.h> 101154586bSJeenu Viswambharan 111154586bSJeenu Viswambharan static inline uint32_t smmuv3_read_s_idr1(uintptr_t base) 121154586bSJeenu Viswambharan { 131154586bSJeenu Viswambharan return mmio_read_32(base + SMMU_S_IDR1); 141154586bSJeenu Viswambharan } 151154586bSJeenu Viswambharan 161154586bSJeenu Viswambharan static inline uint32_t smmuv3_read_s_init(uintptr_t base) 171154586bSJeenu Viswambharan { 181154586bSJeenu Viswambharan return mmio_read_32(base + SMMU_S_INIT); 191154586bSJeenu Viswambharan } 201154586bSJeenu Viswambharan 211154586bSJeenu Viswambharan static inline void smmuv3_write_s_init(uintptr_t base, uint32_t value) 221154586bSJeenu Viswambharan { 231154586bSJeenu Viswambharan mmio_write_32(base + SMMU_S_INIT, value); 241154586bSJeenu Viswambharan } 251154586bSJeenu Viswambharan 26*6d5f0631SAntonio Nino Diaz /* Test for pending invalidate */ 27*6d5f0631SAntonio Nino Diaz static inline bool smmuv3_inval_pending(uintptr_t base) 28*6d5f0631SAntonio Nino Diaz { 29*6d5f0631SAntonio Nino Diaz return (smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK) != 0U; 30*6d5f0631SAntonio Nino Diaz } 31*6d5f0631SAntonio Nino Diaz 321154586bSJeenu Viswambharan /* 331154586bSJeenu Viswambharan * Initialize the SMMU by invalidating all secure caches and TLBs. 341154586bSJeenu Viswambharan * 351154586bSJeenu Viswambharan * Returns 0 on success, and -1 on failure. 361154586bSJeenu Viswambharan */ 371154586bSJeenu Viswambharan int smmuv3_init(uintptr_t smmu_base) 381154586bSJeenu Viswambharan { 391154586bSJeenu Viswambharan uint32_t idr1_reg; 401154586bSJeenu Viswambharan 411154586bSJeenu Viswambharan /* 421154586bSJeenu Viswambharan * Invalidation of secure caches and TLBs is required only if the SMMU 431154586bSJeenu Viswambharan * supports secure state. If not, it's implementation defined as to how 441154586bSJeenu Viswambharan * SMMU_S_INIT register is accessed. 451154586bSJeenu Viswambharan */ 461154586bSJeenu Viswambharan idr1_reg = smmuv3_read_s_idr1(smmu_base); 47*6d5f0631SAntonio Nino Diaz if (((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) & 48*6d5f0631SAntonio Nino Diaz SMMU_S_IDR1_SECURE_IMPL_MASK) == 0U) { 491154586bSJeenu Viswambharan return -1; 501154586bSJeenu Viswambharan } 511154586bSJeenu Viswambharan 521154586bSJeenu Viswambharan /* Initiate invalidation, and wait for it to finish */ 531154586bSJeenu Viswambharan smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK); 54*6d5f0631SAntonio Nino Diaz while (smmuv3_inval_pending(smmu_base)) 551154586bSJeenu Viswambharan ; 561154586bSJeenu Viswambharan 571154586bSJeenu Viswambharan return 0; 581154586bSJeenu Viswambharan } 59