blob: 5da9ea80e59452ee984720c65b52d40818587082 [file] [log] [blame]
XiaoDong Huang1c167792025-02-07 18:07:46 +08001// 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
16enum {
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 */
24enum {
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
33enum {
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
71typedef 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
96static 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 */
132static 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 */
150static 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
200static 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
208static 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
216void 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
236static 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
244static 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
252static 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
260static 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
268static 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
276void 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
303static 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
311static 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
319static 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
327static 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
335static 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
343static 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
351static 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
359static 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
367void 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
406void 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
414void 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 */
423void 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 */
430void 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 */
437void 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
443static 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
455static 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
481static 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
490static 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
528static 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
619static __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
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
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
675void 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}