1 /*
2  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <platform_def.h>
8 
9 #include <arch_helpers.h>
10 #include <common/debug.h>
11 #include <lib/mmio.h>
12 
13 #include <plat_private.h>
14 #include <rk3288_def.h>
15 #include <soc.h>
16 #include <secure.h>
17 
18 /* sleep data for pll suspend */
19 static struct deepsleep_data_s slp_data;
20 
21 /* Table of regions to map using the MMU. */
22 const mmap_region_t plat_rk_mmap[] = {
23 	MAP_REGION_FLAT(GIC400_BASE, GIC400_SIZE,
24 			MT_DEVICE | MT_RW | MT_SECURE),
25 	MAP_REGION_FLAT(STIME_BASE, STIME_SIZE,
26 			MT_DEVICE | MT_RW | MT_SECURE),
27 	MAP_REGION_FLAT(SGRF_BASE, SGRF_SIZE,
28 			MT_DEVICE | MT_RW | MT_SECURE),
29 	MAP_REGION_FLAT(TZPC_BASE, TZPC_SIZE,
30 			MT_DEVICE | MT_RW | MT_SECURE),
31 	MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
32 			MT_MEMORY | MT_RW | MT_SECURE),
33 	MAP_REGION_FLAT(SRAM_BASE, SRAM_SIZE,
34 			MT_DEVICE | MT_RW | MT_SECURE),
35 	MAP_REGION_FLAT(PMU_BASE, PMU_SIZE,
36 			MT_DEVICE | MT_RW | MT_SECURE),
37 	MAP_REGION_FLAT(UART0_BASE, UART0_SIZE,
38 			MT_DEVICE | MT_RW | MT_SECURE),
39 	MAP_REGION_FLAT(UART1_BASE, UART1_SIZE,
40 			MT_DEVICE | MT_RW | MT_SECURE),
41 	MAP_REGION_FLAT(UART2_BASE, UART2_SIZE,
42 			MT_DEVICE | MT_RW | MT_SECURE),
43 	MAP_REGION_FLAT(UART3_BASE, UART3_SIZE,
44 			MT_DEVICE | MT_RW | MT_SECURE),
45 	MAP_REGION_FLAT(UART4_BASE, UART4_SIZE,
46 			MT_DEVICE | MT_RW | MT_SECURE),
47 	MAP_REGION_FLAT(CRU_BASE, CRU_SIZE,
48 			MT_DEVICE | MT_RW | MT_SECURE),
49 	MAP_REGION_FLAT(GRF_BASE, GRF_SIZE,
50 			MT_DEVICE | MT_RW | MT_SECURE),
51 	MAP_REGION_FLAT(DDR_PCTL0_BASE, DDR_PCTL0_SIZE,
52 			MT_DEVICE | MT_RW | MT_SECURE),
53 	MAP_REGION_FLAT(DDR_PHY0_BASE, DDR_PHY0_SIZE,
54 			MT_DEVICE | MT_RW | MT_SECURE),
55 	MAP_REGION_FLAT(DDR_PCTL1_BASE, DDR_PCTL1_SIZE,
56 			MT_DEVICE | MT_RW | MT_SECURE),
57 	MAP_REGION_FLAT(DDR_PHY1_BASE, DDR_PHY1_SIZE,
58 			MT_DEVICE | MT_RW | MT_SECURE),
59 	MAP_REGION_FLAT(SERVICE_BUS_BASE, SERVICE_BUS_SIZE,
60 			MT_DEVICE | MT_RW | MT_SECURE),
61 	MAP_REGION_FLAT(CORE_AXI_BUS_BASE, CORE_AXI_BUS_SIZE,
62 			MT_DEVICE | MT_RW | MT_SECURE),
63 	{ 0 }
64 };
65 
66 /* The RockChip power domain tree descriptor */
67 const unsigned char rockchip_power_domain_tree_desc[] = {
68 	/* No of root nodes */
69 	PLATFORM_SYSTEM_COUNT,
70 	/* No of children for the root node */
71 	PLATFORM_CLUSTER_COUNT,
72 	/* No of children for the first cluster node */
73 	PLATFORM_CLUSTER0_CORE_COUNT,
74 };
75 
plat_rockchip_soc_init(void)76 void plat_rockchip_soc_init(void)
77 {
78 	secure_timer_init();
79 	secure_sgrf_init();
80 	/*
81 	 * We cannot enable ddr security at this point, as the kernel
82 	 * seems to have an issue with it even living in the same 128MB
83 	 * memory block. Only when moving the kernel to the second
84 	 * 128MB block does it not conflict, but then we'd loose this
85 	 * memory area for use. Late maybe enable
86 	 * secure_sgrf_ddr_rgn_init();
87 	 */
88 }
89 
regs_update_bits(uintptr_t addr,uint32_t val,uint32_t mask,uint32_t shift)90 void regs_update_bits(uintptr_t addr, uint32_t val,
91 		      uint32_t mask, uint32_t shift)
92 {
93 	uint32_t tmp, orig;
94 
95 	orig = mmio_read_32(addr);
96 
97 	tmp = orig & ~(mask << shift);
98 	tmp |= (val & mask) << shift;
99 
100 	if (tmp != orig)
101 		mmio_write_32(addr, tmp);
102 	dsb();
103 }
104 
pll_save(uint32_t pll_id)105 static void pll_save(uint32_t pll_id)
106 {
107 	uint32_t *pll = slp_data.pll_con[pll_id];
108 
109 	pll[0] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 0));
110 	pll[1] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 1));
111 	pll[2] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 2));
112 	pll[3] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 3));
113 }
114 
clk_plls_suspend(void)115 void clk_plls_suspend(void)
116 {
117 	pll_save(NPLL_ID);
118 	pll_save(CPLL_ID);
119 	pll_save(GPLL_ID);
120 	pll_save(APLL_ID);
121 	slp_data.pll_mode = mmio_read_32(CRU_BASE + PLL_MODE_CON);
122 
123 	/*
124 	 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
125 	 * avoid crashes on resume. The Mask ROM on the system will
126 	 * put APLL, CPLL, and GPLL into slow mode at resume time
127 	 * anyway (which is why we restore them), but we might not
128 	 * even make it to the Mask ROM if this isn't done at suspend
129 	 * time.
130 	 *
131 	 * NOTE: only APLL truly matters here, but we'll do them all.
132 	 */
133 	mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
134 }
135 
clk_plls_resume(void)136 void clk_plls_resume(void)
137 {
138 	/* restore pll-modes */
139 	mmio_write_32(CRU_BASE + PLL_MODE_CON,
140 		      slp_data.pll_mode | REG_SOC_WMSK);
141 }
142 
clk_gate_con_save(void)143 void clk_gate_con_save(void)
144 {
145 	uint32_t i = 0;
146 
147 	for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
148 		slp_data.cru_gate_con[i] =
149 			mmio_read_32(CRU_BASE + CRU_CLKGATES_CON(i));
150 }
151 
clk_gate_con_disable(void)152 void clk_gate_con_disable(void)
153 {
154 	uint32_t i;
155 
156 	for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
157 		mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), REG_SOC_WMSK);
158 }
159 
clk_gate_con_restore(void)160 void clk_gate_con_restore(void)
161 {
162 	uint32_t i;
163 
164 	for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
165 		mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i),
166 			      REG_SOC_WMSK | slp_data.cru_gate_con[i]);
167 }
168 
clk_sel_con_save(void)169 void clk_sel_con_save(void)
170 {
171 	uint32_t i = 0;
172 
173 	for (i = 0; i < CRU_CLKSELS_CON_CNT; i++)
174 		slp_data.cru_sel_con[i] =
175 			mmio_read_32(CRU_BASE + CRU_CLKSELS_CON(i));
176 }
177 
clk_sel_con_restore(void)178 void clk_sel_con_restore(void)
179 {
180 	uint32_t i, val;
181 
182 	for (i = 0; i < CRU_CLKSELS_CON_CNT; i++) {
183 		/* fractional dividers don't have write-masks */
184 		if ((i >= 7 && i <= 9) ||
185 		    (i >= 17 && i <= 20) ||
186 		    (i == 23) || (i == 41))
187 			val = slp_data.cru_sel_con[i];
188 		else
189 			val = slp_data.cru_sel_con[i] | REG_SOC_WMSK;
190 
191 		mmio_write_32(CRU_BASE + CRU_CLKSELS_CON(i), val);
192 	}
193 }
194 
rockchip_soc_soft_reset(void)195 void __dead2 rockchip_soc_soft_reset(void)
196 {
197 	uint32_t temp_val;
198 
199 	/*
200 	 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
201 	 * avoid crashes on resume. The Mask ROM on the system will
202 	 * put APLL, CPLL, and GPLL into slow mode at resume time
203 	 * anyway (which is why we restore them), but we might not
204 	 * even make it to the Mask ROM if this isn't done at suspend
205 	 * time.
206 	 *
207 	 * NOTE: only APLL truly matters here, but we'll do them all.
208 	 */
209 	mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
210 
211 	temp_val = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON);
212 	temp_val &= ~PMU_RST_MASK;
213 	temp_val |= PMU_RST_BY_SECOND_SFT;
214 	mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, temp_val);
215 	mmio_write_32(CRU_BASE + CRU_GLB_SRST_SND, 0xeca8);
216 
217 	/*
218 	 * Maybe the HW needs some times to reset the system,
219 	 * so we do not hope the core to excute valid codes.
220 	 */
221 	while (1)
222 		;
223 }
224