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