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