2 * Device Tree support for Rockchip RK3036
4 * Copyright (C) 2014 ROCKCHIP, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/clk-provider.h>
18 #include <linux/clocksource.h>
19 #include <linux/cpuidle.h>
20 #include <linux/delay.h>
21 #include <linux/init.h>
22 #include <linux/irqchip.h>
23 #include <linux/kernel.h>
24 #include <linux/of_address.h>
25 #include <linux/of_platform.h>
26 #include <linux/wakeup_reason.h>
27 #include <linux/rockchip/common.h>
28 #include <linux/rockchip/cpu.h>
29 #include <linux/rockchip/cru.h>
30 #include <linux/rockchip/dvfs.h>
31 #include <linux/rockchip/grf.h>
32 #include <linux/rockchip/iomap.h>
33 #include <linux/rockchip/pmu.h>
34 #include <asm/cpuidle.h>
35 #include <asm/cputype.h>
36 #include <asm/mach/arch.h>
37 #include <asm/mach/map.h>
44 #define RK3036_DEVICE(name) \
46 .virtual = (unsigned long) RK_##name##_VIRT, \
47 .pfn = __phys_to_pfn(RK3036_##name##_PHYS), \
48 .length = RK3036_##name##_SIZE, \
52 #define RK3036_IMEM_VIRT (RK_BOOTRAM_VIRT + SZ_32K)
53 #define RK3036_TIMER5_VIRT (RK_TIMER_VIRT + 0xa0)
55 static struct map_desc rk3036_io_desc[] __initdata = {
60 RK_DEVICE(RK_DDR_VIRT, RK3036_DDR_PCTL_PHYS, RK3036_DDR_PCTL_SIZE),
61 RK_DEVICE(RK_DDR_VIRT + RK3036_DDR_PCTL_SIZE, RK3036_DDR_PHY_PHYS,
63 RK_DEVICE(RK_GPIO_VIRT(0), RK3036_GPIO0_PHYS, RK3036_GPIO_SIZE),
64 RK_DEVICE(RK_GPIO_VIRT(1), RK3036_GPIO1_PHYS, RK3036_GPIO_SIZE),
65 RK_DEVICE(RK_GPIO_VIRT(2), RK3036_GPIO2_PHYS, RK3036_GPIO_SIZE),
66 RK_DEVICE(RK_DEBUG_UART_VIRT, RK3036_UART2_PHYS, RK3036_UART_SIZE),
67 RK_DEVICE(RK_GIC_VIRT, RK3036_GIC_DIST_PHYS, RK3036_GIC_DIST_SIZE),
68 RK_DEVICE(RK_GIC_VIRT + RK3036_GIC_DIST_SIZE, RK3036_GIC_CPU_PHYS,
70 RK_DEVICE(RK3036_IMEM_VIRT, RK3036_IMEM_PHYS, SZ_4K),
71 RK_DEVICE(RK_TIMER_VIRT, RK3036_TIMER_PHYS, RK3036_TIMER_SIZE),
74 static void __init rk3036_boot_mode_init(void)
76 u32 flag = readl_relaxed(RK_GRF_VIRT + RK3036_GRF_OS_REG4);
77 u32 mode = readl_relaxed(RK_GRF_VIRT + RK3036_GRF_OS_REG5);
78 u32 rst_st = readl_relaxed(RK_CRU_VIRT + RK3036_CRU_RST_ST);
80 if (flag == (SYS_KERNRL_REBOOT_FLAG | BOOT_RECOVER))
81 mode = BOOT_MODE_RECOVERY;
82 if (rst_st & ((1 << 2) | (1 << 3)))
83 mode = BOOT_MODE_WATCHDOG;
84 rockchip_boot_mode_init(flag, mode);
87 static void usb_uart_init(void)
89 #ifdef CONFIG_RK_USB_UART
90 u32 soc_status0 = readl_relaxed(RK_GRF_VIRT + RK3036_GRF_SOC_STATUS0);
92 writel_relaxed(0x34000000, RK_GRF_VIRT + RK3036_GRF_UOC1_CON4);
93 #ifdef CONFIG_RK_USB_UART
94 if (!(soc_status0 & (1 << 14)) && (soc_status0 & (1 << 17))) {
95 /* software control usb phy enable */
96 writel_relaxed(0x007f0055, RK_GRF_VIRT + RK3036_GRF_UOC0_CON5);
97 writel_relaxed(0x34003000, RK_GRF_VIRT + RK3036_GRF_UOC1_CON4);
101 writel_relaxed(0x07, RK_DEBUG_UART_VIRT + 0x88);
102 writel_relaxed(0x00, RK_DEBUG_UART_VIRT + 0x04);
103 writel_relaxed(0x83, RK_DEBUG_UART_VIRT + 0x0c);
104 writel_relaxed(0x0d, RK_DEBUG_UART_VIRT + 0x00);
105 writel_relaxed(0x00, RK_DEBUG_UART_VIRT + 0x04);
106 writel_relaxed(0x03, RK_DEBUG_UART_VIRT + 0x0c);
109 static void __init rk3036_dt_map_io(void)
111 rockchip_soc_id = ROCKCHIP_SOC_RK3036;
113 iotable_init(rk3036_io_desc, ARRAY_SIZE(rk3036_io_desc));
117 /* enable timer5 for core */
118 writel_relaxed(0, RK3036_TIMER5_VIRT + 0x10);
120 writel_relaxed(0xFFFFFFFF, RK3036_TIMER5_VIRT + 0x00);
121 writel_relaxed(0xFFFFFFFF, RK3036_TIMER5_VIRT + 0x04);
123 writel_relaxed(1, RK3036_TIMER5_VIRT + 0x10);
126 rk3036_boot_mode_init();
129 extern void secondary_startup(void);
130 static int rk3036_sys_set_power_domain(enum pmu_power_domain pd, bool on)
134 if (PD_CPU_1 == pd) {
135 writel_relaxed(0x20000
136 , RK_CRU_VIRT + RK3036_CRU_SOFTRST0_CON);
139 writel_relaxed(virt_to_phys(secondary_startup),
140 RK3036_IMEM_VIRT + 8);
141 writel_relaxed(0xDEADBEAF, RK3036_IMEM_VIRT + 4);
147 if (PD_CPU_1 == pd) {
148 writel_relaxed(0x20002
149 , RK_CRU_VIRT + RK3036_CRU_SOFTRST0_CON);
158 static bool rk3036_pmu_power_domain_is_on(enum pmu_power_domain pd)
163 static int rk3036_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
168 static void __init rk3036_dt_init_timer(void)
170 rockchip_pmu_ops.set_power_domain = rk3036_sys_set_power_domain;
171 rockchip_pmu_ops.power_domain_is_on = rk3036_pmu_power_domain_is_on;
172 rockchip_pmu_ops.set_idle_request = rk3036_pmu_set_idle_request;
174 clocksource_of_init();
178 static inline void rk3036_uart_printch(char byte)
181 writel_relaxed(byte, RK_DEBUG_UART_VIRT);
184 /* loop check LSR[6], Transmitter Empty bit */
185 while (!(readl_relaxed(RK_DEBUG_UART_VIRT + 0x14) & 0x40))
194 static void rk3036_ddr_printch(char byte)
196 rk3036_uart_printch(byte);
198 rk_last_log_text(&byte, 1);
202 rk_last_log_text(&byte, 1);
213 #define GPIO_INTEN 0x30
214 #define GPIO_INT_STATUS 0x40
215 #define GIC_DIST_PENDING_SET 0x200
216 static void rk3036_pm_dump_irq(void)
218 u32 irq_gpio = (readl_relaxed(RK_GIC_VIRT
219 + GIC_DIST_PENDING_SET + 8) >> 4) & 7;
223 for (i = 0; i < ARRAY_SIZE(irq); i++) {
224 irq[i] = readl_relaxed(RK_GIC_VIRT + GIC_DIST_PENDING_SET +
227 log_wakeup_reason(32 * (i + 1) + fls(irq[i]) - 1);
229 pr_info("wakeup irq: %08x %08x %08x %08x\n",
230 irq[0], irq[1], irq[2], irq[3]);
231 for (i = 0; i <= 2; i++) {
232 if (irq_gpio & (1 << i))
233 pr_info("wakeup gpio%d: %08x\n", i,
234 readl_relaxed(RK_GPIO_VIRT(i) +
239 #define DUMP_GPIO_INTEN(ID) \
241 u32 en = readl_relaxed(RK_GPIO_VIRT(ID) + GPIO_INTEN); \
243 pr_info("GPIO%d_INTEN: %08x\n", ID, en); \
247 static void rk3036_pm_dump_inten(void)
254 static u32 clk_ungt_msk[RK3036_CRU_CLKGATES_CON_CNT];
255 /*first clk gating setting*/
257 static u32 clk_ungt_msk_1[RK3036_CRU_CLKGATES_CON_CNT];
258 /* first clk gating setting*/
260 static u32 clk_ungt_save[RK3036_CRU_CLKGATES_CON_CNT];
261 /*first clk gating value saveing*/
263 static u32 *p_rkpm_clkgt_last_set;
264 #define CLK_MSK_GATING(msk, con) cru_writel((0xffff << 16) | msk, con)
265 #define CLK_MSK_UNGATING(msk, con) cru_writel(((~msk) << 16) | 0xffff, con)
267 static void gtclks_suspend(void)
271 for (i = 0; i < RK3036_CRU_CLKGATES_CON_CNT; i++) {
272 clk_ungt_save[i] = cru_readl(RK3036_CRU_CLKGATES_CON(i));
274 CLK_MSK_GATING(clk_ungt_msk[i]
275 , RK3036_CRU_CLKGATES_CON(i));
277 cru_writel(clk_ungt_msk[i], RK3036_CRU_CLKGATES_CON(i));
281 static void gtclks_resume(void)
285 for (i = 0; i < RK3036_CRU_CLKGATES_CON_CNT; i++) {
287 cru_writel(clk_ungt_save[i] | 0xffff0000
288 , RK3036_CRU_CLKGATES_CON(i));
290 cru_writel(clk_ungt_msk[i]
291 , RK3036_CRU_CLKGATES_CON(i));
295 static void clks_gating_suspend_init(void)
297 p_rkpm_clkgt_last_set = &clk_ungt_msk_1[0];
298 if (clk_suspend_clkgt_info_get(clk_ungt_msk, p_rkpm_clkgt_last_set
299 , RK3036_CRU_CLKGATES_CON_CNT) == RK3036_CRU_CLKGATES_CON(0))
300 rkpm_set_ops_gtclks(gtclks_suspend, gtclks_resume);
303 #define RK3036_PLL_BYPASS CRU_W_MSK_SETBITS(1, 0xF, 0x01)
304 #define RK3036_PLL_NOBYPASS CRU_W_MSK_SETBITS(0, 0xF, 0x01)
306 #define grf_readl(offset) readl_relaxed(RK_GRF_VIRT + offset)
307 #define grf_writel(v, offset) do { writel_relaxed(v, \
308 RK_GRF_VIRT + offset); dsb(); } while (0)
310 #define gpio0_readl(offset) readl_relaxed(RK_GPIO_VIRT(0) + offset)
311 #define gpio0_writel(v, offset) do { writel_relaxed(v, RK_GPIO_VIRT(0) \
312 + offset); dsb(); } while (0)
314 static u32 plls_con0_save[RK3036_END_PLL_ID];
315 static u32 plls_con1_save[RK3036_END_PLL_ID];
316 static u32 plls_con2_save[RK3036_END_PLL_ID];
318 static u32 cru_mode_con;
319 static u32 clk_sel0, clk_sel1, clk_sel10;
320 static int goio0_pin_iomux, gpio0_pin_data, gpio0_pin_dir;
322 static void pm_pll_wait_lock(u32 pll_idx)
333 if ((cru_readl(RK3036_PLL_CONS(pll_idx, 1)) & (0x1 << 10)))
338 rkpm_ddr_printascii("unlock-pll:");
339 rkpm_ddr_printhex(pll_idx);
340 rkpm_ddr_printch('\n');
344 static void pll_udelay(u32 udelay)
348 mode = cru_readl(RK3036_CRU_MODE_CON);
349 cru_writel(RK3036_PLL_MODE_SLOW(APLL_ID), RK3036_CRU_MODE_CON);
350 rkpm_udelay(udelay * 5);
351 cru_writel(mode|(RK3036_PLL_MODE_MSK(APLL_ID)
352 << 16), RK3036_CRU_MODE_CON);
355 static inline void plls_suspend(u32 pll_id)
357 plls_con0_save[pll_id] = cru_readl(RK3036_PLL_CONS((pll_id), 0));
358 plls_con1_save[pll_id] = cru_readl(RK3036_PLL_CONS((pll_id), 1));
359 plls_con2_save[pll_id] = cru_readl(RK3036_PLL_CONS((pll_id), 2));
361 cru_writel(RK3036_PLL_BYPASS, RK3036_PLL_CONS((pll_id), 0));
363 static inline void plls_resume(u32 pll_id)
365 u32 pllcon0, pllcon1, pllcon2;
367 pllcon0 = plls_con0_save[pll_id];
368 pllcon1 = plls_con1_save[pll_id];
369 pllcon2 = plls_con2_save[pll_id];
371 cru_writel(pllcon0 | 0xffff0000, RK3036_PLL_CONS(pll_id, 0));
372 cru_writel(pllcon1 | 0xf5ff0000, RK3036_PLL_CONS(pll_id, 1));
373 cru_writel(pllcon2, RK3036_PLL_CONS(pll_id, 2));
378 pm_pll_wait_lock(pll_id);
381 static void pm_plls_suspend(void)
383 cru_mode_con = cru_readl(RK3036_CRU_MODE_CON);
385 clk_sel0 = cru_readl(RK3036_CRU_CLKSELS_CON(0));
386 clk_sel1 = cru_readl(RK3036_CRU_CLKSELS_CON(1));
387 clk_sel10 = cru_readl(RK3036_CRU_CLKSELS_CON(10));
389 cru_writel(RK3036_PLL_MODE_SLOW(GPLL_ID), RK3036_CRU_MODE_CON);
391 |CRU_W_MSK_SETBITS(0, 0, 0x1f)
392 |CRU_W_MSK_SETBITS(0, 8, 0x3)
393 |CRU_W_MSK_SETBITS(0, 12, 0x3)
394 , RK3036_CRU_CLKSELS_CON(10));
395 plls_suspend(GPLL_ID);
398 cru_writel(RK3036_PLL_MODE_SLOW(APLL_ID), RK3036_CRU_MODE_CON);
401 |CRU_W_MSK_SETBITS(0, 0, 0x1f)
402 |CRU_W_MSK_SETBITS(0, 8, 0x1f)
403 , RK3036_CRU_CLKSELS_CON(0));
406 |CRU_W_MSK_SETBITS(0, 0, 0xf)
407 |CRU_W_MSK_SETBITS(0, 4, 0x7)
408 |CRU_W_MSK_SETBITS(0, 8, 0x3)
409 |CRU_W_MSK_SETBITS(0, 12, 0x7)
410 , RK3036_CRU_CLKSELS_CON(1));
412 plls_suspend(APLL_ID);
414 goio0_pin_iomux = grf_readl(0xa8);
415 grf_writel(0x000c0000, 0xa8);
417 gpio0_pin_data = gpio0_readl(0x0);
418 gpio0_pin_dir = gpio0_readl(0x04);
420 gpio0_writel(gpio0_pin_dir|0x2, 0x04);
421 gpio0_writel(gpio0_pin_data|0x2, 0x00);
424 static void pm_plls_resume(void)
426 gpio0_writel(gpio0_pin_dir, 0x04);
427 gpio0_writel(gpio0_pin_data, 0x00);
428 grf_writel(0x000c0008, 0xa8);
430 cru_writel(clk_sel0 | (CRU_W_MSK(0, 0x1f) | CRU_W_MSK(8, 0x1f))
431 , RK3036_CRU_CLKSELS_CON(0));
432 cru_writel(clk_sel1 | (CRU_W_MSK(0, 0xf) | CRU_W_MSK(4, 0x7)
433 |CRU_W_MSK(8, 0x3) | CRU_W_MSK(12, 0x7))
434 , RK3036_CRU_CLKSELS_CON(1));
436 plls_resume(APLL_ID);
437 cru_writel(cru_mode_con | (RK3036_PLL_MODE_MSK(APLL_ID) << 16)
438 , RK3036_CRU_MODE_CON);
439 cru_writel(clk_sel1 | (CRU_W_MSK(0, 0x1f) | CRU_W_MSK(8, 0x3)
440 | CRU_W_MSK(12, 0x3)), RK3036_CRU_CLKSELS_CON(10));
441 plls_resume(GPLL_ID);
442 cru_writel(cru_mode_con | (RK3036_PLL_MODE_MSK(GPLL_ID)
443 << 16), RK3036_CRU_MODE_CON);
446 static void __init rk3036_suspend_init(void)
448 struct device_node *parent;
451 PM_LOG("%s enter\n", __func__);
453 parent = of_find_node_by_name(NULL, "rockchip_suspend");
455 if (IS_ERR_OR_NULL(parent)) {
456 PM_ERR("%s dev node err\n", __func__);
460 if (of_property_read_u32_array(parent, "rockchip,ctrbits"
462 PM_ERR("%s:get pm ctr error\n", __func__);
465 PM_LOG("%s: pm_ctrbits =%x\n", __func__, pm_ctrbits);
466 rkpm_set_ctrbits(pm_ctrbits);
468 clks_gating_suspend_init();
469 rkpm_set_ops_plls(pm_plls_suspend, pm_plls_resume);
470 rkpm_set_ops_prepare_finish(rk3036_pm_dump_inten
471 , rk3036_pm_dump_irq);
472 rkpm_set_ops_printch(rk3036_ddr_printch);
473 rockchip_suspend_init();
477 static void __init rk3036_init_late(void)
480 rk3036_suspend_init();
484 static void __init rk3036_reserve(void)
486 /* reserve memory for ION */
487 rockchip_ion_reserve();
490 static void rk3036_restart(char mode, const char *cmd)
492 u32 boot_flag, boot_mode;
494 rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);
496 writel_relaxed(boot_flag, RK_GRF_VIRT + RK3036_GRF_OS_REG4);
498 writel_relaxed(boot_mode, RK_GRF_VIRT + RK3036_GRF_OS_REG5);
501 /* pll enter slow mode */
502 writel_relaxed(0x30110000, RK_CRU_VIRT + RK3036_CRU_MODE_CON);
504 writel_relaxed(0xeca8, RK_CRU_VIRT + RK3036_CRU_GLB_SRST_SND_VALUE);
508 static const char *const rk3036_dt_compat[] __initconst = {
513 DT_MACHINE_START(RK3036_DT, "Rockchip RK3036")
514 .dt_compat = rk3036_dt_compat,
515 .smp = smp_ops(rockchip_smp_ops),
516 .reserve = rk3036_reserve,
517 .map_io = rk3036_dt_map_io,
518 .init_time = rk3036_dt_init_timer,
519 .init_late = rk3036_init_late,
520 .reserve = rk3036_reserve,
521 .restart = rk3036_restart,