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 <drivers/delay_timer.h>
11 #include <lib/mmio.h>
12 
13 /* SMMU poll number of retries */
14 #define SMMU_POLL_TIMEOUT_US	U(1000)
15 
smmuv3_poll(uintptr_t smmu_reg,uint32_t mask,uint32_t value)16 static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask,
17 				uint32_t value)
18 {
19 	uint32_t reg_val;
20 	uint64_t timeout;
21 
22 	/* Set 1ms timeout value */
23 	timeout = timeout_init_us(SMMU_POLL_TIMEOUT_US);
24 	do {
25 		reg_val = mmio_read_32(smmu_reg);
26 		if ((reg_val & mask) == value)
27 			return 0;
28 	} while (!timeout_elapsed(timeout));
29 
30 	ERROR("Timeout polling SMMUv3 register @%p\n", (void *)smmu_reg);
31 	ERROR("Read value 0x%x, expected 0x%x\n", reg_val,
32 		value == 0U ? reg_val & ~mask : reg_val | mask);
33 	return -1;
34 }
35 
36 /*
37  * Abort all incoming transactions in order to implement a default
38  * deny policy on reset.
39  */
smmuv3_security_init(uintptr_t smmu_base)40 int __init smmuv3_security_init(uintptr_t smmu_base)
41 {
42 	/* Attribute update has completed when SMMU_(S)_GBPA.Update bit is 0 */
43 	if (smmuv3_poll(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE, 0U) != 0U)
44 		return -1;
45 
46 	/*
47 	 * SMMU_(S)_CR0 resets to zero with all streams bypassing the SMMU,
48 	 * so just abort all incoming transactions.
49 	 */
50 	mmio_setbits_32(smmu_base + SMMU_GBPA,
51 			SMMU_GBPA_UPDATE | SMMU_GBPA_ABORT);
52 
53 	if (smmuv3_poll(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE, 0U) != 0U)
54 		return -1;
55 
56 	/* Check if the SMMU supports secure state */
57 	if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
58 				SMMU_S_IDR1_SECURE_IMPL) == 0U)
59 		return 0;
60 
61 	/* Abort all incoming secure transactions */
62 	if (smmuv3_poll(smmu_base + SMMU_S_GBPA, SMMU_S_GBPA_UPDATE, 0U) != 0U)
63 		return -1;
64 
65 	mmio_setbits_32(smmu_base + SMMU_S_GBPA,
66 			SMMU_S_GBPA_UPDATE | SMMU_S_GBPA_ABORT);
67 
68 	return smmuv3_poll(smmu_base + SMMU_S_GBPA, SMMU_S_GBPA_UPDATE, 0U);
69 }
70 
71 /*
72  * Initialize the SMMU by invalidating all secure caches and TLBs.
73  * Abort all incoming transactions in order to implement a default
74  * deny policy on reset
75  */
smmuv3_init(uintptr_t smmu_base)76 int __init smmuv3_init(uintptr_t smmu_base)
77 {
78 	/* Abort all incoming transactions */
79 	if (smmuv3_security_init(smmu_base) != 0)
80 		return -1;
81 
82 	/* Check if the SMMU supports secure state */
83 	if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
84 				SMMU_S_IDR1_SECURE_IMPL) == 0U)
85 		return 0;
86 	/*
87 	 * Initiate invalidation of secure caches and TLBs if the SMMU
88 	 * supports secure state. If not, it's implementation defined
89 	 * as to how SMMU_S_INIT register is accessed.
90 	 */
91 	mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
92 
93 	/* Wait for global invalidation operation to finish */
94 	return smmuv3_poll(smmu_base + SMMU_S_INIT,
95 				SMMU_S_INIT_INV_ALL, 0U);
96 }
97