rk312x: iomap PMU register
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rk312x.c
1 /*
2  * Device Tree support for Rockchip RK3288
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  *
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.
10  *
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.
15  */
16
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>
37 #include "cpu_axi.h"
38 #include "loader.h"
39 #define CPU 312x
40 #include "sram.h"
41 #include "pm.h"
42
43 #define RK312X_DEVICE(name) \
44         { \
45                 .virtual        = (unsigned long) RK_##name##_VIRT, \
46                 .pfn            = __phys_to_pfn(RK312X_##name##_PHYS), \
47                 .length         = RK312X_##name##_SIZE, \
48                 .type           = MT_DEVICE, \
49         }
50
51 static const char * const rk3126_dt_compat[] __initconst = {
52         "rockchip,rk3126",
53         NULL,
54 };
55
56 static const char * const rk3128_dt_compat[] __initconst = {
57         "rockchip,rk3128",
58         NULL,
59 };
60
61 #define RK312X_IMEM_VIRT (RK_BOOTRAM_VIRT + SZ_32K)
62 #define RK312X_TIMER5_VIRT (RK_TIMER_VIRT + 0xa0)
63
64 static struct map_desc rk312x_io_desc[] __initdata = {
65         RK312X_DEVICE(CRU),
66         RK312X_DEVICE(GRF),
67         RK312X_DEVICE(ROM),
68         RK312X_DEVICE(PMU),
69         RK312X_DEVICE(EFUSE),
70         RK312X_DEVICE(TIMER),
71         RK312X_DEVICE(CPU_AXI_BUS),
72         RK_DEVICE(RK_DEBUG_UART_VIRT, RK312X_UART2_PHYS, RK312X_UART_SIZE),
73         RK_DEVICE(RK_DDR_VIRT, RK312X_DDR_PCTL_PHYS, RK312X_DDR_PCTL_SIZE),
74         RK_DEVICE(RK_DDR_VIRT + RK312X_DDR_PCTL_SIZE, RK312X_DDR_PHY_PHYS, RK312X_DDR_PHY_SIZE),
75         RK_DEVICE(RK_GPIO_VIRT(0), RK312X_GPIO0_PHYS, RK312X_GPIO_SIZE),
76         RK_DEVICE(RK_GPIO_VIRT(1), RK312X_GPIO1_PHYS, RK312X_GPIO_SIZE),
77         RK_DEVICE(RK_GPIO_VIRT(2), RK312X_GPIO2_PHYS, RK312X_GPIO_SIZE),
78         RK_DEVICE(RK_GPIO_VIRT(3), RK312X_GPIO3_PHYS, RK312X_GPIO_SIZE),
79         RK_DEVICE(RK_GIC_VIRT, RK312X_GIC_DIST_PHYS, RK312X_GIC_DIST_SIZE),
80         RK_DEVICE(RK_GIC_VIRT + RK312X_GIC_DIST_SIZE, RK312X_GIC_CPU_PHYS, RK312X_GIC_CPU_SIZE),
81         RK_DEVICE(RK312X_IMEM_VIRT, RK312X_IMEM_PHYS, RK312X_IMEM_SIZE),
82 };
83 static void usb_uart_init(void)
84 {
85 #ifdef CONFIG_RK_USB_UART
86         u32 soc_status0 = readl_relaxed(RK_GRF_VIRT + RK312X_GRF_SOC_STATUS0);
87 #endif
88         writel_relaxed(0x34000000, RK_GRF_VIRT + RK312X_GRF_UOC1_CON4);
89 #ifdef CONFIG_RK_USB_UART
90         if (!(soc_status0 & (1 << 5)) && (soc_status0 & (1 << 8))) {
91                 /* software control usb phy enable */
92                 writel_relaxed(0x007f0055, RK_GRF_VIRT + RK312X_GRF_UOC0_CON0);
93                 writel_relaxed(0x34003000, RK_GRF_VIRT + RK312X_GRF_UOC1_CON4);
94         }
95 #endif
96
97         writel_relaxed(0x07, RK_DEBUG_UART_VIRT + 0x88);
98         writel_relaxed(0x00, RK_DEBUG_UART_VIRT + 0x04);
99         writel_relaxed(0x83, RK_DEBUG_UART_VIRT + 0x0c);
100         writel_relaxed(0x0d, RK_DEBUG_UART_VIRT + 0x00);
101         writel_relaxed(0x00, RK_DEBUG_UART_VIRT + 0x04);
102         writel_relaxed(0x03, RK_DEBUG_UART_VIRT + 0x0c);
103 }
104
105 static void __init rk312x_dt_map_io(void)
106 {
107         iotable_init(rk312x_io_desc, ARRAY_SIZE(rk312x_io_desc));
108         debug_ll_io_init();
109         usb_uart_init();
110
111         /* enable timer5 for core */
112         writel_relaxed(0, RK312X_TIMER5_VIRT + 0x10);
113         dsb();
114         writel_relaxed(0xFFFFFFFF, RK312X_TIMER5_VIRT + 0x00);
115         writel_relaxed(0xFFFFFFFF, RK312X_TIMER5_VIRT + 0x04);
116         dsb();
117         writel_relaxed(1, RK312X_TIMER5_VIRT + 0x10);
118         dsb();
119 }
120
121 static void __init rk3126_dt_map_io(void)
122 {
123         rockchip_soc_id = ROCKCHIP_SOC_RK3126;
124
125         rk312x_dt_map_io();
126 }
127
128 static void __init rk3128_dt_map_io(void)
129 {
130         rockchip_soc_id = ROCKCHIP_SOC_RK3128;
131
132         rk312x_dt_map_io();
133 }
134
135 extern void secondary_startup(void);
136 static int rk312x_sys_set_power_domain(enum pmu_power_domain pd, bool on)
137 {
138         if (on) {
139 #ifdef CONFIG_SMP
140                 if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
141                         writel_relaxed(0x20000 << (pd - PD_CPU_1),
142                                        RK_CRU_VIRT + RK312X_CRU_SOFTRSTS_CON(0));
143                         dsb();
144                         udelay(10);
145                         writel_relaxed(virt_to_phys(secondary_startup),
146                                        RK312X_IMEM_VIRT + 8);
147                         writel_relaxed(0xDEADBEAF, RK312X_IMEM_VIRT + 4);
148                         dsb_sev();
149                 }
150 #endif
151         } else {
152 #ifdef CONFIG_SMP
153                 if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
154                         writel_relaxed(0x20002 << (pd - PD_CPU_1),
155                                        RK_CRU_VIRT + RK312X_CRU_SOFTRSTS_CON(0));
156                         dsb();
157                 }
158 #endif
159         }
160
161         return 0;
162 }
163
164 static bool rk312x_pmu_power_domain_is_on(enum pmu_power_domain pd)
165 {
166         return 1;
167 }
168
169 static int rk312x_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
170 {
171         return 0;
172 }
173
174 static void __init rk312x_dt_init_timer(void)
175 {
176         rockchip_pmu_ops.set_power_domain = rk312x_sys_set_power_domain;
177         rockchip_pmu_ops.power_domain_is_on = rk312x_pmu_power_domain_is_on;
178         rockchip_pmu_ops.set_idle_request = rk312x_pmu_set_idle_request;
179         of_clk_init(NULL);
180         clocksource_of_init();
181         of_dvfs_init();
182 }
183
184 static void __init rk312x_reserve(void)
185 {
186         /* reserve memory for ION */
187         rockchip_ion_reserve();
188 }
189
190 static void __init rk312x_init_late(void)
191 {
192 }
193
194 static void rk312x_restart(char mode, const char *cmd)
195 {
196         u32 boot_flag, boot_mode;
197
198         rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);
199
200         writel_relaxed(boot_flag, RK_GRF_VIRT + RK312X_GRF_OS_REG4);    // for loader
201         writel_relaxed(boot_mode, RK_GRF_VIRT + RK312X_GRF_OS_REG5);    // for linux
202         dsb();
203
204         /* pll enter slow mode */
205         writel_relaxed(0x30110000, RK_CRU_VIRT + RK312X_CRU_MODE_CON);
206         dsb();
207         writel_relaxed(0xeca8, RK_CRU_VIRT + RK312X_CRU_GLB_SRST_SND_VALUE);
208         dsb();
209 }
210
211 DT_MACHINE_START(RK3126_DT, "Rockchip RK3126")
212         .smp            = smp_ops(rockchip_smp_ops),
213         .map_io         = rk3126_dt_map_io,
214         .init_time      = rk312x_dt_init_timer,
215         .dt_compat      = rk3126_dt_compat,
216         .init_late      = rk312x_init_late,
217         .reserve        = rk312x_reserve,
218         .restart        = rk312x_restart,
219 MACHINE_END
220
221 DT_MACHINE_START(RK3128_DT, "Rockchip RK3128")
222         .smp            = smp_ops(rockchip_smp_ops),
223         .map_io         = rk3128_dt_map_io,
224         .init_time      = rk312x_dt_init_timer,
225         .dt_compat      = rk3128_dt_compat,
226         .init_late      = rk312x_init_late,
227         .reserve        = rk312x_reserve,
228         .restart        = rk312x_restart,
229 MACHINE_END
230
231
232 char PIE_DATA(sram_stack)[1024];
233 EXPORT_PIE_SYMBOL(DATA(sram_stack));
234
235 static int __init rk312x_pie_init(void)
236 {
237         int err;
238
239         if (!cpu_is_rk312x())
240                 return 0;
241
242         err = rockchip_pie_init();
243         if (err)
244                 return err;
245
246         rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk312x);
247         if (IS_ERR(rockchip_pie_chunk)) {
248                 err = PTR_ERR(rockchip_pie_chunk);
249                 pr_err("%s: failed to load section %d\n", __func__, err);
250                 rockchip_pie_chunk = NULL;
251                 return err;
252         }
253
254         rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk, &__pie_common_start[0]);
255         rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk, (char *)DATA(sram_stack) + sizeof(DATA(sram_stack)));
256
257         return 0;
258 }
259 arch_initcall(rk312x_pie_init);
260 #include "ddr_rk3126.c"
261 static int __init rk312x_ddr_init(void)
262 {
263         if (cpu_is_rk312x()) {
264                 ddr_change_freq = _ddr_change_freq;
265                 ddr_round_rate = _ddr_round_rate;
266                 ddr_set_auto_self_refresh = _ddr_set_auto_self_refresh;
267                 ddr_init(DDR3_DEFAULT, 300);
268                 }
269         return 0;
270 }
271 arch_initcall_sync(rk312x_ddr_init);