rk312x: add pie init
[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 static void __init rk312x_dt_init_timer(void)
112 {
113         of_clk_init(NULL);
114         clocksource_of_init();
115         of_dvfs_init();
116 }
117
118 static void __init rk312x_reserve(void)
119 {
120 }
121
122 static void __init rk312x_init_late(void)
123 {
124 }
125
126 static void rk312x_restart(char mode, const char *cmd)
127 {
128 }
129
130 DT_MACHINE_START(RK3126_DT, "Rockchip RK3126")
131         .smp            = smp_ops(rockchip_smp_ops),
132         .map_io         = rk3126_dt_map_io,
133         .init_time      = rk312x_dt_init_timer,
134         .dt_compat      = rk3126_dt_compat,
135         .init_late      = rk312x_init_late,
136         .reserve        = rk312x_reserve,
137         .restart        = rk312x_restart,
138 MACHINE_END
139
140 DT_MACHINE_START(RK3128_DT, "Rockchip RK3128")
141         .smp            = smp_ops(rockchip_smp_ops),
142         .map_io         = rk3128_dt_map_io,
143         .init_time      = rk312x_dt_init_timer,
144         .dt_compat      = rk3128_dt_compat,
145         .init_late      = rk312x_init_late,
146         .reserve        = rk312x_reserve,
147         .restart        = rk312x_restart,
148 MACHINE_END
149
150
151 char PIE_DATA(sram_stack)[1024];
152 EXPORT_PIE_SYMBOL(DATA(sram_stack));
153
154 static int __init rk312x_pie_init(void)
155 {
156         int err;
157
158         if (!cpu_is_rk312x())
159                 return 0;
160
161         err = rockchip_pie_init();
162         if (err)
163                 return err;
164
165         rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk312x);
166         if (IS_ERR(rockchip_pie_chunk)) {
167                 err = PTR_ERR(rockchip_pie_chunk);
168                 pr_err("%s: failed to load section %d\n", __func__, err);
169                 rockchip_pie_chunk = NULL;
170                 return err;
171         }
172
173         rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk, &__pie_common_start[0]);
174         rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk, (char *)DATA(sram_stack) + sizeof(DATA(sram_stack)));
175
176         return 0;
177 }
178 arch_initcall(rk312x_pie_init);