1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3 * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
4 */
5
6 #include <linux/init.h>
7 #include <linux/io.h>
8 #include <linux/kernel.h>
9 #include <linux/of.h>
10 #include <linux/of_address.h>
11 #include <linux/suspend.h>
12 #include <linux/mfd/syscon.h>
13
14 #include <asm/cacheflush.h>
15 #include <asm/fiq_glue.h>
16 #include <asm/tlbflush.h>
17 #include <asm/suspend.h>
18
19 #include "rkpm_gicv2.h"
20 #include "rkpm_helpers.h"
21 #include "rkpm_uart.h"
22
23 #include "rv1106_pm.h"
24
25 #define RV1106_PM_REG_REGION_MEM_SIZE SZ_4K
26
27 enum {
28 RV1106_GPIO_PULL_NONE,
29 RV1106_GPIO_PULL_UP,
30 RV1106_GPIO_PULL_DOWN,
31 RV1106_GPIO_PULL_UP_DOWN,
32 };
33
34 struct rockchip_pm_data {
35 const struct platform_suspend_ops *ops;
36 int (*init)(struct device_node *np);
37 };
38
39 struct rv1106_sleep_ddr_data {
40 u32 cru_gate_con[RV1106_CRU_GATE_CON_NUM];
41 u32 pmucru_gate_con[RV1106_PMUCRU_GATE_CON_NUM];
42 u32 pericru_gate_con[RV1106_PERICRU_GATE_CON_NUM];
43 u32 npucru_gate_con[RV1106_NPUCRU_GATE_CON_NUM];
44 u32 venccru_gate_con[RV1106_VENCCRU_GATE_CON_NUM];
45 u32 vicru_gate_con[RV1106_VICRU_GATE_CON_NUM];
46 u32 vocru_gate_con[RV1106_VOCRU_GATE_CON_NUM];
47
48 u32 ddrgrf_con1, ddrgrf_con2, ddrgrf_con3, ddrc_pwrctrl, ddrc_dfilpcfg0;
49 u32 pmucru_sel_con7;
50 u32 pmugrf_soc_con0, pmugrf_soc_con1, pmugrf_soc_con4, pmugrf_soc_con5;
51 u32 ioc0_1a_iomux_l, ioc1_1a_iomux_l;
52 u32 gpio0a_iomux_l, gpio0a_iomux_h, gpio0a0_pull;
53 u32 gpio0_ddr_l, gpio0_ddr_h;
54 u32 pmu_wkup_int_st, gpio0_int_st;
55 };
56
57 static struct rv1106_sleep_ddr_data ddr_data;
58
59 static void __iomem *pmucru_base;
60 static void __iomem *cru_base;
61 static void __iomem *pericru_base;
62 static void __iomem *vicru_base;
63 static void __iomem *npucru_base;
64 static void __iomem *corecru_base;
65 static void __iomem *venccru_base;
66 static void __iomem *vocru_base;
67
68 static void __iomem *perigrf_base;
69 static void __iomem *vencgrf_base;
70 static void __iomem *npugrf_base;
71 static void __iomem *pmugrf_base;
72 static void __iomem *ddrgrf_base;
73 static void __iomem *coregrf_base;
74 static void __iomem *vigrf_base;
75 static void __iomem *vogrf_base;
76 static void __iomem *perisgrf_base;
77 static void __iomem *visgrf_base;
78 static void __iomem *npusgrf_base;
79 static void __iomem *coresgrf_base;
80 static void __iomem *vencsgrf_base;
81 static void __iomem *vosgrf_base;
82 static void __iomem *pmusgrf_base;
83
84 static void __iomem *pmupvtm_base;
85 static void __iomem *uartdbg_base;
86 static void __iomem *pmu_base;
87 static void __iomem *gicd_base;
88 static void __iomem *gicc_base;
89 static void __iomem *firewall_ddr_base;
90 static void __iomem *firewall_syssram_base;
91 static void __iomem *pmu_base;
92 static void __iomem *nstimer_base;
93 static void __iomem *stimer_base;
94 static void __iomem *ddrc_base;
95 static void __iomem *ioc_base[5];
96 static void __iomem *gpio_base[5];
97 static void __iomem *rv1106_bootram_base;
98
99 #define WMSK_VAL 0xffff0000
100
101 static struct reg_region vd_core_reg_rgns[] = {
102 /* core_cru */
103 { REG_REGION(0x300, 0x310, 4, &corecru_base, WMSK_VAL)},
104 { REG_REGION(0x800, 0x804, 4, &corecru_base, WMSK_VAL)},
105
106 /* core_sgrf */
107 { REG_REGION(0x004, 0x014, 4, &coresgrf_base, 0)},
108 { REG_REGION(0x000, 0x000, 4, &coresgrf_base, 0)},
109 { REG_REGION(0x020, 0x030, 4, &coresgrf_base, WMSK_VAL)},
110 { REG_REGION(0x040, 0x040, 4, &coresgrf_base, WMSK_VAL)},
111 { REG_REGION(0x044, 0x044, 4, &coresgrf_base, 0)},
112
113 /* core grf */
114 { REG_REGION(0x004, 0x004, 4, &coregrf_base, WMSK_VAL)},
115 { REG_REGION(0x008, 0x010, 4, &coregrf_base, 0)},
116 { REG_REGION(0x024, 0x028, 4, &coregrf_base, 0)},
117 { REG_REGION(0x000, 0x000, 4, &coregrf_base, WMSK_VAL)},
118 { REG_REGION(0x02c, 0x02c, 4, &coregrf_base, WMSK_VAL)},
119 { REG_REGION(0x038, 0x03c, 4, &coregrf_base, WMSK_VAL)},
120 };
121
122 static struct reg_region vd_log_reg_rgns[] = {
123 /* firewall_ddr */
124 { REG_REGION(0x000, 0x03c, 4, &firewall_ddr_base, 0)},
125 { REG_REGION(0x040, 0x06c, 4, &firewall_ddr_base, 0)},
126 { REG_REGION(0x0f0, 0x0f0, 4, &firewall_ddr_base, 0)},
127
128 /* firewall_sram */
129 { REG_REGION(0x000, 0x01c, 4, &firewall_syssram_base, 0)},
130 { REG_REGION(0x040, 0x054, 4, &firewall_syssram_base, 0)},
131 { REG_REGION(0x0f0, 0x0f0, 4, &firewall_syssram_base, 0)},
132
133 /* cru */
134 { REG_REGION(0x000, 0x004, 4, &cru_base, WMSK_VAL)},
135 { REG_REGION(0x008, 0x008, 4, &cru_base, 0)},
136 { REG_REGION(0x00c, 0x010, 4, &cru_base, WMSK_VAL)},
137 { REG_REGION(0x020, 0x024, 4, &cru_base, WMSK_VAL)},
138 { REG_REGION(0x028, 0x028, 4, &cru_base, 0)},
139 { REG_REGION(0x02c, 0x030, 4, &cru_base, WMSK_VAL)},
140 { REG_REGION(0x060, 0x064, 4, &cru_base, WMSK_VAL)},
141 { REG_REGION(0x068, 0x068, 4, &cru_base, 0)},
142 { REG_REGION(0x06c, 0x070, 4, &cru_base, WMSK_VAL)},
143 { REG_REGION(0x140, 0x1bc, 4, &cru_base, 0)},
144 /* { REG_REGION(0x280, 0x280, 4, &cru_base, WMSK_VAL)}, */
145 { REG_REGION(0x300, 0x310, 4, &cru_base, WMSK_VAL)},
146 { REG_REGION(0x314, 0x34c, 8, &cru_base, WMSK_VAL)},
147 { REG_REGION(0x318, 0x350, 8, &cru_base, 0)},
148 { REG_REGION(0x354, 0x360, 4, &cru_base, WMSK_VAL)},
149 { REG_REGION(0x364, 0x37c, 8, &cru_base, WMSK_VAL)},
150 { REG_REGION(0x368, 0x380, 8, &cru_base, 0)},
151 { REG_REGION(0x384, 0x384, 4, &cru_base, WMSK_VAL)},
152 { REG_REGION(0x800, 0x80c, 4, &cru_base, WMSK_VAL)},
153 { REG_REGION(0xc00, 0xc00, 4, &cru_base, 0)},
154 { REG_REGION(0xc10, 0xc10, 4, &cru_base, 0)},
155 { REG_REGION(0xc14, 0xc28, 4, &cru_base, WMSK_VAL)},
156
157 /* npu_cru */
158 { REG_REGION(0x300, 0x300, 4, &npucru_base, WMSK_VAL)},
159 { REG_REGION(0x800, 0x804, 4, &npucru_base, WMSK_VAL)},
160
161 /* npu_sgrf */
162 { REG_REGION(0x004, 0x014, 4, &npusgrf_base, 0)},
163 { REG_REGION(0x000, 0x000, 4, &npusgrf_base, 0)},
164
165 /* peri_cru */
166 { REG_REGION(0x304, 0x32c, 4, &pericru_base, WMSK_VAL)},
167 { REG_REGION(0x800, 0x81c, 4, &pericru_base, WMSK_VAL)},
168
169 /* peri_sgrf */
170 { REG_REGION(0x004, 0x014, 4, &perisgrf_base, 0)},
171 { REG_REGION(0x000, 0x000, 4, &perisgrf_base, 0)},
172 { REG_REGION(0x020, 0x030, 4, &perisgrf_base, WMSK_VAL)},
173 { REG_REGION(0x080, 0x0a4, 4, &perisgrf_base, WMSK_VAL)},
174 { REG_REGION(0x0b8, 0x0bc, 4, &perisgrf_base, WMSK_VAL)},
175
176 /* vi_cru */
177 { REG_REGION(0x300, 0x30c, 4, &vicru_base, WMSK_VAL)},
178 { REG_REGION(0x800, 0x808, 4, &vicru_base, WMSK_VAL)},
179
180 /* vi_sgrf */
181 { REG_REGION(0x004, 0x014, 4, &visgrf_base, 0)},
182 { REG_REGION(0x000, 0x000, 4, &visgrf_base, 0)},
183
184 /* vo_cru */
185 { REG_REGION(0x300, 0x30c, 4, &vocru_base, WMSK_VAL)},
186 { REG_REGION(0x800, 0x80c, 4, &vocru_base, WMSK_VAL)},
187
188 /* vo_sgrf */
189 { REG_REGION(0x004, 0x014, 4, &vosgrf_base, 0)},
190 { REG_REGION(0x000, 0x000, 4, &vosgrf_base, 0)},
191 { REG_REGION(0x018, 0x018, 4, &vosgrf_base, WMSK_VAL)},
192
193 /* vepu_cru */
194 { REG_REGION(0x300, 0x304, 4, &venccru_base, WMSK_VAL)},
195 { REG_REGION(0x800, 0x808, 4, &venccru_base, WMSK_VAL)},
196
197 /* vepu_sgrf */
198 { REG_REGION(0x004, 0x014, 4, &vencsgrf_base, 0)},
199 { REG_REGION(0x000, 0x000, 4, &vencsgrf_base, 0)},
200
201 /* gpio1_ioc */
202 { REG_REGION(0x000, 0x018, 4, &ioc_base[1], WMSK_VAL)},
203 { REG_REGION(0x080, 0x0b4, 4, &ioc_base[1], WMSK_VAL)},
204 { REG_REGION(0x180, 0x18c, 4, &ioc_base[1], WMSK_VAL)},
205 { REG_REGION(0x1c0, 0x1cc, 4, &ioc_base[1], WMSK_VAL)},
206 { REG_REGION(0x200, 0x20c, 4, &ioc_base[1], WMSK_VAL)},
207 { REG_REGION(0x240, 0x24c, 4, &ioc_base[1], WMSK_VAL)},
208 { REG_REGION(0x280, 0x28c, 4, &ioc_base[1], WMSK_VAL)},
209 { REG_REGION(0x2c0, 0x2cc, 4, &ioc_base[1], WMSK_VAL)},
210 { REG_REGION(0x2f4, 0x2f4, 4, &ioc_base[1], WMSK_VAL)},
211
212 /* gpio2_ioc */
213 { REG_REGION(0x020, 0x028, 4, &ioc_base[2], WMSK_VAL)},
214 { REG_REGION(0x0c0, 0x0d0, 4, &ioc_base[2], WMSK_VAL)},
215 { REG_REGION(0x190, 0x194, 4, &ioc_base[2], WMSK_VAL)},
216 { REG_REGION(0x1d0, 0x1d4, 4, &ioc_base[2], WMSK_VAL)},
217 { REG_REGION(0x210, 0x214, 4, &ioc_base[2], WMSK_VAL)},
218 { REG_REGION(0x250, 0x254, 4, &ioc_base[2], WMSK_VAL)},
219 { REG_REGION(0x290, 0x294, 4, &ioc_base[2], WMSK_VAL)},
220 { REG_REGION(0x2d0, 0x2d4, 4, &ioc_base[2], WMSK_VAL)},
221
222 /* gpio3_ioc */
223 { REG_REGION(0x040, 0x058, 4, &ioc_base[3], WMSK_VAL)},
224 { REG_REGION(0x100, 0x10c, 4, &ioc_base[3], WMSK_VAL)},
225 { REG_REGION(0x128, 0x134, 4, &ioc_base[3], WMSK_VAL)},
226 { REG_REGION(0x1a0, 0x1ac, 4, &ioc_base[3], WMSK_VAL)},
227 { REG_REGION(0x1e0, 0x1ec, 4, &ioc_base[3], WMSK_VAL)},
228 { REG_REGION(0x220, 0x22c, 4, &ioc_base[3], WMSK_VAL)},
229 { REG_REGION(0x260, 0x26c, 4, &ioc_base[3], WMSK_VAL)},
230 { REG_REGION(0x2a0, 0x2ac, 4, &ioc_base[3], WMSK_VAL)},
231 { REG_REGION(0x2e0, 0x2ec, 4, &ioc_base[3], WMSK_VAL)},
232 { REG_REGION(0x2f4, 0x2f4, 4, &ioc_base[3], WMSK_VAL)},
233
234 /* gpio1~3 */
235 { REG_REGION(0x000, 0x00c, 4, &gpio_base[1], WMSK_VAL)},
236 { REG_REGION(0x018, 0x044, 4, &gpio_base[1], WMSK_VAL)},
237 { REG_REGION(0x048, 0x048, 4, &gpio_base[1], 0)},
238 { REG_REGION(0x060, 0x064, 4, &gpio_base[1], WMSK_VAL)},
239 { REG_REGION(0x100, 0x108, 4, &gpio_base[1], WMSK_VAL)},
240 { REG_REGION(0x010, 0x014, 4, &gpio_base[1], WMSK_VAL)},
241
242 { REG_REGION(0x000, 0x00c, 4, &gpio_base[2], WMSK_VAL)},
243 { REG_REGION(0x018, 0x044, 4, &gpio_base[2], WMSK_VAL)},
244 { REG_REGION(0x048, 0x048, 4, &gpio_base[2], 0)},
245 { REG_REGION(0x060, 0x064, 4, &gpio_base[2], WMSK_VAL)},
246 { REG_REGION(0x100, 0x108, 4, &gpio_base[2], WMSK_VAL)},
247 { REG_REGION(0x010, 0x014, 4, &gpio_base[2], WMSK_VAL)},
248
249 { REG_REGION(0x000, 0x00c, 4, &gpio_base[3], WMSK_VAL)},
250 { REG_REGION(0x018, 0x044, 4, &gpio_base[3], WMSK_VAL)},
251 { REG_REGION(0x048, 0x048, 4, &gpio_base[3], 0)},
252 { REG_REGION(0x060, 0x064, 4, &gpio_base[3], WMSK_VAL)},
253 { REG_REGION(0x100, 0x108, 4, &gpio_base[3], WMSK_VAL)},
254 { REG_REGION(0x010, 0x014, 4, &gpio_base[3], WMSK_VAL)},
255
256 /* NS TIMER 6 channel */
257 { REG_REGION(0x00, 0x04, 4, &nstimer_base, 0)},
258 { REG_REGION(0x10, 0x10, 4, &nstimer_base, 0)},
259 { REG_REGION(0x20, 0x24, 4, &nstimer_base, 0)},
260 { REG_REGION(0x30, 0x30, 4, &nstimer_base, 0)},
261 { REG_REGION(0x40, 0x44, 4, &nstimer_base, 0)},
262 { REG_REGION(0x50, 0x50, 4, &nstimer_base, 0)},
263 { REG_REGION(0x60, 0x64, 4, &nstimer_base, 0)},
264 { REG_REGION(0x70, 0x70, 4, &nstimer_base, 0)},
265 { REG_REGION(0x80, 0x84, 4, &nstimer_base, 0)},
266 { REG_REGION(0x90, 0x90, 4, &nstimer_base, 0)},
267 { REG_REGION(0xa0, 0xa4, 4, &nstimer_base, 0)},
268 { REG_REGION(0xb0, 0xb0, 4, &nstimer_base, 0)},
269
270 /* S TIMER0 2 channel */
271 { REG_REGION(0x00, 0x04, 4, &stimer_base, 0)},
272 { REG_REGION(0x10, 0x10, 4, &stimer_base, 0)},
273 { REG_REGION(0x20, 0x24, 4, &stimer_base, 0)},
274 { REG_REGION(0x30, 0x30, 4, &stimer_base, 0)},
275 };
276
277 #define PLL_LOCKED_TIMEOUT 600000U
278
pm_pll_wait_lock(u32 pll_id)279 static void pm_pll_wait_lock(u32 pll_id)
280 {
281 int delay = PLL_LOCKED_TIMEOUT;
282
283 if (readl_relaxed(cru_base + RV1106_CRU_PLL_CON(pll_id, 1)) & CRU_PLLCON1_PWRDOWN)
284 return;
285
286 while (delay-- >= 0) {
287 if (readl_relaxed(cru_base + RV1106_CRU_PLL_CON(pll_id, 1)) &
288 CRU_PLLCON1_LOCK_STATUS)
289 break;
290
291 rkpm_raw_udelay(1);
292 }
293
294 if (delay <= 0) {
295 rkpm_printstr("Can't wait pll lock: ");
296 rkpm_printhex(pll_id);
297 rkpm_printch('\n');
298 }
299 }
300
301 struct plat_gicv2_dist_ctx_t gicd_ctx_save;
302 struct plat_gicv2_cpu_ctx_t gicc_ctx_save;
303
gic400_save(void)304 static void gic400_save(void)
305 {
306 rkpm_gicv2_cpu_save(gicd_base, gicc_base, &gicc_ctx_save);
307 rkpm_gicv2_dist_save(gicd_base, &gicd_ctx_save);
308 }
309
gic400_restore(void)310 static void gic400_restore(void)
311 {
312 rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
313 rkpm_gicv2_cpu_restore(gicd_base, gicc_base, &gicc_ctx_save);
314 }
315
uart_wrtie_byte(uint8_t byte)316 static void uart_wrtie_byte(uint8_t byte)
317 {
318 writel_relaxed(byte, uartdbg_base + 0x0);
319
320 while (!(readl_relaxed(uartdbg_base + 0x14) & 0x40))
321 ;
322 }
323
rkpm_printch(int c)324 void rkpm_printch(int c)
325 {
326 if (c == '\n')
327 uart_wrtie_byte('\r');
328
329 uart_wrtie_byte(c);
330 }
331
332 #define RV1106_DUMP_GPIO_INTEN(id) \
333 do { \
334 rkpm_printstr("GPIO"); \
335 rkpm_printdec(id); \
336 rkpm_printstr(": "); \
337 rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_EN_L)); \
338 rkpm_printch(' '); \
339 rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_EN_H)); \
340 rkpm_printch(' '); \
341 rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_MASK_L)); \
342 rkpm_printch(' '); \
343 rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_MASK_H)); \
344 rkpm_printch(' '); \
345 rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_STATUS)); \
346 rkpm_printch(' '); \
347 rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_RAWSTATUS));\
348 rkpm_printch('\n'); \
349 } while (0)
350
rv1106_dbg_pmu_wkup_src(void)351 static void rv1106_dbg_pmu_wkup_src(void)
352 {
353 u32 pmu_int_st = ddr_data.pmu_wkup_int_st;
354
355 rkpm_printstr("wake up status:");
356 rkpm_printhex(pmu_int_st);
357 rkpm_printch('\n');
358
359 if (pmu_int_st)
360 rkpm_printstr("wake up information:\n");
361
362 if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_GPIO_INT_EN)) {
363 rkpm_printstr("GPIO0 interrupt wakeup:");
364 rkpm_printhex(ddr_data.gpio0_int_st);
365 rkpm_printch('\n');
366 }
367
368 if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_SDMMC_EN))
369 rkpm_printstr("PWM detect wakeup\n");
370
371 if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_SDIO_EN))
372 rkpm_printstr("GMAC interrupt wakeup\n");
373
374 if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMER_EN))
375 rkpm_printstr("TIMER interrupt wakeup\n");
376
377 if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_USBDEV_EN))
378 rkpm_printstr("USBDEV detect wakeup\n");
379
380 if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN))
381 rkpm_printstr("TIMEOUT interrupt wakeup\n");
382
383 rkpm_printch('\n');
384 }
385
rv1106_dbg_irq_prepare(void)386 static void rv1106_dbg_irq_prepare(void)
387 {
388 RV1106_DUMP_GPIO_INTEN(0);
389 }
390
rv1106_dbg_irq_finish(void)391 static void rv1106_dbg_irq_finish(void)
392 {
393 rv1106_dbg_pmu_wkup_src();
394 }
395
rv1106_l2_config(void)396 static inline u32 rv1106_l2_config(void)
397 {
398 u32 l2ctlr;
399
400 asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (l2ctlr));
401 return l2ctlr;
402 }
403
rv1106_config_bootdata(void)404 static void __init rv1106_config_bootdata(void)
405 {
406 rkpm_bootdata_cpusp = RV1106_PMUSRAM_BASE + (SZ_8K - 8);
407 rkpm_bootdata_cpu_code = __pa_symbol(cpu_resume);
408
409 rkpm_bootdata_l2ctlr_f = 1;
410 rkpm_bootdata_l2ctlr = rv1106_l2_config();
411 }
412
clock_suspend(void)413 static void clock_suspend(void)
414 {
415 int i;
416
417 for (i = 0; i < RV1106_CRU_GATE_CON_NUM; i++) {
418 ddr_data.cru_gate_con[i] =
419 readl_relaxed(cru_base + RV1106_CRU_GATE_CON(i));
420 writel_relaxed(0xffff0000, cru_base + RV1106_CRU_GATE_CON(i));
421 }
422
423 for (i = 0; i < RV1106_PMUCRU_GATE_CON_NUM; i++) {
424 ddr_data.pmucru_gate_con[i] =
425 readl_relaxed(pmucru_base + RV1106_PMUCRU_GATE_CON(i));
426 writel_relaxed(0xffff0000, pmucru_base + RV1106_PMUCRU_GATE_CON(i));
427 }
428
429 for (i = 0; i < RV1106_PERICRU_GATE_CON_NUM; i++) {
430 ddr_data.pericru_gate_con[i] =
431 readl_relaxed(pericru_base + RV1106_PERICRU_GATE_CON(i));
432 writel_relaxed(0xffff0000, pericru_base + RV1106_PERICRU_GATE_CON(i));
433 }
434
435 for (i = 0; i < RV1106_NPUCRU_GATE_CON_NUM; i++) {
436 ddr_data.npucru_gate_con[i] =
437 readl_relaxed(npucru_base + RV1106_NPUCRU_GATE_CON(i));
438 writel_relaxed(0xffff0000, npucru_base + RV1106_NPUCRU_GATE_CON(i));
439 }
440
441 for (i = 0; i < RV1106_VENCCRU_GATE_CON_NUM; i++) {
442 ddr_data.venccru_gate_con[i] =
443 readl_relaxed(venccru_base + RV1106_VENCCRU_GATE_CON(i));
444 writel_relaxed(0xffff0000, venccru_base + RV1106_VENCCRU_GATE_CON(i));
445 }
446
447 for (i = 0; i < RV1106_VICRU_GATE_CON_NUM; i++) {
448 ddr_data.vicru_gate_con[i] =
449 readl_relaxed(vicru_base + RV1106_VICRU_GATE_CON(i));
450 writel_relaxed(0xffff0000, vicru_base + RV1106_VICRU_GATE_CON(i));
451 }
452
453 for (i = 0; i < RV1106_VOCRU_GATE_CON_NUM; i++) {
454 ddr_data.vocru_gate_con[i] =
455 readl_relaxed(vocru_base + RV1106_VOCRU_GATE_CON(i));
456 writel_relaxed(0xffff0000, vocru_base + RV1106_VOCRU_GATE_CON(i));
457 }
458 }
459
clock_resume(void)460 static void clock_resume(void)
461 {
462 int i;
463
464 for (i = 0; i < RV1106_CRU_GATE_CON_NUM; i++)
465 writel_relaxed(WITH_16BITS_WMSK(ddr_data.cru_gate_con[i]),
466 cru_base + RV1106_CRU_GATE_CON(i));
467
468 for (i = 0; i < RV1106_PMUCRU_GATE_CON_NUM; i++)
469 writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmucru_gate_con[i]),
470 pmucru_base + RV1106_PMUCRU_GATE_CON(i));
471
472 for (i = 0; i < RV1106_PERICRU_GATE_CON_NUM; i++)
473 writel_relaxed(WITH_16BITS_WMSK(ddr_data.pericru_gate_con[i]),
474 pericru_base + RV1106_PERICRU_GATE_CON(i));
475
476 for (i = 0; i < RV1106_NPUCRU_GATE_CON_NUM; i++)
477 writel_relaxed(WITH_16BITS_WMSK(ddr_data.npucru_gate_con[i]),
478 npucru_base + RV1106_NPUCRU_GATE_CON(i));
479
480 for (i = 0; i < RV1106_VENCCRU_GATE_CON_NUM; i++)
481 writel_relaxed(WITH_16BITS_WMSK(ddr_data.venccru_gate_con[i]),
482 venccru_base + RV1106_VENCCRU_GATE_CON(i));
483
484 for (i = 0; i < RV1106_VICRU_GATE_CON_NUM; i++)
485 writel_relaxed(WITH_16BITS_WMSK(ddr_data.vicru_gate_con[i]),
486 vicru_base + RV1106_VICRU_GATE_CON(i));
487
488 for (i = 0; i < RV1106_VOCRU_GATE_CON_NUM; i++)
489 writel_relaxed(WITH_16BITS_WMSK(ddr_data.vocru_gate_con[i]),
490 vocru_base + RV1106_VOCRU_GATE_CON(i));
491 }
492
pvtm_32k_config(int flag)493 static void pvtm_32k_config(int flag)
494 {
495 int value;
496 int pvtm_freq_khz, pvtm_div;
497 int sleep_clk_freq_khz;
498
499 ddr_data.pmucru_sel_con7 =
500 readl_relaxed(pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
501
502 if (flag) {
503 writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 6), vigrf_base + 0x0);
504 writel_relaxed(BITS_WITH_WMASK(0x4, 0xf, 0), ioc_base[0] + 0);
505 writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 15),
506 pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
507 writel_relaxed(BITS_WITH_WMASK(0x1, 0x3, 0),
508 pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
509 } else {
510 writel_relaxed(BITS_WITH_WMASK(0, 0x3, 0),
511 pmupvtm_base + RV1106_PVTM_CON(2));
512 writel_relaxed(RV1106_PVTM_CALC_CNT,
513 pmupvtm_base + RV1106_PVTM_CON(1));
514 writel_relaxed(BITS_WITH_WMASK(0, 0x3, PVTM_START),
515 pmupvtm_base + RV1106_PVTM_CON(0));
516 dsb();
517
518 writel_relaxed(BITS_WITH_WMASK(0, 0x7, PVTM_OSC_SEL),
519 pmupvtm_base + RV1106_PVTM_CON(0));
520 writel_relaxed(BITS_WITH_WMASK(1, 0x1, PVTM_OSC_EN),
521 pmupvtm_base + RV1106_PVTM_CON(0));
522 writel_relaxed(BITS_WITH_WMASK(1, 0x1, PVTM_RND_SEED_EN),
523 pmupvtm_base + RV1106_PVTM_CON(0));
524 dsb();
525
526 writel_relaxed(BITS_WITH_WMASK(1, 0x1, PVTM_START),
527 pmupvtm_base + RV1106_PVTM_CON(0));
528 dsb();
529
530 while (readl_relaxed(pmupvtm_base + RV1106_PVTM_STATUS(1)) < 30)
531 ;
532
533 dsb();
534
535 while (!readl_relaxed(pmupvtm_base + RV1106_PVTM_STATUS(0)) & 0x1)
536 ;
537
538 value = (readl_relaxed(pmupvtm_base + RV1106_PVTM_STATUS(1)));
539 pvtm_freq_khz = (value * 24000 + RV1106_PVTM_CALC_CNT / 2) / RV1106_PVTM_CALC_CNT;
540 pvtm_div = (pvtm_freq_khz + 16) / 32 - 1;
541 if (pvtm_div > 0xfff)
542 pvtm_div = 0xfff;
543
544 writel_relaxed(WITH_16BITS_WMSK(pvtm_div),
545 pmugrf_base + RV1106_PMUGRF_SOC_CON(3));
546
547 /* select 32k source */
548 writel_relaxed(BITS_WITH_WMASK(0x2, 0x3, 0),
549 pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
550
551 sleep_clk_freq_khz = pvtm_freq_khz / (pvtm_div + 1);
552
553 rkpm_printstr("pvtm real_freq (khz):");
554 rkpm_printhex(sleep_clk_freq_khz);
555 rkpm_printch('\n');
556 }
557 }
558
pvtm_32k_config_restore(void)559 static void pvtm_32k_config_restore(void)
560 {
561 writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmucru_sel_con7),
562 pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
563 }
564
ddr_sleep_config(void)565 static void ddr_sleep_config(void)
566 {
567 u32 val;
568
569 ddr_data.ddrc_pwrctrl = readl_relaxed(ddrc_base + 0x30);
570 ddr_data.ddrgrf_con1 = readl_relaxed(ddrgrf_base + RV1106_DDRGRF_CON(1));
571 ddr_data.ddrgrf_con2 = readl_relaxed(ddrgrf_base + RV1106_DDRGRF_CON(2));
572 ddr_data.ddrgrf_con3 = readl_relaxed(ddrgrf_base + RV1106_DDRGRF_CON(3));
573 ddr_data.ddrc_dfilpcfg0 = readl_relaxed(ddrc_base + 0x198);
574 ddr_data.pmugrf_soc_con0 = readl_relaxed(pmugrf_base + RV1106_PMUGRF_SOC_CON(0));
575
576 val = readl_relaxed(ddrc_base + 0x30);
577 writel_relaxed(val & ~(BIT(0) | BIT(1)), ddrc_base + 0x30);
578
579 /* disable ddr auto gt */
580 writel_relaxed(BITS_WITH_WMASK(0x12, 0x1f, 0), ddrgrf_base + RV1106_DDRGRF_CON(1));
581
582 writel_relaxed(BITS_WITH_WMASK(0x3ff, 0x3ff, 0), ddrgrf_base + RV1106_DDRGRF_CON(2));
583
584 /* ddr low power request by pmu */
585 writel_relaxed(BITS_WITH_WMASK(0x3, 0x3, 8), ddrgrf_base + RV1106_DDRGRF_CON(3));
586
587 while ((readl_relaxed(ddrc_base + 0x4) & 0x7) != 0x1)
588 continue;
589
590 val = readl_relaxed(ddrc_base + 0x198) & ~(0xf << 12 | 0xf << 4);
591 val |= (0xa << 12 | 0xa << 4);
592 writel_relaxed(val, ddrc_base + 0x198);
593
594 val = readl_relaxed(ddrc_base + 0x198) | BIT(8) | BIT(0);
595 writel_relaxed(val, ddrc_base + 0x198);
596
597 /* ddr io ret by pmu */
598 writel_relaxed(BITS_WITH_WMASK(0x0, 0x7, 9), pmugrf_base + RV1106_PMUGRF_SOC_CON(0));
599 }
600
ddr_sleep_config_restore(void)601 static void ddr_sleep_config_restore(void)
602 {
603 writel_relaxed(WITH_16BITS_WMSK(ddr_data.ddrgrf_con3),
604 ddrgrf_base + RV1106_DDRGRF_CON(3));
605 }
606
pmu_sleep_config(void)607 static void pmu_sleep_config(void)
608 {
609 u32 clk_freq_khz = 32;
610 u32 pmu_wkup_con, pmu_pwr_con, pmu_scu_con, pmu_ddr_con;
611 u32 pmu_bus_idle_con, pmu_cru_con[2], pmu_pll_con;
612
613 ddr_data.pmugrf_soc_con1 = readl_relaxed(pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
614 ddr_data.pmugrf_soc_con4 = readl_relaxed(pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
615 ddr_data.pmugrf_soc_con5 = readl_relaxed(pmugrf_base + RV1106_PMUGRF_SOC_CON(5));
616 ddr_data.ioc1_1a_iomux_l = readl_relaxed(ioc_base[1] + 0);
617
618 pmu_wkup_con =
619 /* BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN) | */
620 /* BIT(RV1106_PMU_WAKEUP_CPU_INT_EN) | */
621 BIT(RV1106_PMU_WAKEUP_GPIO_INT_EN) |
622 0;
623
624 pmu_pwr_con =
625 BIT(RV1106_PMU_PWRMODE_EN) |
626 /* BIT(RV1106_PMU_BUS_BYPASS) | */
627 /* BIT(RV1106_PMU_DDR_BYPASS) | */
628 /* BIT(RV1106_PMU_CRU_BYPASS) | */
629 0;
630
631 pmu_scu_con =
632 BIT(RV1106_PMU_SCU_INT_MASK_ENA) |
633 BIT(RV1106_PMU_CPU_INT_MASK_ENA) |
634 0;
635
636 pmu_bus_idle_con =
637 BIT(RV1106_PMU_IDLE_REQ_MSCH) |
638 BIT(RV1106_PMU_IDLE_REQ_DDR) |
639 BIT(RV1106_PMU_IDLE_REQ_NPU) |
640 BIT(RV1106_PMU_IDLE_REQ_NPU_ACLK) |
641 BIT(RV1106_PMU_IDLE_REQ_VI) |
642 BIT(RV1106_PMU_IDLE_REQ_VO) |
643 BIT(RV1106_PMU_IDLE_REQ_PERI) |
644 BIT(RV1106_PMU_IDLE_REQ_CRU) |
645 BIT(RV1106_PMU_IDLE_REQ_CPU) |
646 BIT(RV1106_PMU_IDLE_REQ_VENC_COM) |
647 BIT(RV1106_PMU_IDLE_REQ_VEPU) |
648 0;
649
650 pmu_cru_con[0] =
651 BIT(RV1106_PMU_ALIVE_32K_ENA) |
652 BIT(RV1106_PMU_OSC_DIS_ENA) |
653 BIT(RV1106_PMU_WAKEUP_RST_ENA) |
654 BIT(RV1106_PMU_INPUT_CLAMP_ENA) |
655 /* BIT(RV1106_PMU_ALIVE_OSC_ENA) | */
656 BIT(RV1106_PMU_POWER_OFF_ENA) |
657 0;
658
659 pmu_cru_con[1] =
660 /* BIT(RV1106_PMU_VI_CLK_SRC_GATE_ENA) | */
661 /* BIT(RV1106_PMU_VO_CLK_SRC_GATE_ENA) | */
662 /* BIT(RV1106_PMU_VENC_CLK_SRC_GATE_ENA) | */
663 /* BIT(RV1106_PMU_NPU_CLK_SRC_GATE_ENA) | */
664 /* BIT(RV1106_PMU_DDR_CLK_SRC_CATE_ENA) | */
665 /* BIT(RV1106_PMU_PERI_CLK_SRC_GATE_ENA) | */
666 /* BIT(RV1106_PMU_CORE_CLK_SRC_GATE_ENA) | */
667 /* BIT(RV1106_PMU_CRU_CLK_SRC_GATE_ENA) | */
668 0;
669
670 pmu_ddr_con =
671 BIT(RV1106_PMU_DDR_SREF_C_ENA) |
672 #if !RV1106_WAKEUP_TO_SYSTEM_RESET
673 BIT(RV1106_PMU_DDRIO_RET_ENA) |
674 #endif
675 BIT(RV1106_PMU_DDRCTL_C_AUTO_GATING_ENA) |
676 BIT(RV1106_PMU_MSCH_AUTO_GATING_ENA) |
677 BIT(RV1106_PMU_DDR_SREF_A_ENA) |
678 BIT(RV1106_PMU_DDRCTL_A_AUTO_GATING_ENA) |
679 0;
680
681 pmu_pll_con =
682 BIT(RV1106_PMU_APLL_PD_ENA) |
683 BIT(RV1106_PMU_DPLL_PD_ENA) |
684 BIT(RV1106_PMU_CPLL_PD_ENA) |
685 BIT(RV1106_PMU_GPLL_PD_ENA) |
686 0;
687
688 /* pmic_sleep */
689 /* gpio0_a3 activelow, gpio0_a4 active high */
690 writel_relaxed(BITS_WITH_WMASK(0x4, 0x7, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
691 /* select sleep func */
692 writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
693 /* gpio0_a3 iomux */
694 writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 12), ioc_base[0] + 0);
695
696 /* pmu_debug */
697 writel_relaxed(0xffffff01, pmu_base + RV1106_PMU_INFO_TX_CON);
698 writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 4), ioc_base[1] + 0);
699
700 /* pmu count */
701 writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_OSC_STABLE_CNT);
702 writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_PMIC_STABLE_CNT);
703 writel_relaxed(clk_freq_khz * 3000, pmu_base + RV1106_PMU_WAKEUP_TIMEOUT_CNT);
704
705 /* Pmu's clk has switched to 24M back When pmu FSM counts
706 * the follow counters, so we should use 24M to calculate
707 * these counters.
708 */
709 writel_relaxed(24000 * 2, pmu_base + RV1106_PMU_WAKEUP_RSTCLR_CNT);
710 writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PLL_LOCK_CNT);
711 writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PWM_SWITCH_CNT);
712
713 /* pmu reset hold */
714 writel_relaxed(0xffffffff, pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
715 writel_relaxed(0xffffff47, pmugrf_base + RV1106_PMUGRF_SOC_CON(5));
716
717 writel_relaxed(0x00010001, pmu_base + RV1106_PMU_INT_MASK_CON);
718 writel_relaxed(WITH_16BITS_WMSK(pmu_scu_con), pmu_base + RV1106_PMU_SCU_PWR_CON);
719
720 writel_relaxed(WITH_16BITS_WMSK(pmu_cru_con[0]), pmu_base + RV1106_PMU_CRU_PWR_CON0);
721 writel_relaxed(WITH_16BITS_WMSK(pmu_cru_con[1]), pmu_base + RV1106_PMU_CRU_PWR_CON1);
722 writel_relaxed(WITH_16BITS_WMSK(pmu_bus_idle_con), pmu_base + RV1106_PMU_BIU_IDLE_CON);
723
724 writel_relaxed(WITH_16BITS_WMSK(pmu_ddr_con), pmu_base + RV1106_PMU_DDR_PWR_CON);
725 writel_relaxed(WITH_16BITS_WMSK(pmu_pll_con), pmu_base + RV1106_PMU_PLLPD_CON);
726 writel_relaxed(pmu_wkup_con, pmu_base + RV1106_PMU_WAKEUP_INT_CON);
727 writel_relaxed(WITH_16BITS_WMSK(pmu_pwr_con), pmu_base + RV1106_PMU_PWR_CON);
728
729 #if RV1106_WAKEUP_TO_SYSTEM_RESET
730 writel_relaxed(0, pmugrf_base + RV1106_PMUGRF_OS_REG(9));
731 /* Use PMUGRF_OS_REG10 to save wakeup source */
732 writel_relaxed(0, pmugrf_base + RV1106_PMUGRF_OS_REG(10));
733 #else
734 writel_relaxed(PMU_SUSPEND_MAGIC, pmugrf_base + RV1106_PMUGRF_OS_REG(9));
735 #endif
736 }
737
pmu_sleep_restore(void)738 static void pmu_sleep_restore(void)
739 {
740 ddr_data.pmu_wkup_int_st = readl_relaxed(pmu_base + RV1106_PMU_WAKEUP_INT_ST);
741 ddr_data.gpio0_int_st = readl_relaxed(gpio_base[0] + RV1106_GPIO_INT_STATUS);
742
743 writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_INFO_TX_CON);
744 writel_relaxed(0x00010000, pmu_base + RV1106_PMU_INT_MASK_CON);
745 writel_relaxed(0x00000000, pmu_base + RV1106_PMU_WAKEUP_INT_CON);
746 writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_PWR_CON);
747 writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_BIU_IDLE_CON);
748 writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_DDR_PWR_CON);
749 writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_SCU_PWR_CON);
750 writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_PLLPD_CON);
751 writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_CRU_PWR_CON0);
752 writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_CRU_PWR_CON1);
753
754 writel_relaxed(WITH_16BITS_WMSK(ddr_data.ioc1_1a_iomux_l),
755 ioc_base[1] + 0);
756 writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmugrf_soc_con1),
757 pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
758 writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmugrf_soc_con4),
759 pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
760 writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmugrf_soc_con5),
761 pmugrf_base + RV1106_PMUGRF_SOC_CON(5));
762 }
763
soc_sleep_config(void)764 static void soc_sleep_config(void)
765 {
766 ddr_data.ioc0_1a_iomux_l = readl_relaxed(ioc_base[0] + 0);
767
768 rkpm_printch('a');
769
770 pvtm_32k_config(0);
771 rkpm_printch('b');
772
773 ddr_sleep_config();
774 rkpm_printch('c');
775
776 pmu_sleep_config();
777 rkpm_printch('d');
778 }
779
soc_sleep_restore(void)780 static void soc_sleep_restore(void)
781 {
782 rkpm_printch('d');
783
784 pmu_sleep_restore();
785 rkpm_printch('c');
786
787 ddr_sleep_config_restore();
788 rkpm_printch('b');
789
790 pvtm_32k_config_restore();
791 rkpm_printch('a');
792
793 writel_relaxed(WITH_16BITS_WMSK(ddr_data.ioc0_1a_iomux_l),
794 ioc_base[0] + 0);
795 }
796
plls_suspend(void)797 static void plls_suspend(void)
798 {
799 }
800
plls_resume(void)801 static void plls_resume(void)
802 {
803 }
804
gpio0_set_iomux(u32 pin_id,u32 func)805 static void gpio0_set_iomux(u32 pin_id, u32 func)
806 {
807 u32 sft = (pin_id % 4) << 2;
808
809 if (pin_id < 4)
810 writel_relaxed(BITS_WITH_WMASK(func, 0xf, sft), ioc_base[0] + 0);
811 else
812 writel_relaxed(BITS_WITH_WMASK(func, 0xf, sft), ioc_base[0] + 4);
813 }
814
gpio0_set_pull(u32 pin_id,int pull)815 static void gpio0_set_pull(u32 pin_id, int pull)
816 {
817 u32 sft = (pin_id % 8) << 1;
818
819 writel_relaxed(BITS_WITH_WMASK(pull, 0x3, sft), ioc_base[0] + 0x38);
820 }
821
gpio0_set_direct(u32 pin_id,int out)822 static void gpio0_set_direct(u32 pin_id, int out)
823 {
824 u32 sft = (pin_id % 16);
825
826 if (pin_id < 16)
827 writel_relaxed(BITS_WITH_WMASK(out, 0x1, sft),
828 gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
829 else
830 writel_relaxed(BITS_WITH_WMASK(out, 0x1, sft),
831 gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
832 }
833
gpio_config(void)834 static void gpio_config(void)
835 {
836 ddr_data.gpio0a_iomux_l = readl_relaxed(ioc_base[0] + 0);
837 ddr_data.gpio0a_iomux_h = readl_relaxed(ioc_base[0] + 0x4);
838 ddr_data.gpio0a0_pull = readl_relaxed(ioc_base[0] + 0x38);
839 ddr_data.gpio0_ddr_l = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
840 ddr_data.gpio0_ddr_h = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
841
842 /* gpio0_a0, input, pulldown */
843 gpio0_set_iomux(0, 0);
844 gpio0_set_pull(0, RV1106_GPIO_PULL_DOWN);
845 gpio0_set_direct(0, 0);
846
847 #ifdef RV1106_GPIO0_A1_LOWPOWER
848 /* gpio0_a1, input, pulldown */
849 gpio0_set_iomux(1, 0);
850 gpio0_set_pull(1, RV1106_GPIO_PULL_DOWN);
851 gpio0_set_direct(1, 0);
852 #endif
853 /* gpio0_a2, input, pulldown */
854 gpio0_set_iomux(2, 0);
855 gpio0_set_pull(2, RV1106_GPIO_PULL_DOWN);
856 gpio0_set_direct(2, 0);
857
858 /* gpio0_a3, pullnone */
859 gpio0_set_pull(3, RV1106_GPIO_PULL_NONE);
860
861 /* gpio0_a4, input, pulldown */
862 gpio0_set_iomux(4, 0);
863 gpio0_set_pull(4, RV1106_GPIO_PULL_DOWN);
864 gpio0_set_direct(4, 0);
865
866 /* gpio0_a5, input, pullnone */
867 gpio0_set_iomux(5, 0);
868 gpio0_set_pull(5, RV1106_GPIO_PULL_NONE);
869 gpio0_set_direct(5, 0);
870
871 /* gpio0_a6, input, pullnone */
872 gpio0_set_iomux(6, 0);
873 gpio0_set_pull(6, RV1106_GPIO_PULL_NONE);
874 gpio0_set_direct(6, 0);
875 }
876
gpio_restore(void)877 static void gpio_restore(void)
878 {
879 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l), ioc_base[0] + 0);
880 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h), ioc_base[0] + 0x4);
881
882 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a0_pull), ioc_base[0] + 0x38);
883
884 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0_ddr_l),
885 gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
886 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0_ddr_h),
887 gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
888 }
889
890 static struct uart_debug_ctx debug_port_save;
891 static u32 cru_mode;
892
vd_log_regs_save(void)893 static void vd_log_regs_save(void)
894 {
895 cru_mode = readl_relaxed(cru_base + 0x280);
896
897 rkpm_printch('a');
898
899 gic400_save();
900 rkpm_printch('b');
901
902 rkpm_reg_rgn_save(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns));
903 rkpm_printch('c');
904 rkpm_reg_rgn_save(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns));
905 rkpm_printch('d');
906
907 rkpm_uart_debug_save(uartdbg_base, &debug_port_save);
908 rkpm_printch('e');
909 }
910
vd_log_regs_restore(void)911 static void vd_log_regs_restore(void)
912 {
913 rkpm_uart_debug_restore(uartdbg_base, &debug_port_save);
914
915 /* slow mode */
916 writel_relaxed(0x003f0000, cru_base + 0x280);
917
918 rkpm_reg_rgn_restore(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns));
919 rkpm_reg_rgn_restore(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns));
920
921 /* wait lock */
922 pm_pll_wait_lock(RV1106_APLL_ID);
923 pm_pll_wait_lock(RV1106_CPLL_ID);
924 pm_pll_wait_lock(RV1106_GPLL_ID);
925
926 /* restore mode */
927 writel_relaxed(WITH_16BITS_WMSK(cru_mode), cru_base + 0x280);
928
929 gic400_restore();
930 }
931
rkpm_reg_rgns_init(void)932 static void rkpm_reg_rgns_init(void)
933 {
934 rkpm_alloc_region_mem(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns));
935 rkpm_alloc_region_mem(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns));
936 }
937
rkpm_regs_rgn_dump(void)938 static void rkpm_regs_rgn_dump(void)
939 {
940 return;
941
942 rkpm_dump_reg_rgns(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns));
943 rkpm_dump_reg_rgns(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns));
944 }
945
rockchip_lpmode_enter(unsigned long arg)946 static int rockchip_lpmode_enter(unsigned long arg)
947 {
948 flush_cache_all();
949
950 cpu_do_idle();
951
952 pr_err("%s: Failed to suspend\n", __func__);
953
954 return 1;
955 }
956
rv1106_suspend_enter(suspend_state_t state)957 static int rv1106_suspend_enter(suspend_state_t state)
958 {
959 rkpm_printstr("rv1106 enter sleep\n");
960
961 local_fiq_disable();
962
963 rv1106_dbg_irq_prepare();
964
965 rkpm_printch('-');
966
967 clock_suspend();
968 rkpm_printch('0');
969
970 soc_sleep_config();
971 rkpm_printch('1');
972
973 plls_suspend();
974 rkpm_printch('2');
975
976 gpio_config();
977 rkpm_printch('3');
978
979 vd_log_regs_save();
980 rkpm_regs_rgn_dump();
981 rkpm_printch('4');
982
983 rkpm_printstr("-WFI-");
984 cpu_suspend(0, rockchip_lpmode_enter);
985
986 rkpm_printch('4');
987
988 vd_log_regs_restore();
989 rkpm_printch('3');
990 rkpm_regs_rgn_dump();
991
992 gpio_restore();
993 rkpm_printch('2');
994
995 plls_resume();
996 rkpm_printch('1');
997
998 soc_sleep_restore();
999 rkpm_printch('0');
1000
1001 clock_resume();
1002 rkpm_printch('-');
1003
1004 fiq_glue_resume();
1005
1006 rv1106_dbg_irq_finish();
1007
1008 local_fiq_enable();
1009 rkpm_printstr("rv1106 exit sleep\n");
1010
1011 return 0;
1012 }
1013
rv1106_suspend_init(struct device_node * np)1014 static int __init rv1106_suspend_init(struct device_node *np)
1015 {
1016 void __iomem *dev_reg_base;
1017
1018 dev_reg_base = ioremap(RV1106_DEV_REG_BASE, RV1106_DEV_REG_SIZE);
1019 if (dev_reg_base)
1020 pr_info("%s map dev_reg 0x%x -> 0x%x\n",
1021 __func__, RV1106_DEV_REG_BASE, (u32)dev_reg_base);
1022 else
1023 pr_err("%s: can't map dev_reg(0x%x)\n", __func__, RV1106_DEV_REG_BASE);
1024
1025 gicd_base = dev_reg_base + RV1106_GIC_OFFSET + 0x1000;
1026 gicc_base = dev_reg_base + RV1106_GIC_OFFSET + 0x2000;
1027
1028 firewall_ddr_base = dev_reg_base + RV1106_FW_DDR_OFFSET;
1029 firewall_syssram_base = dev_reg_base + RV1106_FW_SRAM_OFFSET;
1030
1031 nstimer_base = dev_reg_base + RV1106_NSTIMER_OFFSET;
1032 stimer_base = dev_reg_base + RV1106_STIMER_OFFSET;
1033
1034 pmu_base = dev_reg_base + RV1106_PMU_OFFSET;
1035 uartdbg_base = dev_reg_base + RV1106_UART2_OFFSET;
1036 pmupvtm_base = dev_reg_base + RV1106_PMUPVTM_OFFSET;
1037 pmusgrf_base = dev_reg_base + RV1106_PMUSGRF_OFFSET;
1038 ddrc_base = dev_reg_base + RV1106_DDRC_OFFSET;
1039
1040 perigrf_base = dev_reg_base + RV1106_PERIGRF_OFFSET;
1041 vencgrf_base = dev_reg_base + RV1106_VENCGRF_OFFSET;
1042 npugrf_base = dev_reg_base + RV1106_NPUGRF_OFFSET;
1043 pmugrf_base = dev_reg_base + RV1106_PMUGRF_OFFSET;
1044 ddrgrf_base = dev_reg_base + RV1106_DDRGRF_OFFSET;
1045 coregrf_base = dev_reg_base + RV1106_COREGRF_OFFSET;
1046 vigrf_base = dev_reg_base + RV1106_VIGRF_OFFSET;
1047 vogrf_base = dev_reg_base + RV1106_VOGRF_OFFSET;
1048
1049 perisgrf_base = dev_reg_base + RV1106_PERISGRF_OFFSET;
1050 visgrf_base = dev_reg_base + RV1106_VIGRF_OFFSET;
1051 npusgrf_base = dev_reg_base + RV1106_NPUSGRF_OFFSET;
1052 coresgrf_base = dev_reg_base + RV1106_CORESGRF_OFFSET;
1053 vencsgrf_base = dev_reg_base + RV1106_VENCSGRF_OFFSET;
1054 vosgrf_base = dev_reg_base + RV1106_VOSGRF_OFFSET;
1055 pmusgrf_base = dev_reg_base + RV1106_PMUSGRF_OFFSET;
1056
1057 pmucru_base = dev_reg_base + RV1106_PMUCRU_OFFSET;
1058 cru_base = dev_reg_base + RV1106_CRU_OFFSET;
1059 pericru_base = dev_reg_base + RV1106_PERICRU_OFFSET;
1060 vicru_base = dev_reg_base + RV1106_VICRU_OFFSET;
1061 npucru_base = dev_reg_base + RV1106_NPUCRU_OFFSET;
1062 corecru_base = dev_reg_base + RV1106_CORECRU_OFFSET;
1063 venccru_base = dev_reg_base + RV1106_VENCCRU_OFFSET;
1064 vocru_base = dev_reg_base + RV1106_VOCRU_OFFSET;
1065
1066 ioc_base[0] = dev_reg_base + RV1106_GPIO0IOC_OFFSET;
1067 ioc_base[1] = dev_reg_base + RV1106_GPIO1IOC_OFFSET;
1068 ioc_base[2] = dev_reg_base + RV1106_GPIO2IOC_OFFSET;
1069 ioc_base[3] = dev_reg_base + RV1106_GPIO3IOC_OFFSET;
1070 ioc_base[4] = dev_reg_base + RV1106_GPIO4IOC_OFFSET;
1071
1072 gpio_base[0] = dev_reg_base + RV1106_GPIO0_OFFSET;
1073 gpio_base[1] = dev_reg_base + RV1106_GPIO1_OFFSET;
1074 gpio_base[2] = dev_reg_base + RV1106_GPIO2_OFFSET;
1075 gpio_base[3] = dev_reg_base + RV1106_GPIO3_OFFSET;
1076 gpio_base[4] = dev_reg_base + RV1106_GPIO4_OFFSET;
1077
1078 rv1106_bootram_base = dev_reg_base + RV1106_PMUSRAM_OFFSET;
1079
1080 rv1106_config_bootdata();
1081
1082 /* copy resume code and data to bootsram */
1083 memcpy(rv1106_bootram_base, rockchip_slp_cpu_resume,
1084 rv1106_bootram_sz + 0x50);
1085
1086 /* remap */
1087 #if RV1106_WAKEUP_TO_SYSTEM_RESET
1088 writel_relaxed(BITS_WITH_WMASK(1, 0x1, 10), pmusgrf_base + RV1106_PMUSGRF_SOC_CON(1));
1089 #else
1090 writel_relaxed(BITS_WITH_WMASK(0, 0x1, 10), pmusgrf_base + RV1106_PMUSGRF_SOC_CON(1));
1091 #endif
1092 /* biu auto con */
1093 writel_relaxed(0x07ff07ff, pmu_base + RV1106_PMU_BIU_AUTO_CON);
1094
1095 rkpm_region_mem_init(RV1106_PM_REG_REGION_MEM_SIZE);
1096 rkpm_reg_rgns_init();
1097
1098 return 0;
1099 }
1100
1101 static const struct platform_suspend_ops rv1106_suspend_ops = {
1102 .enter = rv1106_suspend_enter,
1103 .valid = suspend_valid_only_mem,
1104 };
1105
1106 static const struct rockchip_pm_data rv1106_pm_data __initconst = {
1107 .ops = &rv1106_suspend_ops,
1108 .init = rv1106_suspend_init,
1109 };
1110
1111 /****************************************************************************/
1112 static const struct of_device_id rockchip_pmu_of_device_ids[] __initconst = {
1113 {
1114 .compatible = "rockchip,rv1106-pmu",
1115 .data = &rv1106_pm_data,
1116 },
1117 { /* sentinel */ },
1118 };
1119
rockchip_suspend_init(void)1120 void __init rockchip_suspend_init(void)
1121 {
1122 const struct rockchip_pm_data *pm_data;
1123 const struct of_device_id *match;
1124 struct device_node *np;
1125 int ret;
1126
1127 np = of_find_matching_node_and_match(NULL, rockchip_pmu_of_device_ids,
1128 &match);
1129 if (!match) {
1130 pr_err("Failed to find PMU node\n");
1131 return;
1132 }
1133 pm_data = (struct rockchip_pm_data *)match->data;
1134
1135 if (pm_data->init) {
1136 ret = pm_data->init(np);
1137
1138 if (ret) {
1139 pr_err("%s: matches init error %d\n", __func__, ret);
1140 return;
1141 }
1142 }
1143
1144 suspend_set_ops(pm_data->ops);
1145 }
1146