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