xref: /rk3399_ARM-atf/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c (revision 7ed4d67c6351e61dd5500a0887e4d5e85b8ab764)
1 /*
2  * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <errno.h>
8 
9 /* TF-A system header */
10 #include <common/debug.h>
11 #include <drivers/delay_timer.h>
12 #include <lib/mmio.h>
13 #include <lib/spinlock.h>
14 
15 /* Vendor header */
16 #include "apusys.h"
17 #include "apusys_rv.h"
18 #include "apusys_rv_mbox_mpu.h"
19 #include "apusys_rv_pwr_ctrl.h"
20 #include "apusys_rv_sec_info.h"
21 #ifdef CONFIG_MTK_APUSYS_SEC_CTRL
22 #include "apusys_security_ctrl_perm.h"
23 #endif
24 #include "apusys_security_ctrl_plat.h"
25 #include <mtk_mmap_pool.h>
26 #include <mtk_sip_svc.h>
27 
28 #ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
29 #include "apusys_ammu.h"
30 #endif
31 
32 static spinlock_t apusys_rv_lock;
33 
34 void apusys_rv_mbox_mpu_init(void)
35 {
36 	int i;
37 
38 	for (i = 0; i < APU_MBOX_NUM; i++) {
39 		mmio_write_32(APU_MBOX_FUNC_CFG(i),
40 			      (MBOX_CTRL_LOCK |
41 			       (mbox_mpu_setting_tab[i].no_mpu << MBOX_NO_MPU_SHIFT)));
42 		mmio_write_32(APU_MBOX_DOMAIN_CFG(i),
43 			      (MBOX_CTRL_LOCK |
44 			       (mbox_mpu_setting_tab[i].rx_ns << MBOX_RX_NS_SHIFT) |
45 			       (mbox_mpu_setting_tab[i].rx_domain << MBOX_RX_DOMAIN_SHIFT) |
46 			       (mbox_mpu_setting_tab[i].tx_ns << MBOX_TX_NS_SHIFT) |
47 			       (mbox_mpu_setting_tab[i].tx_domain << MBOX_TX_DOMAIN_SHIFT)));
48 	}
49 }
50 
51 int apusys_kernel_apusys_rv_setup_reviser(void)
52 {
53 	spin_lock(&apusys_rv_lock);
54 
55 	mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
56 	mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
57 
58 	mmio_write_32(UP_IOMMU_CTRL, MMU_CTRL_LOCK | MMU_CTRL | MMU_EN);
59 
60 	mmio_write_32(UP_NORMAL_DOMAIN_NS,
61 		      (UP_NORMAL_DOMAIN << UP_DOMAIN_SHIFT) | (UP_NORMAL_NS << UP_NS_SHIFT));
62 	mmio_write_32(UP_PRI_DOMAIN_NS,
63 		      (UP_PRI_DOMAIN << UP_DOMAIN_SHIFT) | (UP_PRI_NS << UP_NS_SHIFT));
64 
65 	mmio_write_32(UP_CORE0_VABASE0,
66 		      VLD | PARTIAL_ENABLE | (THREAD_NUM_PRI << THREAD_NUM_SHIFT));
67 	mmio_write_32(UP_CORE0_MVABASE0, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
68 
69 	mmio_write_32(UP_CORE0_VABASE1,
70 		      VLD | PARTIAL_ENABLE | (THREAD_NUM_NORMAL << THREAD_NUM_SHIFT));
71 	mmio_write_32(UP_CORE0_MVABASE1, VASIZE_1MB | (APU_SEC_FW_IOVA >> MVA_34BIT_SHIFT));
72 
73 	spin_unlock(&apusys_rv_lock);
74 
75 	return 0;
76 }
77 
78 int apusys_kernel_apusys_rv_reset_mp(void)
79 {
80 	spin_lock(&apusys_rv_lock);
81 
82 	mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST);
83 
84 	dsb();
85 	udelay(RESET_DEALY_US);
86 
87 	mmio_write_32(MD32_SYS_CTRL, MD32_G2B_CG_EN | MD32_DBG_EN | MD32_DM_AWUSER_IOMMU_EN |
88 		      MD32_DM_ARUSER_IOMMU_EN | MD32_PM_AWUSER_IOMMU_EN | MD32_PM_ARUSER_IOMMU_EN |
89 		      MD32_SOFT_RSTN);
90 
91 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
92 	mmio_write_32(UP_WAKE_HOST_MASK0, WDT_IRQ_EN);
93 	mmio_write_32(UP_WAKE_HOST_MASK1, MBOX0_IRQ_EN | MBOX1_IRQ_EN | MBOX2_IRQ_EN);
94 
95 	spin_unlock(&apusys_rv_lock);
96 
97 	return 0;
98 }
99 
100 int apusys_kernel_apusys_rv_setup_boot(void)
101 {
102 	spin_lock(&apusys_rv_lock);
103 
104 	mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA);
105 
106 	mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) |
107 		      (PREDEFINE_CACHE << PREDEF_2G_OFS) | (PREDEFINE_CACHE << PREDEF_3G_OFS) |
108 		      (PREDEFINE_CACHE << PREDEF_4G_OFS));
109 
110 	apusys_infra_dcm_setup();
111 
112 	spin_unlock(&apusys_rv_lock);
113 	return 0;
114 }
115 
116 int apusys_kernel_apusys_rv_start_mp(void)
117 {
118 	spin_lock(&apusys_rv_lock);
119 	mmio_write_32(MD32_RUNSTALL, MD32_RUN);
120 	spin_unlock(&apusys_rv_lock);
121 
122 	return 0;
123 }
124 
125 static int hw_sema2_release(uint32_t timeout)
126 {
127 #ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
128 	int ret;
129 
130 	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 0, timeout, 0);
131 	if (ret) {
132 		ERROR("%s: HW semaphore release timeout\n", __func__);
133 	}
134 
135 	return ret;
136 #else
137 	return 0;
138 #endif
139 }
140 
141 static int hw_sema2_acquire(uint32_t timeout)
142 {
143 #ifdef CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT
144 	int ret;
145 
146 	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_USER, 1, timeout, 0);
147 	if (ret) {
148 		ERROR("%s: HW semaphore acquire timeout\n", __func__);
149 	}
150 
151 	return ret;
152 #else
153 	return 0;
154 #endif
155 }
156 
157 int apusys_kernel_apusys_rv_stop_mp(void)
158 {
159 	int ret;
160 
161 	ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
162 	if (ret)
163 		return ret;
164 
165 	spin_lock(&apusys_rv_lock);
166 	mmio_write_32(MD32_RUNSTALL, MD32_STALL);
167 	spin_unlock(&apusys_rv_lock);
168 
169 	ret = hw_sema2_release(HW_SEM_TIMEOUT);
170 
171 	return ret;
172 }
173 
174 int apusys_kernel_apusys_rv_setup_sec_mem(void)
175 {
176 	int ret = 0;
177 
178 	spin_lock(&apusys_rv_lock);
179 
180 	ret = apusys_plat_setup_sec_mem();
181 	if (ret != 0)
182 		ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__);
183 
184 	spin_unlock(&apusys_rv_lock);
185 	return ret;
186 }
187 
188 int apusys_kernel_apusys_rv_disable_wdt_isr(void)
189 {
190 	int ret;
191 
192 	ret = hw_sema2_acquire(0);
193 	if (ret)
194 		return ret;
195 
196 	spin_lock(&apusys_rv_lock);
197 	mmio_clrbits_32(WDT_CTRL0, WDT_EN);
198 	spin_unlock(&apusys_rv_lock);
199 
200 	ret = hw_sema2_release(0);
201 
202 	return ret;
203 }
204 
205 int apusys_kernel_apusys_rv_clear_wdt_isr(void)
206 {
207 	int ret;
208 
209 	ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
210 	if (ret)
211 		return ret;
212 
213 	spin_lock(&apusys_rv_lock);
214 	mmio_clrbits_32(UP_INT_EN2, DBG_APB_EN);
215 	mmio_write_32(WDT_INT, WDT_INT_W1C);
216 	spin_unlock(&apusys_rv_lock);
217 
218 	ret = hw_sema2_release(HW_SEM_TIMEOUT);
219 
220 	return ret;
221 }
222 
223 int apusys_kernel_apusys_rv_cg_gating(void)
224 {
225 	int ret;
226 
227 	ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
228 	if (ret)
229 		return ret;
230 
231 	spin_lock(&apusys_rv_lock);
232 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS);
233 	spin_unlock(&apusys_rv_lock);
234 
235 	ret = hw_sema2_release(HW_SEM_TIMEOUT);
236 
237 	return ret;
238 }
239 
240 int apusys_kernel_apusys_rv_cg_ungating(void)
241 {
242 	int ret;
243 
244 	ret = hw_sema2_acquire(HW_SEM_TIMEOUT);
245 	if (ret)
246 		return ret;
247 
248 	spin_lock(&apusys_rv_lock);
249 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
250 	spin_unlock(&apusys_rv_lock);
251 
252 	ret = hw_sema2_release(HW_SEM_TIMEOUT);
253 
254 	return ret;
255 }
256 
257 int apusys_kernel_apusys_rv_setup_apummu(void)
258 {
259 	spin_lock(&apusys_rv_lock);
260 
261 #ifdef CONFIG_MTK_APUSYS_SEC_CTRL
262 	sec_set_rv_dns();
263 #endif
264 
265 #ifdef CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT
266 	uint32_t apummu_tcm_sz_select = 0;
267 
268 	if (APU_MD32_TCM_SZ <= 0x20000)
269 		apummu_tcm_sz_select = APUMMU_PAGE_LEN_128KB;
270 	else if (APU_MD32_TCM_SZ <= 0x40000)
271 		apummu_tcm_sz_select = APUMMU_PAGE_LEN_256KB;
272 	else if (APU_MD32_TCM_SZ <= 0x80000)
273 		apummu_tcm_sz_select = APUMMU_PAGE_LEN_512KB;
274 	else if (APU_MD32_TCM_SZ <= 0x100000)
275 		apummu_tcm_sz_select = APUMMU_PAGE_LEN_1MB;
276 	else {
277 		ERROR("%s: APU_MD32_TCM_SZ = 0x%x > 1MB", __func__, APU_MD32_TCM_SZ);
278 		spin_unlock(&apusys_rv_lock);
279 		return -EINVAL;
280 	}
281 
282 	INFO("%s: apummu_tcm_sz_select = %u\n", __func__, apummu_tcm_sz_select);
283 	rv_boot(APU_SEC_FW_IOVA, 0, APUMMU_PAGE_LEN_1MB,
284 		APU_MD32_TCM, apummu_tcm_sz_select);
285 #endif
286 
287 	spin_unlock(&apusys_rv_lock);
288 	return 0;
289 }
290 
291 int apusys_kernel_apusys_rv_pwr_ctrl(enum APU_PWR_OP op)
292 {
293 	return apusys_rv_pwr_ctrl(op);
294 }
295 
296 #ifdef CONFIG_MTK_APUSYS_LOGTOP_SUPPORT
297 int apusys_kernel_apusys_logtop_reg_dump(uint32_t op, struct smccc_res *smccc_ret)
298 {
299 	int ret = 0;
300 	uint8_t smc_op;
301 	uint32_t reg_addr[MAX_SMC_OP_NUM];
302 	uint32_t i;
303 
304 	if (op == 0) {
305 		ERROR("%s empty op = 0x%08x\n", MODULE_TAG, op);
306 		return -EINVAL;
307 	}
308 
309 	for (i = 0; i < MAX_SMC_OP_NUM; i++) {
310 		smc_op = (op >> (LOGTOP_OP_SHIFT * i)) & LOGTOP_OP_MASK;
311 		switch (smc_op) {
312 		case SMC_OP_APU_LOG_BUF_NULL:
313 			reg_addr[i] = 0x0;
314 			break;
315 		case SMC_OP_APU_LOG_BUF_T_SIZE:
316 			reg_addr[i] = APU_LOG_BUF_T_SIZE;
317 			break;
318 		case SMC_OP_APU_LOG_BUF_W_PTR:
319 			reg_addr[i] = APU_LOG_BUF_W_PTR;
320 			break;
321 		case SMC_OP_APU_LOG_BUF_R_PTR:
322 			reg_addr[i] = APU_LOG_BUF_R_PTR;
323 			break;
324 		case SMC_OP_APU_LOG_BUF_CON:
325 			reg_addr[i] = APU_LOGTOP_CON;
326 			break;
327 		default:
328 			ERROR("%s unknown op = 0x%08x\n", MODULE_TAG, smc_op);
329 			return -EINVAL;
330 		}
331 	}
332 
333 	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
334 	if (ret)
335 		return ret;
336 
337 	for (i = 0; i < MAX_SMC_OP_NUM; i++) {
338 		if (reg_addr[i] == 0)
339 			continue;
340 
341 		switch (i) {
342 		case 0:
343 			smccc_ret->a1 = mmio_read_32(reg_addr[i]);
344 			break;
345 		case 1:
346 			smccc_ret->a2 = mmio_read_32(reg_addr[i]);
347 			break;
348 		case 2:
349 			smccc_ret->a3 = mmio_read_32(reg_addr[i]);
350 			break;
351 		}
352 	}
353 
354 	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
355 	if (ret)
356 		ERROR("%s(%d): sem release timeout\n", __func__, op);
357 
358 	return ret;
359 }
360 
361 static int apusys_kernel_apusys_logtop_reg_rw(uint32_t op, uint32_t write_val,
362 					      bool w1c, struct smccc_res *smccc_ret)
363 {
364 	int ret = 0;
365 	uint32_t reg_addr = 0, reg_val = 0;
366 
367 	switch (op) {
368 	case SMC_OP_APU_LOG_BUF_R_PTR:
369 		reg_addr = APU_LOG_BUF_R_PTR;
370 		break;
371 	case SMC_OP_APU_LOG_BUF_CON:
372 		reg_addr = APU_LOGTOP_CON;
373 		break;
374 	default:
375 		ERROR("%s unknown or not support op = %x\n", MODULE_TAG, op);
376 		return -EINVAL;
377 	}
378 
379 	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 1, 0, 0);
380 	if (ret)
381 		return ret;
382 
383 	if (w1c) {
384 		reg_val = mmio_read_32(reg_addr);
385 		mmio_write_32(reg_addr, reg_val);
386 		smccc_ret->a1 = reg_val;
387 	} else {
388 		mmio_write_32(reg_addr, write_val);
389 	}
390 
391 	ret = apu_hw_sema_ctl(HW_SEMA2, HW_SEMA_LOGGER_USER, 0, 0, 0);
392 	if (ret)
393 		ERROR("%s(%d): sem release timeout\n", __func__, op);
394 
395 	return ret;
396 }
397 
398 int apusys_kernel_apusys_logtop_reg_write(uint32_t op, uint32_t write_val,
399 					  struct smccc_res *smccc_ret)
400 {
401 	return apusys_kernel_apusys_logtop_reg_rw(op, write_val, false, smccc_ret);
402 }
403 
404 int apusys_kernel_apusys_logtop_reg_w1c(uint32_t op, struct smccc_res *smccc_ret)
405 {
406 	return apusys_kernel_apusys_logtop_reg_rw(op, 0, true, smccc_ret);
407 }
408 
409 #endif /* CONFIG_MTK_APUSYS_LOGTOP_SUPPORT */
410 
411 int apusys_rv_cold_boot_clr_mbox_dummy(void)
412 {
413 #ifdef SUPPORT_APU_CLEAR_MBOX_DUMMY
414 	mmio_write_32(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_DUMMY, 0);
415 #else
416 	WARN("Not support clear mbox dummy on this platform\n");
417 #endif
418 	return 0;
419 }
420 
421 int apusys_rv_setup_ce_bin(void)
422 {
423 #ifdef CONFIG_MTK_APUSYS_CE_SUPPORT
424 	uintptr_t apusys_rv_sec_buf_pa;
425 	struct apusys_secure_info_t *apusys_secure_info;
426 	struct ce_main_hdr_t *ce_main_hdr;
427 	struct ce_sub_hdr_t *ce_sub_hdr;
428 	unsigned int cnt, i, reg_val;
429 	uint64_t ce_sub_hdr_bin;
430 	int ret;
431 
432 	apusys_rv_sec_buf_pa = APU_RESERVE_MEMORY;
433 	/* create mapping */
434 	ret = mmap_add_dynamic_region(apusys_rv_sec_buf_pa, apusys_rv_sec_buf_pa,
435 				      round_up(APU_RESERVE_SIZE, PAGE_SIZE),
436 				      MT_MEMORY | MT_RW | MT_NS);
437 	if (ret) {
438 		ERROR("%s: mmap_add_dynamic_region() fail, ret=0x%x\n", __func__, ret);
439 		return ret;
440 	}
441 
442 	apusys_secure_info = (struct apusys_secure_info_t *)
443 				(apusys_rv_sec_buf_pa + APU_SEC_INFO_OFFSET);
444 
445 	ce_main_hdr = (struct ce_main_hdr_t *)(apusys_rv_sec_buf_pa +
446 		apusys_secure_info->ce_bin_ofs);
447 	ce_sub_hdr = (struct ce_sub_hdr_t *)((uintptr_t)ce_main_hdr + ce_main_hdr->hdr_size);
448 
449 	if (ce_main_hdr->magic != CE_MAIN_MAGIC) {
450 		ERROR("%s: invalid header\n", __func__);
451 		return -EINVAL;
452 	}
453 
454 	cnt = 0;
455 
456 	while (ce_sub_hdr->magic == CE_SUB_MAGIC && cnt < ce_main_hdr->bin_count) {
457 		VERBOSE("%s: job (%d), magic (0x%x)\n", __func__,
458 			ce_sub_hdr->ce_enum, ce_sub_hdr->magic);
459 
460 		ce_sub_hdr_bin = (uint64_t)ce_sub_hdr + ce_sub_hdr->bin_offset;
461 
462 		for (i = 0; i < ce_sub_hdr->bin_size; i += sizeof(uint32_t)) {
463 			reg_val = *(uint32_t *)(ce_sub_hdr_bin + i);
464 			mmio_write_32(ce_sub_hdr->mem_st + i, reg_val);
465 		}
466 
467 		if (ce_sub_hdr->hw_entry) {
468 			mmio_clrsetbits_32(ce_sub_hdr->hw_entry,
469 					   ce_sub_hdr->hw_entry_mask << ce_sub_hdr->hw_entry_bit,
470 					   (ce_sub_hdr->hw_entry_val & ce_sub_hdr->hw_entry_mask)
471 					   << ce_sub_hdr->hw_entry_bit);
472 		}
473 
474 		ce_sub_hdr = (struct ce_sub_hdr_t *)(ce_sub_hdr_bin + ce_sub_hdr->bin_size);
475 		cnt++;
476 	}
477 
478 	mmap_remove_dynamic_region(apusys_rv_sec_buf_pa,
479 				   round_up(APU_RESERVE_SIZE, PAGE_SIZE));
480 
481 	INFO("%s: setup CE binary done\n", __func__);
482 #else
483 	WARN("Not support CE on this platform\n");
484 #endif
485 	return 0;
486 }
487