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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 */ 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 */ 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 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 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 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 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 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 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 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 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