blob: db90ae41bf53a8640fd9e33fdf214fe7f68c6e8f [file] [log] [blame]
Heiko Stuebner87b9a3c2019-03-14 22:12:04 +01001/*
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 */
19static struct deepsleep_data_s slp_data;
20
21/* Table of regions to map using the MMU. */
22const 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(UART_DBG_BASE, UART_DBG_SIZE,
38 MT_DEVICE | MT_RW | MT_SECURE),
39 MAP_REGION_FLAT(CRU_BASE, CRU_SIZE,
40 MT_DEVICE | MT_RW | MT_SECURE),
41 MAP_REGION_FLAT(GRF_BASE, GRF_SIZE,
42 MT_DEVICE | MT_RW | MT_SECURE),
43 MAP_REGION_FLAT(DDR_PCTL0_BASE, DDR_PCTL0_SIZE,
44 MT_DEVICE | MT_RW | MT_SECURE),
45 MAP_REGION_FLAT(DDR_PHY0_BASE, DDR_PHY0_SIZE,
46 MT_DEVICE | MT_RW | MT_SECURE),
47 MAP_REGION_FLAT(DDR_PCTL1_BASE, DDR_PCTL1_SIZE,
48 MT_DEVICE | MT_RW | MT_SECURE),
49 MAP_REGION_FLAT(DDR_PHY1_BASE, DDR_PHY1_SIZE,
50 MT_DEVICE | MT_RW | MT_SECURE),
51 MAP_REGION_FLAT(SERVICE_BUS_BASE, SERVICE_BUS_SIZE,
52 MT_DEVICE | MT_RW | MT_SECURE),
53 MAP_REGION_FLAT(CORE_AXI_BUS_BASE, CORE_AXI_BUS_SIZE,
54 MT_DEVICE | MT_RW | MT_SECURE),
55 { 0 }
56};
57
58/* The RockChip power domain tree descriptor */
59const unsigned char rockchip_power_domain_tree_desc[] = {
60 /* No of root nodes */
61 PLATFORM_SYSTEM_COUNT,
62 /* No of children for the root node */
63 PLATFORM_CLUSTER_COUNT,
64 /* No of children for the first cluster node */
65 PLATFORM_CLUSTER0_CORE_COUNT,
66};
67
68void plat_rockchip_soc_init(void)
69{
70 secure_timer_init();
71 secure_sgrf_init();
72 /*
73 * We cannot enable ddr security at this point, as the kernel
74 * seems to have an issue with it even living in the same 128MB
75 * memory block. Only when moving the kernel to the second
76 * 128MB block does it not conflict, but then we'd loose this
77 * memory area for use. Late maybe enable
78 * secure_sgrf_ddr_rgn_init();
79 */
80}
81
82void regs_update_bits(uintptr_t addr, uint32_t val,
83 uint32_t mask, uint32_t shift)
84{
85 uint32_t tmp, orig;
86
87 orig = mmio_read_32(addr);
88
89 tmp = orig & ~(mask << shift);
90 tmp |= (val & mask) << shift;
91
92 if (tmp != orig)
93 mmio_write_32(addr, tmp);
94 dsb();
95}
96
97static void pll_save(uint32_t pll_id)
98{
99 uint32_t *pll = slp_data.pll_con[pll_id];
100
101 pll[0] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 0));
102 pll[1] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 1));
103 pll[2] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 2));
104 pll[3] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 3));
105}
106
107void clk_plls_suspend(void)
108{
109 pll_save(NPLL_ID);
110 pll_save(CPLL_ID);
111 pll_save(GPLL_ID);
112 pll_save(APLL_ID);
113 slp_data.pll_mode = mmio_read_32(CRU_BASE + PLL_MODE_CON);
114
115 /*
116 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
117 * avoid crashes on resume. The Mask ROM on the system will
118 * put APLL, CPLL, and GPLL into slow mode at resume time
119 * anyway (which is why we restore them), but we might not
120 * even make it to the Mask ROM if this isn't done at suspend
121 * time.
122 *
123 * NOTE: only APLL truly matters here, but we'll do them all.
124 */
125 mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
126}
127
128void clk_plls_resume(void)
129{
130 /* restore pll-modes */
131 mmio_write_32(CRU_BASE + PLL_MODE_CON,
132 slp_data.pll_mode | REG_SOC_WMSK);
133}
134
135void clk_gate_con_save(void)
136{
137 uint32_t i = 0;
138
139 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
140 slp_data.cru_gate_con[i] =
141 mmio_read_32(CRU_BASE + CRU_CLKGATES_CON(i));
142}
143
144void clk_gate_con_disable(void)
145{
146 uint32_t i;
147
148 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
149 mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), REG_SOC_WMSK);
150}
151
152void clk_gate_con_restore(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),
158 REG_SOC_WMSK | slp_data.cru_gate_con[i]);
159}
160
161void clk_sel_con_save(void)
162{
163 uint32_t i = 0;
164
165 for (i = 0; i < CRU_CLKSELS_CON_CNT; i++)
166 slp_data.cru_sel_con[i] =
167 mmio_read_32(CRU_BASE + CRU_CLKSELS_CON(i));
168}
169
170void clk_sel_con_restore(void)
171{
172 uint32_t i, val;
173
174 for (i = 0; i < CRU_CLKSELS_CON_CNT; i++) {
175 /* fractional dividers don't have write-masks */
176 if ((i >= 7 && i <= 9) ||
177 (i >= 17 && i <= 20) ||
178 (i == 23) || (i == 41))
179 val = slp_data.cru_sel_con[i];
180 else
181 val = slp_data.cru_sel_con[i] | REG_SOC_WMSK;
182
183 mmio_write_32(CRU_BASE + CRU_CLKSELS_CON(i), val);
184 }
185}
186
187void __dead2 rockchip_soc_soft_reset(void)
188{
189 uint32_t temp_val;
190
191 /*
192 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
193 * avoid crashes on resume. The Mask ROM on the system will
194 * put APLL, CPLL, and GPLL into slow mode at resume time
195 * anyway (which is why we restore them), but we might not
196 * even make it to the Mask ROM if this isn't done at suspend
197 * time.
198 *
199 * NOTE: only APLL truly matters here, but we'll do them all.
200 */
201 mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
202
203 temp_val = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON);
204 temp_val &= ~PMU_RST_MASK;
205 temp_val |= PMU_RST_BY_SECOND_SFT;
206 mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, temp_val);
207 mmio_write_32(CRU_BASE + CRU_GLB_SRST_SND, 0xeca8);
208
209 /*
210 * Maybe the HW needs some times to reset the system,
211 * so we do not hope the core to excute valid codes.
212 */
213 while (1)
214 ;
215}