xref: /rk3399_ARM-atf/plat/rockchip/rk3576/drivers/secure/firewall.c (revision 04b2fb42b171e3fbf2ef823558ac5b0119663dc7)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
4  */
5 
6 #include <assert.h>
7 #include <errno.h>
8 
9 #include <drivers/delay_timer.h>
10 #include <lib/mmio.h>
11 #include <platform_def.h>
12 
13 #include <firewall.h>
14 #include <soc.h>
15 
16 enum {
17 	FW_NS_A_S_A = 0x0,
18 	FW_NS_A_S_NA = 0x1,
19 	FW_NS_NA_S_A = 0x2,
20 	FW_NS_NA_S_NA = 0x3,
21 };
22 
23 /* group type */
24 enum {
25 	FW_GRP_TYPE_INV = 0,
26 	FW_GRP_TYPE_DDR_RGN = 1,
27 	FW_GRP_TYPE_SYSMEM_RGN = 2,
28 	FW_GRP_TYPE_CBUF_RGN = 3,
29 	FW_GRP_TYPE_SLV = 4,
30 	FW_GRP_TYPE_DM = 5,
31 };
32 
33 enum {
34 	FW_SLV_TYPE_INV = 0,
35 	FW_MST_TYPE_INV = 0,
36 	FW_SLV_TYPE_BUS = 1,
37 	FW_SLV_TYPE_TOP = 2,
38 	FW_SLV_TYPE_CENTER = 3,
39 	FW_SLV_TYPE_CCI = 4,
40 	FW_SLV_TYPE_PHP = 5,
41 	FW_SLV_TYPE_GPU = 6,
42 	FW_SLV_TYPE_NPU = 7,
43 	FW_SLV_TYPE_PMU = 8,
44 	FW_MST_TYPE_SYS = 9,
45 	FW_MST_TYPE_PMU = 10,
46 };
47 
48 #define FW_ID(type, id)			\
49 	((((type) & 0xff) << 16) | ((id) & 0xffff))
50 
51 #define FW_MST_ID(type, id)		FW_ID(type, id)
52 #define FW_SLV_ID(type, id)		FW_ID(type, id)
53 #define FW_GRP_ID(type, id)		FW_ID(type, id)
54 
55 /* group id */
56 #define FW_GRP_ID_DDR_RGN(id)		FW_GRP_ID(FW_GRP_TYPE_DDR_RGN, id)
57 #define FW_GRP_ID_SYSMEM_RGN(id)	FW_GRP_ID(FW_GRP_TYPE_SYSMEM_RGN, id)
58 #define FW_GRP_ID_CBUF(id)		FW_GRP_ID(FW_GRP_TYPE_CBUF_RGN, id)
59 #define FW_GRP_ID_SLV(id)		FW_GRP_ID(FW_GRP_TYPE_SLV, id)
60 #define FW_GRP_ID_DM(id)		FW_GRP_ID(FW_GRP_TYPE_DM, id)
61 
62 #define FW_GRP_ID_SLV_CNT		8
63 #define FW_GRP_ID_DM_CNT		8
64 
65 #define FW_GET_ID(id)			((id) & 0xffff)
66 #define FW_GET_TYPE(id)			(((id) >> 16) & 0xff)
67 
68 #define FW_INVLID_MST_ID		FW_MST_ID(FW_MST_TYPE_INV, 0)
69 #define FW_INVLID_SLV_ID		FW_SLV_ID(FW_SLV_TYPE_INV, 0)
70 
71 typedef struct {
72 	uint32_t domain[FW_SGRF_MST_DOMAIN_CON_CNT];
73 	uint32_t pmu_domain;
74 	uint32_t bus_slv_grp[FW_SGRF_BUS_SLV_CON_CNT];
75 	uint32_t top_slv_grp[FW_SGRF_TOP_SLV_CON_CNT];
76 	uint32_t center_slv_grp[FW_SGRF_CENTER_SLV_CON_CNT];
77 	uint32_t cci_slv_grp[FW_SGRF_CCI_SLV_CON_CNT];
78 	uint32_t php_slv_grp[FW_SGRF_PHP_SLV_CON_CNT];
79 	uint32_t gpu_slv_grp;
80 	uint32_t npu_slv_grp[FW_SGRF_NPU_SLV_CON_CNT];
81 	uint32_t pmu_slv_grp[FW_PMU_SGRF_SLV_CON_CNT];
82 	uint32_t ddr_rgn[FW_SGRF_DDR_RGN_CNT];
83 	uint32_t ddr_size;
84 	uint32_t ddr_con;
85 	uint32_t sysmem_rgn[FW_SGRF_SYSMEM_RGN_CNT];
86 	uint32_t sysmem_con;
87 	uint32_t cbuf_rgn[FW_SGRF_CBUF_RGN_CNT];
88 	uint32_t cbuf_con;
89 	uint32_t ddr_lookup[FW_SGRF_DDR_LOOKUP_CNT];
90 	uint32_t sysmem_lookup[FW_SGRF_SYSMEM_LOOKUP_CNT];
91 	uint32_t cbuf_lookup[FW_SGRF_CBUF_LOOKUP_CNT];
92 	uint32_t slv_lookup[FW_SGRF_SLV_LOOKUP_CNT];
93 	uint32_t pmu_slv_lookup[FW_PMU_SGRF_SLV_LOOKUP_CNT];
94 } fw_config_t;
95 
96 static fw_config_t fw_config_buf;
97 
98 /****************************************************************************
99  * Access rights between domains and groups are as follows:
100  *
101  * 00: NS access,     S access
102  * 01: NS access,     S not access
103  * 10: NS not access, S access
104  * 11: NS not access, S not access
105  * |---------------------------------------------------------|
106  * |                 | d0 | d1 | d2 | d3 | d4 | d5 | d6 | d7 |
107  * |---------------------------------------------------------|
108  * | slave g0        | 00 | 00 | 11 | 11 | 11 | 11 | 11 | 00 |
109  * |---------------------------------------------------------|
110  * | slave g1        | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
111  * |---------------------------------------------------------|
112  * | slave g2~7      | 11 | 11 | 11 | 11 | 11 | 11 | 11 | 11 |
113  * |---------------------------------------------------------|
114  * | ddr region 0~15 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
115  * |---------------------------------------------------------|
116  * | sram region 0~3 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
117  * |---------------------------------------------------------|
118  * | cbuf region 0~7 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
119  * |---------------------------------------------------------|
120  *
121  * PS:
122  * Domain 0/1/7 NS/S can access group 0.
123  * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
124  * Other domains NS/S can't access all groups.
125  *
126  * Domain 0/7 NS can't access ddr/sram/cbuf region and Domain 0/7 S can access.
127  * Other domains NS/S can't access ddr/sram/cbuf region.
128  *
129  ******************************************************************************/
130 
131 /* Masters in dm1 */
132 static const int dm1_mst[] = {
133 	FW_MST_ID(FW_MST_TYPE_SYS, 1), /* keylad_apbm */
134 	FW_MST_ID(FW_MST_TYPE_SYS, 2), /* dft2apbm */
135 	FW_MST_ID(FW_MST_TYPE_SYS, 11), /* dma2ddr */
136 	FW_MST_ID(FW_MST_TYPE_SYS, 12), /* dmac0 */
137 	FW_MST_ID(FW_MST_TYPE_SYS, 13), /* dmac1 */
138 	FW_MST_ID(FW_MST_TYPE_SYS, 14), /* dmac2 */
139 	FW_MST_ID(FW_MST_TYPE_SYS, 19), /* gpu */
140 	FW_MST_ID(FW_MST_TYPE_SYS, 31), /* vop_m0 */
141 	FW_MST_ID(FW_MST_TYPE_SYS, 32), /* vop_m1 */
142 	FW_MST_ID(FW_MST_TYPE_SYS, 36), /* bus_mcu */
143 	FW_MST_ID(FW_MST_TYPE_SYS, 38), /* npu_mcu */
144 	FW_MST_ID(FW_MST_TYPE_SYS, 56), /* dap_lite */
145 
146 	FW_INVLID_MST_ID
147 };
148 
149 /* Slaves in group1 */
150 static const int sec_slv[] = {
151 	FW_SLV_ID(FW_SLV_TYPE_TOP, 28), /* crypto_s */
152 	FW_SLV_ID(FW_SLV_TYPE_TOP, 29), /* keyladder_s */
153 	FW_SLV_ID(FW_SLV_TYPE_TOP, 30), /* rkrng_s */
154 	FW_SLV_ID(FW_SLV_TYPE_TOP, 33), /* jtag_lock */
155 	FW_SLV_ID(FW_SLV_TYPE_TOP, 34), /* otp_s */
156 	FW_SLV_ID(FW_SLV_TYPE_TOP, 35), /* otpmsk */
157 	FW_SLV_ID(FW_SLV_TYPE_TOP, 37), /* scru_s */
158 	FW_SLV_ID(FW_SLV_TYPE_TOP, 38), /* sys_sgrf */
159 	FW_SLV_ID(FW_SLV_TYPE_TOP, 39), /* bootrom */
160 	FW_SLV_ID(FW_SLV_TYPE_TOP, 41), /* wdts */
161 	FW_SLV_ID(FW_SLV_TYPE_TOP, 44), /* sevice_secure */
162 	FW_SLV_ID(FW_SLV_TYPE_TOP, 61), /* timers0_ch0~5 */
163 	FW_SLV_ID(FW_SLV_TYPE_TOP, 62),
164 	FW_SLV_ID(FW_SLV_TYPE_TOP, 63),
165 	FW_SLV_ID(FW_SLV_TYPE_TOP, 64),
166 	FW_SLV_ID(FW_SLV_TYPE_TOP, 65),
167 	FW_SLV_ID(FW_SLV_TYPE_TOP, 66),
168 	FW_SLV_ID(FW_SLV_TYPE_TOP, 67), /* timers1_ch0~5 */
169 	FW_SLV_ID(FW_SLV_TYPE_TOP, 68),
170 	FW_SLV_ID(FW_SLV_TYPE_TOP, 69),
171 	FW_SLV_ID(FW_SLV_TYPE_TOP, 70),
172 	FW_SLV_ID(FW_SLV_TYPE_TOP, 71),
173 	FW_SLV_ID(FW_SLV_TYPE_TOP, 72),
174 	FW_SLV_ID(FW_SLV_TYPE_TOP, 73), /* sys_fw */
175 
176 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 3),  /* ddr grf */
177 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 4),  /* ddr ctl0 */
178 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 5),  /* ddr ctl1 */
179 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 6),  /* ddr phy0 */
180 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 7),  /* ddr0 cru */
181 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 8),  /* ddr phy1 */
182 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 9),  /* ddr1 cru */
183 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 15), /* ddr wdt */
184 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 19), /* service ddr */
185 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 58), /* ddr timer ch0 */
186 	FW_SLV_ID(FW_SLV_TYPE_CENTER, 59), /* ddr timer ch1 */
187 
188 	FW_SLV_ID(FW_SLV_TYPE_PMU, 1),	/* pmu mem */
189 	FW_SLV_ID(FW_SLV_TYPE_PMU, 15), /* pmu1_scru */
190 	FW_SLV_ID(FW_SLV_TYPE_PMU, 30), /* osc chk */
191 	FW_SLV_ID(FW_SLV_TYPE_PMU, 31), /* pmu0_sgrf */
192 	FW_SLV_ID(FW_SLV_TYPE_PMU, 32), /* pmu1_sgrf */
193 	FW_SLV_ID(FW_SLV_TYPE_PMU, 34), /* scramble key */
194 	FW_SLV_ID(FW_SLV_TYPE_PMU, 36), /* pmu remap */
195 	FW_SLV_ID(FW_SLV_TYPE_PMU, 43), /* pmu fw */
196 
197 	FW_INVLID_SLV_ID
198 };
199 
fw_buf_sys_mst_dm_cfg(int mst_id,uint32_t dm_id)200 static void fw_buf_sys_mst_dm_cfg(int mst_id, uint32_t dm_id)
201 {
202 	int sft = (mst_id & 0x7) << 2;
203 
204 	fw_config_buf.domain[mst_id >> 3] &= ~(0xf << sft);
205 	fw_config_buf.domain[mst_id >> 3] |= (dm_id & 0xf) << sft;
206 }
207 
fw_buf_pmu_mst_dm_cfg(int mst_id,uint32_t dm_id)208 static void fw_buf_pmu_mst_dm_cfg(int mst_id, uint32_t dm_id)
209 {
210 	int sft = (mst_id & 0x7) << 2;
211 
212 	fw_config_buf.pmu_domain &= ~(0xf << sft);
213 	fw_config_buf.pmu_domain |= (dm_id & 0xf) << sft;
214 }
215 
fw_buf_mst_dm_cfg(int mst_id,uint32_t dm_id)216 void fw_buf_mst_dm_cfg(int mst_id, uint32_t dm_id)
217 {
218 	int type = FW_GET_TYPE(mst_id);
219 
220 	mst_id = FW_GET_ID(mst_id);
221 
222 	switch (type) {
223 	case FW_MST_TYPE_SYS:
224 		fw_buf_sys_mst_dm_cfg(mst_id, dm_id);
225 		break;
226 	case FW_MST_TYPE_PMU:
227 		fw_buf_pmu_mst_dm_cfg(mst_id, dm_id);
228 		break;
229 
230 	default:
231 		ERROR("%s: unknown FW_DOMAIN_TYPE (0x%x)\n", __func__, type);
232 		break;
233 	}
234 }
235 
fw_buf_ddr_lookup_cfg(int rgn_id,int dm_id,uint32_t priv)236 static void fw_buf_ddr_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
237 {
238 	int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
239 
240 	fw_config_buf.ddr_lookup[rgn_id >> 1] &= ~(0x3 << sft);
241 	fw_config_buf.ddr_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
242 }
243 
fw_buf_sysmem_lookup_cfg(int rgn_id,int dm_id,uint32_t priv)244 static void fw_buf_sysmem_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
245 {
246 	int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
247 
248 	fw_config_buf.sysmem_lookup[rgn_id >> 1] &= ~(0x3 << sft);
249 	fw_config_buf.sysmem_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
250 }
251 
fw_buf_cbuf_lookup_cfg(int rgn_id,int dm_id,uint32_t priv)252 static void fw_buf_cbuf_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
253 {
254 	int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
255 
256 	fw_config_buf.cbuf_lookup[rgn_id >> 1] &= ~(0x3 << sft);
257 	fw_config_buf.cbuf_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
258 }
259 
fw_buf_slv_lookup_cfg(int grp_id,int dm_id,uint32_t priv)260 static void fw_buf_slv_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
261 {
262 	int sft = (dm_id << 1) + (grp_id & 0x1) * 16;
263 
264 	fw_config_buf.slv_lookup[grp_id >> 1] &= ~(0x3 << sft);
265 	fw_config_buf.slv_lookup[grp_id >> 1] |= (priv & 0x3) << sft;
266 }
267 
fw_buf_pmu_slv_lookup_cfg(int grp_id,int dm_id,uint32_t priv)268 static void fw_buf_pmu_slv_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
269 {
270 	int sft = (dm_id << 1) + (grp_id & 0x1) * 16;
271 
272 	fw_config_buf.pmu_slv_lookup[grp_id >> 1] &= ~(0x3 << sft);
273 	fw_config_buf.pmu_slv_lookup[grp_id >> 1] |= (priv & 0x3) << sft;
274 }
275 
fw_buf_grp_lookup_cfg(int grp_id,int dm_id,uint32_t priv)276 void fw_buf_grp_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
277 {
278 	uint32_t type = FW_GET_TYPE(grp_id);
279 
280 	grp_id = FW_GET_ID(grp_id);
281 
282 	switch (type) {
283 	case FW_GRP_TYPE_DDR_RGN:
284 		fw_buf_ddr_lookup_cfg(grp_id, dm_id, priv);
285 		break;
286 	case FW_GRP_TYPE_SYSMEM_RGN:
287 		fw_buf_sysmem_lookup_cfg(grp_id, dm_id, priv);
288 		break;
289 	case FW_GRP_TYPE_CBUF_RGN:
290 		fw_buf_cbuf_lookup_cfg(grp_id, dm_id, priv);
291 		break;
292 	case FW_GRP_TYPE_SLV:
293 		fw_buf_slv_lookup_cfg(grp_id, dm_id, priv);
294 		fw_buf_pmu_slv_lookup_cfg(grp_id, dm_id, priv);
295 		break;
296 
297 	default:
298 		ERROR("%s: unknown FW_LOOKUP_TYPE (0x%x)\n", __func__, type);
299 		break;
300 	}
301 }
302 
fw_buf_bus_slv_grp_cfg(int slv_id,int grp_id)303 static void fw_buf_bus_slv_grp_cfg(int slv_id, int grp_id)
304 {
305 	int sft = slv_id % 5 << 2;
306 
307 	fw_config_buf.bus_slv_grp[slv_id / 5] &= ~(0xf << sft);
308 	fw_config_buf.bus_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
309 }
310 
fw_buf_top_slv_grp_cfg(int slv_id,int grp_id)311 static void fw_buf_top_slv_grp_cfg(int slv_id, int grp_id)
312 {
313 	int sft = slv_id % 5 << 2;
314 
315 	fw_config_buf.top_slv_grp[slv_id / 5] &= ~(0xf << sft);
316 	fw_config_buf.top_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
317 }
318 
fw_buf_center_slv_grp_cfg(int slv_id,int grp_id)319 static void fw_buf_center_slv_grp_cfg(int slv_id, int grp_id)
320 {
321 	int sft = slv_id % 5 << 2;
322 
323 	fw_config_buf.center_slv_grp[slv_id / 5] &= ~(0xf << sft);
324 	fw_config_buf.center_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
325 }
326 
fw_buf_cci_slv_grp_cfg(int slv_id,int grp_id)327 static void fw_buf_cci_slv_grp_cfg(int slv_id, int grp_id)
328 {
329 	int sft = slv_id % 5 << 2;
330 
331 	fw_config_buf.cci_slv_grp[slv_id / 5] &= ~(0xf << sft);
332 	fw_config_buf.cci_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
333 }
334 
fw_buf_php_slv_grp_cfg(int slv_id,int grp_id)335 static void fw_buf_php_slv_grp_cfg(int slv_id, int grp_id)
336 {
337 	int sft = slv_id % 5 << 2;
338 
339 	fw_config_buf.php_slv_grp[slv_id / 5] &= ~(0xf << sft);
340 	fw_config_buf.php_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
341 }
342 
fw_buf_gpu_slv_grp_cfg(int slv_id,int grp_id)343 static void fw_buf_gpu_slv_grp_cfg(int slv_id, int grp_id)
344 {
345 	int sft = slv_id % 5 << 2;
346 
347 	fw_config_buf.gpu_slv_grp &= ~(0xf << sft);
348 	fw_config_buf.gpu_slv_grp |= (grp_id & 0xf) << sft;
349 }
350 
fw_buf_npu_slv_grp_cfg(int slv_id,int grp_id)351 static void fw_buf_npu_slv_grp_cfg(int slv_id, int grp_id)
352 {
353 	int sft = slv_id % 5 << 2;
354 
355 	fw_config_buf.npu_slv_grp[slv_id / 5] &= ~(0xf << sft);
356 	fw_config_buf.npu_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
357 }
358 
fw_buf_pmu_slv_grp_cfg(int slv_id,int grp_id)359 static void fw_buf_pmu_slv_grp_cfg(int slv_id, int grp_id)
360 {
361 	int sft = slv_id % 5 << 2;
362 
363 	fw_config_buf.pmu_slv_grp[slv_id / 5] &= ~(0xf << sft);
364 	fw_config_buf.pmu_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
365 }
366 
fw_buf_slv_grp_cfg(int slv_id,int grp_id)367 void fw_buf_slv_grp_cfg(int slv_id, int grp_id)
368 {
369 	int type = FW_GET_TYPE(slv_id);
370 
371 	slv_id = FW_GET_ID(slv_id);
372 	grp_id = FW_GET_ID(grp_id);
373 
374 	switch (type) {
375 	case FW_SLV_TYPE_BUS:
376 		fw_buf_bus_slv_grp_cfg(slv_id, grp_id);
377 		break;
378 	case FW_SLV_TYPE_TOP:
379 		fw_buf_top_slv_grp_cfg(slv_id, grp_id);
380 		break;
381 	case FW_SLV_TYPE_CENTER:
382 		fw_buf_center_slv_grp_cfg(slv_id, grp_id);
383 		break;
384 	case FW_SLV_TYPE_CCI:
385 		fw_buf_cci_slv_grp_cfg(slv_id, grp_id);
386 		break;
387 	case FW_SLV_TYPE_PHP:
388 		fw_buf_php_slv_grp_cfg(slv_id, grp_id);
389 		break;
390 	case FW_SLV_TYPE_GPU:
391 		fw_buf_gpu_slv_grp_cfg(slv_id, grp_id);
392 		break;
393 	case FW_SLV_TYPE_NPU:
394 		fw_buf_npu_slv_grp_cfg(slv_id, grp_id);
395 		break;
396 	case FW_SLV_TYPE_PMU:
397 		fw_buf_pmu_slv_grp_cfg(slv_id, grp_id);
398 		break;
399 
400 	default:
401 		ERROR("%s: unknown FW_SLV_TYPE (0x%x)\n", __func__, type);
402 		break;
403 	}
404 }
405 
fw_buf_add_msts(const int * mst_ids,int dm_id)406 void fw_buf_add_msts(const int *mst_ids, int dm_id)
407 {
408 	int i;
409 
410 	for (i = 0; FW_GET_TYPE(mst_ids[i]) != FW_INVLID_SLV_ID; i++)
411 		fw_buf_mst_dm_cfg(mst_ids[i], dm_id);
412 }
413 
fw_buf_add_slvs(const int * slv_ids,int grp_id)414 void fw_buf_add_slvs(const int *slv_ids, int grp_id)
415 {
416 	int i;
417 
418 	for (i = 0; FW_GET_TYPE(slv_ids[i]) != FW_INVLID_SLV_ID; i++)
419 		fw_buf_slv_grp_cfg(slv_ids[i], grp_id);
420 }
421 
422 /* unit: Mb */
fw_buf_ddr_size_cfg(uint64_t base_mb,uint64_t top_mb,int id)423 void fw_buf_ddr_size_cfg(uint64_t base_mb, uint64_t top_mb, int id)
424 {
425 	fw_config_buf.ddr_size = RG_MAP_SECURE(top_mb, base_mb);
426 	fw_config_buf.ddr_con |= BIT(16);
427 }
428 
429 /* unit: Mb */
fw_buf_ddr_rgn_cfg(uint64_t base_mb,uint64_t top_mb,int rgn_id)430 void fw_buf_ddr_rgn_cfg(uint64_t base_mb, uint64_t top_mb, int rgn_id)
431 {
432 	fw_config_buf.ddr_rgn[rgn_id] = RG_MAP_SECURE(top_mb, base_mb);
433 	fw_config_buf.ddr_con |= BIT(rgn_id);
434 }
435 
436 /* Unit: kb */
fw_buf_sysmem_rgn_cfg(uint64_t base_kb,uint64_t top_kb,int rgn_id)437 void fw_buf_sysmem_rgn_cfg(uint64_t base_kb, uint64_t top_kb, int rgn_id)
438 {
439 	fw_config_buf.sysmem_rgn[rgn_id] = RG_MAP_SRAM_SECURE(top_kb, base_kb);
440 	fw_config_buf.sysmem_con |= BIT(rgn_id);
441 }
442 
fw_domain_init(void)443 static void fw_domain_init(void)
444 {
445 	int i;
446 
447 	/* select to domain0 by default */
448 	for (i = 0; i < FW_SGRF_MST_DOMAIN_CON_CNT; i++)
449 		fw_config_buf.domain[i] = 0x0;
450 
451 	/* select to domain0 by default */
452 	fw_config_buf.pmu_domain = 0x0;
453 }
454 
fw_slv_grp_init(void)455 static void fw_slv_grp_init(void)
456 {
457 	int i;
458 
459 	/* select to group0 by default */
460 	for (i = 0; i < FW_SGRF_BUS_SLV_CON_CNT; i++)
461 		fw_config_buf.bus_slv_grp[i] = 0x0;
462 
463 	for (i = 0; i < FW_SGRF_TOP_SLV_CON_CNT; i++)
464 		fw_config_buf.top_slv_grp[i] = 0x0;
465 
466 	for (i = 0; i < FW_SGRF_CENTER_SLV_CON_CNT; i++)
467 		fw_config_buf.center_slv_grp[i] = 0x0;
468 
469 	for (i = 0; i < FW_SGRF_CCI_SLV_CON_CNT; i++)
470 		fw_config_buf.cci_slv_grp[i] = 0x0;
471 
472 	for (i = 0; i < FW_SGRF_PHP_SLV_CON_CNT; i++)
473 		fw_config_buf.php_slv_grp[i] = 0x0;
474 
475 	fw_config_buf.gpu_slv_grp = 0x0;
476 
477 	for (i = 0; i < FW_SGRF_NPU_SLV_CON_CNT; i++)
478 		fw_config_buf.npu_slv_grp[i] = 0x0;
479 }
480 
fw_region_init(void)481 static void fw_region_init(void)
482 {
483 	/* Use FW_DDR_RGN0_REG to config 1024~1025M space to secure */
484 	fw_buf_ddr_rgn_cfg(1024, 1025, 0);
485 
486 	/* Use FW_SYSMEM_RGN0_REG to config 0~32k space to secure */
487 	fw_buf_sysmem_rgn_cfg(0, 32, 0);
488 }
489 
fw_lookup_init(void)490 static void fw_lookup_init(void)
491 {
492 	int i;
493 
494 	/*
495 	 * Domain 0/7 NS can't access ddr/sram/cbuf region and Domain 0/7 S can access.
496 	 * Other domains NS/S can't access ddr/sram/cbuf region.
497 	 */
498 	for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
499 		fw_config_buf.ddr_lookup[i] = 0xbffebffe;
500 
501 	for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
502 		fw_config_buf.sysmem_lookup[i] = 0xbffebffe;
503 
504 	for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
505 		fw_config_buf.cbuf_lookup[i] = 0xbffebffe;
506 
507 	/*
508 	 * Domain 0/1/7 NS/S can access group 0.
509 	 * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
510 	 * Other domains NS/S can't access all groups.
511 	 */
512 	fw_config_buf.slv_lookup[0] = 0xbffe3ff0;
513 	fw_config_buf.slv_lookup[1] = 0xffffffff;
514 	fw_config_buf.slv_lookup[2] = 0xffffffff;
515 	fw_config_buf.slv_lookup[3] = 0xffffffff;
516 
517 	/*
518 	 * Domain 0/1/7 NS/S can access group 0.
519 	 * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
520 	 * Other domains NS/S can't access all groups.
521 	 */
522 	fw_config_buf.pmu_slv_lookup[0] = 0xbffe3ff0;
523 	fw_config_buf.pmu_slv_lookup[1] = 0xffffffff;
524 	fw_config_buf.pmu_slv_lookup[2] = 0xffffffff;
525 	fw_config_buf.pmu_slv_lookup[3] = 0xffffffff;
526 }
527 
fw_config_buf_flush(void)528 static void fw_config_buf_flush(void)
529 {
530 	int i;
531 
532 	/* domain */
533 	for (i = 0; i < FW_SGRF_MST_DOMAIN_CON_CNT; i++)
534 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_MST_DOMAIN_CON(i),
535 			      fw_config_buf.domain[i]);
536 
537 	mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_DOMAIN_CON,
538 		      fw_config_buf.pmu_domain);
539 
540 	/* slave group */
541 	for (i = 0; i < FW_SGRF_BUS_SLV_CON_CNT; i++)
542 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_BUS_SLV_CON(i),
543 			      fw_config_buf.bus_slv_grp[i]);
544 
545 	for (i = 0; i < FW_SGRF_TOP_SLV_CON_CNT; i++)
546 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_TOP_SLV_CON(i),
547 			      fw_config_buf.top_slv_grp[i]);
548 
549 	for (i = 0; i < FW_SGRF_CENTER_SLV_CON_CNT; i++)
550 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CENTER_SLV_CON(i),
551 			      fw_config_buf.center_slv_grp[i]);
552 
553 	for (i = 0; i < FW_SGRF_CCI_SLV_CON_CNT; i++)
554 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CCI_SLV_CON(i),
555 			      fw_config_buf.cci_slv_grp[i]);
556 
557 	for (i = 0; i < FW_SGRF_PHP_SLV_CON_CNT; i++)
558 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_PHP_SLV_CON(i),
559 			      fw_config_buf.php_slv_grp[i]);
560 
561 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_GPU_SLV_CON,
562 		      fw_config_buf.gpu_slv_grp);
563 
564 	for (i = 0; i < FW_SGRF_NPU_SLV_CON_CNT; i++)
565 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_NPU_SLV_CON(i),
566 			      fw_config_buf.npu_slv_grp[i]);
567 
568 	for (i = 0; i < FW_PMU_SGRF_SLV_CON_CNT; i++)
569 		mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_CON(i),
570 			      fw_config_buf.pmu_slv_grp[i]);
571 
572 	/* region */
573 	for (i = 0; i < FW_SGRF_DDR_RGN_CNT; i++)
574 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_RGN(i),
575 			      fw_config_buf.ddr_rgn[i]);
576 
577 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_SIZE, fw_config_buf.ddr_size);
578 
579 	for (i = 0; i < FW_SGRF_SYSMEM_RGN_CNT; i++)
580 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_RGN(i),
581 			      fw_config_buf.sysmem_rgn[i]);
582 
583 	for (i = 0; i < FW_SGRF_CBUF_RGN_CNT; i++)
584 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_RGN(i),
585 			      fw_config_buf.cbuf_rgn[i]);
586 
587 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_CON, fw_config_buf.ddr_con);
588 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_CON, fw_config_buf.sysmem_con);
589 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_CON, fw_config_buf.cbuf_con);
590 
591 	dsb();
592 	isb();
593 
594 	/* lookup */
595 	for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
596 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_LOOKUP(i),
597 			      fw_config_buf.ddr_lookup[i]);
598 
599 	for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
600 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_LOOKUP(i),
601 			      fw_config_buf.sysmem_lookup[i]);
602 
603 	for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
604 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_LOOKUP(i),
605 			      fw_config_buf.cbuf_lookup[i]);
606 
607 	for (i = 0; i < FW_SGRF_SLV_LOOKUP_CNT; i++)
608 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SLV_LOOKUP(i),
609 			      fw_config_buf.slv_lookup[i]);
610 
611 	for (i = 0; i < FW_PMU_SGRF_SLV_LOOKUP_CNT; i++)
612 		mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_LOOKUP(i),
613 			      fw_config_buf.pmu_slv_lookup[i]);
614 
615 	dsb();
616 	isb();
617 }
618 
pmusram_udelay(uint32_t us)619 static __pmusramfunc void pmusram_udelay(uint32_t us)
620 {
621 	uint64_t orig;
622 	uint64_t to_wait;
623 
624 	orig = read_cntpct_el0();
625 	to_wait = read_cntfrq_el0() * us / 1000000;
626 
627 	while (read_cntpct_el0() - orig <= to_wait)
628 		;
629 }
630 
pmusram_fw_update_msk(uint32_t msk)631 __pmusramfunc void pmusram_fw_update_msk(uint32_t msk)
632 {
633 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON0,
634 		      BITS_WITH_WMASK(0, 0x3ff, 0));
635 	dsb();
636 
637 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON0,
638 		      BITS_WITH_WMASK(msk, msk, 0));
639 	dsb();
640 	isb();
641 	pmusram_udelay(20);
642 	dsb();
643 	isb();
644 }
645 
pmusram_all_fw_bypass(void)646 __pmusramfunc void pmusram_all_fw_bypass(void)
647 {
648 	int i;
649 
650 	/* disable regions */
651 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_CON, 0);
652 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_CON, 0);
653 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_CON, 0);
654 
655 	for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
656 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_LOOKUP(i), 0x0);
657 
658 	for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
659 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_LOOKUP(i), 0x0);
660 
661 	for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
662 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_LOOKUP(i), 0x0);
663 
664 	for (i = 0; i < FW_SGRF_SLV_LOOKUP_CNT; i++)
665 		mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SLV_LOOKUP(i), 0x0);
666 
667 	for (i = 0; i < FW_PMU_SGRF_SLV_LOOKUP_CNT; i++)
668 		mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_LOOKUP(i), 0x0);
669 
670 	dsb();
671 
672 	pmusram_fw_update_msk(0x3ff);
673 }
674 
fw_init(void)675 void fw_init(void)
676 {
677 	/* Enable all fw auto-update */
678 	mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON1, 0x03ff03ff);
679 
680 	pmusram_all_fw_bypass();
681 
682 	fw_domain_init();
683 	fw_slv_grp_init();
684 	fw_region_init();
685 
686 	fw_buf_add_slvs(sec_slv, 1);
687 	fw_buf_add_msts(dm1_mst, 1);
688 
689 	fw_lookup_init();
690 
691 	fw_config_buf_flush();
692 	pmusram_fw_update_msk(0x3ff);
693 }
694