2 * Device Tree support for Rockchip RK3288
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/rockchip/common.h>
27 #include <linux/rockchip/cpu.h>
28 #include <linux/rockchip/cru.h>
29 #include <linux/rockchip/dvfs.h>
30 #include <linux/rockchip/grf.h>
31 #include <linux/rockchip/iomap.h>
32 #include <linux/rockchip/pmu.h>
33 #include <asm/cpuidle.h>
34 #include <asm/cputype.h>
35 #include <asm/mach/arch.h>
36 #include <asm/mach/map.h>
43 #define RK312X_DEVICE(name) \
45 .virtual = (unsigned long) RK_##name##_VIRT, \
46 .pfn = __phys_to_pfn(RK312X_##name##_PHYS), \
47 .length = RK312X_##name##_SIZE, \
51 static const char * const rk3126_dt_compat[] __initconst = {
56 static const char * const rk3128_dt_compat[] __initconst = {
61 #define RK312X_IMEM_VIRT (RK_BOOTRAM_VIRT + SZ_32K)
62 #define RK312X_TIMER5_VIRT (RK_TIMER_VIRT + 0xa0)
64 static struct map_desc rk312x_io_desc[] __initdata = {
70 RK_DEVICE(RK_DEBUG_UART_VIRT, RK312X_UART2_PHYS, RK312X_UART_SIZE),
71 RK_DEVICE(RK_DDR_VIRT, RK312X_DDR_PCTL_PHYS, RK312X_DDR_PCTL_SIZE),
72 RK_DEVICE(RK_DDR_VIRT + RK312X_DDR_PCTL_SIZE, RK312X_DDR_PHY_PHYS, RK312X_DDR_PHY_SIZE),
73 RK_DEVICE(RK_GPIO_VIRT(0), RK312X_GPIO0_PHYS, RK312X_GPIO_SIZE),
74 RK_DEVICE(RK_GPIO_VIRT(1), RK312X_GPIO1_PHYS, RK312X_GPIO_SIZE),
75 RK_DEVICE(RK_GPIO_VIRT(2), RK312X_GPIO2_PHYS, RK312X_GPIO_SIZE),
76 RK_DEVICE(RK_GPIO_VIRT(3), RK312X_GPIO3_PHYS, RK312X_GPIO_SIZE),
77 RK_DEVICE(RK_GIC_VIRT, RK312X_GIC_DIST_PHYS, RK312X_GIC_DIST_SIZE),
78 RK_DEVICE(RK_GIC_VIRT + RK312X_GIC_DIST_SIZE, RK312X_GIC_CPU_PHYS, RK312X_GIC_CPU_SIZE),
79 RK_DEVICE(RK312X_IMEM_VIRT, RK312X_IMEM_PHYS, SZ_4K),
82 static void __init rk312x_dt_map_io(void)
84 iotable_init(rk312x_io_desc, ARRAY_SIZE(rk312x_io_desc));
87 /* enable timer5 for core */
88 writel_relaxed(0, RK312X_TIMER5_VIRT + 0x10);
90 writel_relaxed(0xFFFFFFFF, RK312X_TIMER5_VIRT + 0x00);
91 writel_relaxed(0xFFFFFFFF, RK312X_TIMER5_VIRT + 0x04);
93 writel_relaxed(1, RK312X_TIMER5_VIRT + 0x10);
97 static void __init rk3126_dt_map_io(void)
99 rockchip_soc_id = ROCKCHIP_SOC_RK3126;
104 static void __init rk3128_dt_map_io(void)
106 rockchip_soc_id = ROCKCHIP_SOC_RK3128;
111 extern void secondary_startup(void);
112 static int rk312x_sys_set_power_domain(enum pmu_power_domain pd, bool on)
116 if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
117 writel_relaxed(0x20000 << (pd - PD_CPU_1),
118 RK_CRU_VIRT + RK312X_CRU_SOFTRSTS_CON(0));
121 writel_relaxed(virt_to_phys(secondary_startup),
122 RK312X_IMEM_VIRT + 8);
123 writel_relaxed(0xDEADBEAF, RK312X_IMEM_VIRT + 4);
129 if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
130 writel_relaxed(0x20002 << (pd - PD_CPU_1),
131 RK_CRU_VIRT + RK312X_CRU_SOFTRSTS_CON(0));
140 static bool rk312x_pmu_power_domain_is_on(enum pmu_power_domain pd)
145 static int rk312x_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
150 static void __init rk312x_dt_init_timer(void)
152 rockchip_pmu_ops.set_power_domain = rk312x_sys_set_power_domain;
153 rockchip_pmu_ops.power_domain_is_on = rk312x_pmu_power_domain_is_on;
154 rockchip_pmu_ops.set_idle_request = rk312x_pmu_set_idle_request;
156 clocksource_of_init();
160 static void __init rk312x_reserve(void)
164 static void __init rk312x_init_late(void)
168 static void rk312x_restart(char mode, const char *cmd)
172 DT_MACHINE_START(RK3126_DT, "Rockchip RK3126")
173 .smp = smp_ops(rockchip_smp_ops),
174 .map_io = rk3126_dt_map_io,
175 .init_time = rk312x_dt_init_timer,
176 .dt_compat = rk3126_dt_compat,
177 .init_late = rk312x_init_late,
178 .reserve = rk312x_reserve,
179 .restart = rk312x_restart,
182 DT_MACHINE_START(RK3128_DT, "Rockchip RK3128")
183 .smp = smp_ops(rockchip_smp_ops),
184 .map_io = rk3128_dt_map_io,
185 .init_time = rk312x_dt_init_timer,
186 .dt_compat = rk3128_dt_compat,
187 .init_late = rk312x_init_late,
188 .reserve = rk312x_reserve,
189 .restart = rk312x_restart,
193 char PIE_DATA(sram_stack)[1024];
194 EXPORT_PIE_SYMBOL(DATA(sram_stack));
196 static int __init rk312x_pie_init(void)
200 if (!cpu_is_rk312x())
203 err = rockchip_pie_init();
207 rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk312x);
208 if (IS_ERR(rockchip_pie_chunk)) {
209 err = PTR_ERR(rockchip_pie_chunk);
210 pr_err("%s: failed to load section %d\n", __func__, err);
211 rockchip_pie_chunk = NULL;
215 rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk, &__pie_common_start[0]);
216 rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk, (char *)DATA(sram_stack) + sizeof(DATA(sram_stack)));
220 arch_initcall(rk312x_pie_init);