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);
206 #define GPIO_INTEN 0x30
207 #define GPIO_INT_STATUS 0x40
208 #define GIC_DIST_PENDING_SET 0x200
209 static void rk3036_pm_dump_irq(void)
212 (readl_relaxed(RK_GIC_VIRT + GIC_DIST_PENDING_SET + 8) >> 4) & 7;
216 for (i = 0; i < ARRAY_SIZE(irq); i++) {
217 irq[i] = readl_relaxed(RK_GIC_VIRT + GIC_DIST_PENDING_SET +
220 log_wakeup_reason(32 * (i + 1) + fls(irq[i]) - 1);
222 pr_info("wakeup irq: %08x %08x %08x %08x\n",
223 irq[0], irq[1], irq[2], irq[3]);
224 for (i = 0; i <= 2; i++) {
225 if (irq_gpio & (1 << i))
226 pr_info("wakeup gpio%d: %08x\n", i,
227 readl_relaxed(RK_GPIO_VIRT(i) +
232 #define DUMP_GPIO_INTEN(ID) \
234 u32 en = readl_relaxed(RK_GPIO_VIRT(ID) + GPIO_INTEN); \
236 pr_info("GPIO%d_INTEN: %08x\n", ID, en); \
240 static void rk3036_pm_dump_inten(void)
247 static void __init rk3036_suspend_init(void)
249 rkpm_set_ops_prepare_finish(rk3036_pm_dump_inten, rk3036_pm_dump_irq);
250 rkpm_set_ops_printch(rk3036_ddr_printch);
251 rockchip_suspend_init();
255 static void __init rk3036_init_late(void)
258 rk3036_suspend_init();
262 static void __init rk3036_reserve(void)
264 /* reserve memory for ION */
265 rockchip_ion_reserve();
268 static void rk3036_restart(char mode, const char *cmd)
270 u32 boot_flag, boot_mode;
272 rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);
274 writel_relaxed(boot_flag, RK_GRF_VIRT + RK3036_GRF_OS_REG4); // for loader
275 writel_relaxed(boot_mode, RK_GRF_VIRT + RK3036_GRF_OS_REG5); // for linux
278 /* pll enter slow mode */
279 writel_relaxed(0x30110000, RK_CRU_VIRT + RK3036_CRU_MODE_CON);
281 writel_relaxed(0xeca8, RK_CRU_VIRT + RK3036_CRU_GLB_SRST_SND_VALUE);
285 static const char *const rk3036_dt_compat[] __initconst = {
290 DT_MACHINE_START(RK3036_DT, "Rockchip RK3036")
291 .dt_compat = rk3036_dt_compat,
292 .smp = smp_ops(rockchip_smp_ops),
293 .reserve = rk3036_reserve,
294 .map_io = rk3036_dt_map_io,
295 .init_time = rk3036_dt_init_timer,
296 .init_late = rk3036_init_late,
297 .reserve = rk3036_reserve,
298 .restart = rk3036_restart,