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