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 <arch_helpers.h>
10 #include <bl31/bl31.h>
11 #include <common/debug.h>
12 #include <drivers/console.h>
13 #include <drivers/delay_timer.h>
14 #include <lib/mmio.h>
15 #include <lib/xlat_tables/xlat_tables_compat.h>
16 #include <platform.h>
17 #include <platform_def.h>
18 #include <pmu.h>
19
20 #include <plat_private.h>
21 #include <rk3576_clk.h>
22 #include <secure.h>
23 #include <soc.h>
24
25 const mmap_region_t plat_rk_mmap[] = {
26 MAP_REGION_FLAT(RK3576_DEV_RNG0_BASE, RK3576_DEV_RNG0_SIZE,
27 MT_DEVICE | MT_RW | MT_SECURE),
28 MAP_REGION_FLAT(DDR_SHARE_MEM, DDR_SHARE_SIZE,
29 MT_DEVICE | MT_RW | MT_NS),
30 { 0 }
31 };
32
33 /* The RockChip power domain tree descriptor */
34 const unsigned char rockchip_power_domain_tree_desc[] = {
35 /* No of root nodes */
36 PLATFORM_SYSTEM_COUNT,
37 /* No of children for the root node */
38 PLATFORM_CLUSTER_COUNT,
39 /* No of children for the first cluster node */
40 PLATFORM_CLUSTER0_CORE_COUNT,
41 /* No of children for the second cluster node */
42 PLATFORM_CLUSTER1_CORE_COUNT
43 };
44
clear_glb_reset_status(void)45 static void clear_glb_reset_status(void)
46 {
47 uint32_t cru_sel55 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(55));
48
49 /* switch pclk_bus_root to 24M before writing CRU_GLB_RST_ST */
50 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(55),
51 BITS_WITH_WMASK(2, 0x3, 2));
52 dsb();
53
54 mmio_write_32(CRU_BASE + CRU_GLB_RST_ST, 0xffff);
55 dsb();
56
57 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(55),
58 WITH_16BITS_WMSK(cru_sel55));
59 }
60
print_glb_reset_status(void)61 static void print_glb_reset_status(void)
62 {
63 uint32_t glb_rst_st = 0, warm_boot = 0;
64
65 /* clear CRU_GLB_RST_ST_NCLR if cold boot */
66 if (mmio_read_32(PMU0_GRF_BASE + PMU0GRF_OS_REG(17)) == WARM_BOOT_MAGIC) {
67 /* ignore npu_wdt*/
68 glb_rst_st = mmio_read_32(CRU_BASE + CRU_GLB_RST_ST_NCLR) & VALID_GLB_RST_MSK;
69 warm_boot = 1;
70 } else {
71 mmio_write_32(PMU0_GRF_BASE + PMU0GRF_OS_REG(17), WARM_BOOT_MAGIC);
72 }
73
74 clear_glb_reset_status();
75
76 /* save glb_rst_st in mem_os_reg31 */
77 write_mem_os_reg(31, glb_rst_st);
78
79 if (warm_boot != 0)
80 INFO("soc warm boot, reset status: 0x%x\n", glb_rst_st);
81 else
82 INFO("soc cold boot\n");
83 }
84
system_reset_init(void)85 static void system_reset_init(void)
86 {
87 /*
88 * enable tsadc trigger global reset and select first reset.
89 * enable global reset and wdt trigger pmu reset.
90 * select first reset trigger pmu reset.
91 */
92 mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, 0xffdf);
93
94 /* enable wdt_s reset */
95 mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0), 0x20002000);
96
97 /* enable wdt_ns reset */
98 mmio_write_32(SYS_GRF_BASE + SYSGRF_SOC_CON(4), 0x01000100);
99
100 /* reset width = 0xffff */
101 mmio_write_32(PMU1_GRF_BASE + PMU1GRF_SOC_CON(6), 0xffffffff);
102
103 /* enable first/tsadc/wdt reset output */
104 mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00070007);
105
106 /* pmu0sgrf pmu0_ioc hold */
107 mmio_write_32(PMU0SGRF_BASE + PMU1SGRF_SOC_CON(0), 0xffff1800);
108
109 /* pmu1sgrf pmu1_grf hold */
110 mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(16), 0xffff8800);
111
112 /* select tsadc_shut_m0 ionmux*/
113 mmio_write_32(PMU0_IOC_BASE + 0x0, 0x00f00090);
114
115 print_glb_reset_status();
116 }
117
plat_rockchip_soc_init(void)118 void plat_rockchip_soc_init(void)
119 {
120 rockchip_clock_init();
121 system_reset_init();
122 secure_init();
123 rockchip_init_scmi_server();
124
125 /* release cpu1~cpu7 */
126 mmio_write_32(CCI_GRF_BASE + CCIGRF_CON(4), 0xffffffff);
127 mmio_write_32(LITCORE_GRF_BASE + COREGRF_CPU_CON(1),
128 BITS_WITH_WMASK(0x77, 0xff, 4));
129 }
130