1 /*
2 * Copyright (c) 2023, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /* TF-A system header */
8 #include <common/debug.h>
9 #include <drivers/delay_timer.h>
10 #include <lib/mmio.h>
11 #include <lib/spinlock.h>
12
13 /* Vendor header */
14 #include "apusys.h"
15 #include "apusys_rv.h"
16 #include "apusys_rv_mbox_mpu.h"
17 #include "emi_mpu.h"
18
19 static spinlock_t apusys_rv_lock;
20
apusys_rv_mbox_mpu_init(void)21 void apusys_rv_mbox_mpu_init(void)
22 {
23 int i;
24
25 for (i = 0; i < APU_MBOX_NUM; i++) {
26 mmio_write_32(APU_MBOX_FUNC_CFG(i),
27 (MBOX_CTRL_LOCK |
28 (mbox_mpu_setting_tab[i].no_mpu << MBOX_NO_MPU_SHIFT)));
29 mmio_write_32(APU_MBOX_DOMAIN_CFG(i),
30 (MBOX_CTRL_LOCK |
31 (mbox_mpu_setting_tab[i].rx_ns << MBOX_RX_NS_SHIFT) |
32 (mbox_mpu_setting_tab[i].rx_domain << MBOX_RX_DOMAIN_SHIFT) |
33 (mbox_mpu_setting_tab[i].tx_ns << MBOX_TX_NS_SHIFT) |
34 (mbox_mpu_setting_tab[i].tx_domain << MBOX_TX_DOMAIN_SHIFT)));
35 }
36 }
37
apusys_kernel_apusys_rv_setup_reviser(void)38 int apusys_kernel_apusys_rv_setup_reviser(void)
39 {
40 static bool apusys_rv_setup_reviser_called;
41
42 spin_lock(&apusys_rv_lock);
43
44 if (apusys_rv_setup_reviser_called) {
45 WARN(MODULE_TAG "%s: already initialized\n", __func__);
46 spin_unlock(&apusys_rv_lock);
47 return -1;
48 }
49
50 apusys_rv_setup_reviser_called = true;
51
52 mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
53 mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
54
55 mmio_write_32(UP_IOMMU_CTRL, MMU_CTRL_LOCK | MMU_CTRL | MMU_EN);
56
57 mmio_write_32(UP_NORMAL_DOMAIN_NS,
58 (UP_NORMAL_DOMAIN << UP_DOMAIN_SHIFT) | (UP_NORMAL_NS << UP_NS_SHIFT));
59 mmio_write_32(UP_PRI_DOMAIN_NS,
60 (UP_PRI_DOMAIN << UP_DOMAIN_SHIFT) | (UP_PRI_NS << UP_NS_SHIFT));
61
62 mmio_write_32(UP_CORE0_VABASE0,
63 VLD | PARTIAL_ENABLE | (THREAD_NUM_PRI << THREAD_NUM_SHIFT));
64 mmio_write_32(UP_CORE0_MVABASE0, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
65
66 mmio_write_32(UP_CORE0_VABASE1,
67 VLD | PARTIAL_ENABLE | (THREAD_NUM_NORMAL << THREAD_NUM_SHIFT));
68 mmio_write_32(UP_CORE0_MVABASE1, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
69
70 spin_unlock(&apusys_rv_lock);
71
72 return 0;
73 }
74
apusys_kernel_apusys_rv_reset_mp(void)75 int apusys_kernel_apusys_rv_reset_mp(void)
76 {
77 static bool apusys_rv_reset_mp_called;
78
79 spin_lock(&apusys_rv_lock);
80
81 if (apusys_rv_reset_mp_called) {
82 WARN(MODULE_TAG "%s: already initialized\n", __func__);
83 spin_unlock(&apusys_rv_lock);
84 return -1;
85 }
86
87 apusys_rv_reset_mp_called = true;
88
89 mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST);
90
91 dsb();
92 udelay(RESET_DEALY_US);
93
94 mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN |
95 MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN |
96 MD32_SOFT_RSTN);
97
98 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
99 mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN);
100 mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN);
101
102 spin_unlock(&apusys_rv_lock);
103
104 return 0;
105 }
106
apusys_kernel_apusys_rv_setup_boot(void)107 int apusys_kernel_apusys_rv_setup_boot(void)
108 {
109 static bool apusys_rv_setup_boot_called;
110
111 spin_lock(&apusys_rv_lock);
112
113 if (apusys_rv_setup_boot_called) {
114 WARN(MODULE_TAG "%s: already initialized\n", __func__);
115 spin_unlock(&apusys_rv_lock);
116 return -1;
117 }
118
119 apusys_rv_setup_boot_called = true;
120
121 mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA);
122
123 mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) |
124 (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) |
125 (PREDEFINE_CACHE << PREDEF_4G_OFS));
126
127 spin_unlock(&apusys_rv_lock);
128 return 0;
129 }
130
apusys_kernel_apusys_rv_start_mp(void)131 int apusys_kernel_apusys_rv_start_mp(void)
132 {
133 static bool apusys_rv_start_mp_called;
134
135 spin_lock(&apusys_rv_lock);
136
137 if (apusys_rv_start_mp_called) {
138 WARN(MODULE_TAG "%s: already initialized\n", __func__);
139 spin_unlock(&apusys_rv_lock);
140 return -1;
141 }
142
143 apusys_rv_start_mp_called = true;
144
145 mmio_write_32(MD32_RUNSTALL, MD32_RUN);
146
147 spin_unlock(&apusys_rv_lock);
148
149 return 0;
150 }
151
watch_dog_is_timeout(void)152 static bool watch_dog_is_timeout(void)
153 {
154 if (mmio_read_32(WDT_INT) != WDT_INT_W1C) {
155 ERROR(MODULE_TAG "%s: WDT does not timeout\n", __func__);
156 return false;
157 }
158 return true;
159 }
160
apusys_kernel_apusys_rv_stop_mp(void)161 int apusys_kernel_apusys_rv_stop_mp(void)
162 {
163 static bool apusys_rv_stop_mp_called;
164
165 spin_lock(&apusys_rv_lock);
166
167 if (apusys_rv_stop_mp_called) {
168 WARN(MODULE_TAG "%s: already initialized\n", __func__);
169 spin_unlock(&apusys_rv_lock);
170 return -1;
171 }
172
173 if (watch_dog_is_timeout() == false) {
174 spin_unlock(&apusys_rv_lock);
175 return -1;
176 }
177
178 apusys_rv_stop_mp_called = true;
179
180 mmio_write_32(MD32_RUNSTALL, MD32_STALL);
181
182 spin_unlock(&apusys_rv_lock);
183
184 return 0;
185 }
186
apusys_kernel_apusys_rv_setup_sec_mem(void)187 int apusys_kernel_apusys_rv_setup_sec_mem(void)
188 {
189 static bool apusys_rv_setup_sec_mem_called;
190 int ret;
191
192 spin_lock(&apusys_rv_lock);
193
194 if (apusys_rv_setup_sec_mem_called) {
195 WARN(MODULE_TAG "%s: already initialized\n", __func__);
196 spin_unlock(&apusys_rv_lock);
197 return -1;
198 }
199
200 apusys_rv_setup_sec_mem_called = true;
201
202 ret = set_apu_emi_mpu_region();
203 if (ret != 0) {
204 ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__);
205 }
206
207 spin_unlock(&apusys_rv_lock);
208 return ret;
209 }
210
apusys_kernel_apusys_rv_disable_wdt_isr(void)211 int apusys_kernel_apusys_rv_disable_wdt_isr(void)
212 {
213 spin_lock(&apusys_rv_lock);
214 mmio_clrbits_32(WDT_CTRL0, WDT_EN);
215 spin_unlock(&apusys_rv_lock);
216
217 return 0;
218 }
219
apusys_kernel_apusys_rv_clear_wdt_isr(void)220 int apusys_kernel_apusys_rv_clear_wdt_isr(void)
221 {
222 spin_lock(&apusys_rv_lock);
223 mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN);
224 mmio_write_32(WDT_INT, WDT_INT_W1C);
225 spin_unlock(&apusys_rv_lock);
226
227 return 0;
228 }
229
apusys_kernel_apusys_rv_cg_gating(void)230 int apusys_kernel_apusys_rv_cg_gating(void)
231 {
232 spin_lock(&apusys_rv_lock);
233
234 if (watch_dog_is_timeout() == false) {
235 spin_unlock(&apusys_rv_lock);
236 return -1;
237 }
238
239 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS);
240 spin_unlock(&apusys_rv_lock);
241
242 return 0;
243 }
244
apusys_kernel_apusys_rv_cg_ungating(void)245 int apusys_kernel_apusys_rv_cg_ungating(void)
246 {
247 spin_lock(&apusys_rv_lock);
248
249 if (watch_dog_is_timeout() == false) {
250 spin_unlock(&apusys_rv_lock);
251 return -1;
252 }
253
254 mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
255 spin_unlock(&apusys_rv_lock);
256
257 return 0;
258 }
259