blob: ab2eb2bedec78f2b24481a11d01f5dba701680a3 [file] [log] [blame]
Jeenu Viswambharan5c503042017-05-26 14:15:40 +01001/*
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +01002 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
Jeenu Viswambharan5c503042017-05-26 14:15:40 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +01007#include <common/debug.h>
Daniel Boulby844b4872018-09-18 13:36:39 +01008#include <cdefs.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009#include <drivers/arm/smmu_v3.h>
10#include <lib/mmio.h>
11
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010012/* SMMU poll number of retries */
13#define SMMU_POLL_RETRY 1000000
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010014
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010015static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask,
16 uint32_t value)
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010017{
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010018 uint32_t reg_val, retries = SMMU_POLL_RETRY;
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010019
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010020 do {
21 reg_val = mmio_read_32(smmu_reg);
22 if ((reg_val & mask) == value)
23 return 0;
24 } while (--retries != 0U);
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010025
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010026 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;
Antonio Nino Diazfeacba32018-08-21 16:12:29 +010030}
31
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010032/*
33 * Initialize the SMMU by invalidating all secure caches and TLBs.
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010034 * Abort all incoming transactions in order to implement a default
35 * deny policy on reset
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010036 */
Daniel Boulby844b4872018-09-18 13:36:39 +010037int __init smmuv3_init(uintptr_t smmu_base)
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010038{
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010039 /*
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 */
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010044 if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
45 SMMU_S_IDR1_SECURE_IMPL) != 0U) {
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010046
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010047 /* Initiate invalidation */
48 mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010049
Alexei Fedorov6b4a5f02019-04-26 12:07:07 +010050 /* Wait for global invalidation operation to finish */
51 return smmuv3_poll(smmu_base + SMMU_S_INIT,
52 SMMU_S_INIT_INV_ALL, 0U);
53 }
Jeenu Viswambharan5c503042017-05-26 14:15:40 +010054 return 0;
55}