rk312x: init rockchip_pmu_ops
[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(EFUSE),
69         RK312X_DEVICE(TIMER),
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),
80 };
81
82 static void __init rk312x_dt_map_io(void)
83 {
84         iotable_init(rk312x_io_desc, ARRAY_SIZE(rk312x_io_desc));
85         debug_ll_io_init();
86
87         /* enable timer5 for core */
88         writel_relaxed(0, RK312X_TIMER5_VIRT + 0x10);
89         dsb();
90         writel_relaxed(0xFFFFFFFF, RK312X_TIMER5_VIRT + 0x00);
91         writel_relaxed(0xFFFFFFFF, RK312X_TIMER5_VIRT + 0x04);
92         dsb();
93         writel_relaxed(1, RK312X_TIMER5_VIRT + 0x10);
94         dsb();
95 }
96
97 static void __init rk3126_dt_map_io(void)
98 {
99         rockchip_soc_id = ROCKCHIP_SOC_RK3126;
100
101         rk312x_dt_map_io();
102 }
103
104 static void __init rk3128_dt_map_io(void)
105 {
106         rockchip_soc_id = ROCKCHIP_SOC_RK3128;
107
108         rk312x_dt_map_io();
109 }
110
111 extern void secondary_startup(void);
112 static int rk312x_sys_set_power_domain(enum pmu_power_domain pd, bool on)
113 {
114         if (on) {
115 #ifdef CONFIG_SMP
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));
119                         dsb();
120                         udelay(10);
121                         writel_relaxed(virt_to_phys(secondary_startup),
122                                        RK312X_IMEM_VIRT + 8);
123                         writel_relaxed(0xDEADBEAF, RK312X_IMEM_VIRT + 4);
124                         dsb_sev();
125                 }
126 #endif
127         } else {
128 #ifdef CONFIG_SMP
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));
132                         dsb();
133                 }
134 #endif
135         }
136
137         return 0;
138 }
139
140 static bool rk312x_pmu_power_domain_is_on(enum pmu_power_domain pd)
141 {
142         return 1;
143 }
144
145 static int rk312x_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
146 {
147         return 0;
148 }
149
150 static void __init rk312x_dt_init_timer(void)
151 {
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;
155         of_clk_init(NULL);
156         clocksource_of_init();
157         of_dvfs_init();
158 }
159
160 static void __init rk312x_reserve(void)
161 {
162 }
163
164 static void __init rk312x_init_late(void)
165 {
166 }
167
168 static void rk312x_restart(char mode, const char *cmd)
169 {
170 }
171
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,
180 MACHINE_END
181
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,
190 MACHINE_END
191
192
193 char PIE_DATA(sram_stack)[1024];
194 EXPORT_PIE_SYMBOL(DATA(sram_stack));
195
196 static int __init rk312x_pie_init(void)
197 {
198         int err;
199
200         if (!cpu_is_rk312x())
201                 return 0;
202
203         err = rockchip_pie_init();
204         if (err)
205                 return err;
206
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;
212                 return err;
213         }
214
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)));
217
218         return 0;
219 }
220 arch_initcall(rk312x_pie_init);