ARM: rk: build resource.img with logo_kernel.bmp
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / common.c
1 /*
2  * Copyright (C) 2013-2014 ROCKCHIP, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <linux/clk-provider.h>
16 #include <linux/genalloc.h>
17 #include <linux/init.h>
18 #include <linux/io.h>
19 #include <linux/kernel.h>
20 #include <linux/of_address.h>
21 #include <linux/of_platform.h>
22 #include <linux/of_fdt.h>
23 #include <asm/cputype.h>
24 #include <asm/hardware/cache-l2x0.h>
25 #include <linux/rockchip/common.h>
26 #include <linux/rockchip/pmu.h>
27 #include <linux/memblock.h>
28 #include "cpu_axi.h"
29 #include "loader.h"
30 #include "sram.h"
31
32 static int __init rockchip_cpu_axi_init(void)
33 {
34         struct device_node *np, *gp, *cp;
35         void __iomem *base;
36
37         np = of_find_compatible_node(NULL, NULL, "rockchip,cpu_axi_bus");
38         if (!np)
39                 return -ENODEV;
40
41 #define MAP(base) if (!base) base = of_iomap(cp, 0); if (!base) continue;
42
43         gp = of_get_child_by_name(np, "qos");
44         if (gp) {
45                 for_each_child_of_node(gp, cp) {
46                         u32 priority[2], mode, bandwidth, saturation, extcontrol;
47                         base = NULL;
48 #ifdef DEBUG
49                         {
50                                 struct resource r;
51                                 of_address_to_resource(cp, 0, &r);
52                                 pr_debug("qos: %s [%x ~ %x]\n", cp->name, r.start, r.end);
53                         }
54 #endif
55                         if (!of_property_read_u32_array(cp, "rockchip,priority", priority, ARRAY_SIZE(priority))) {
56                                 MAP(base);
57                                 CPU_AXI_SET_QOS_PRIORITY(priority[0], priority[1], base);
58                                 pr_debug("qos: %s priority %x %x\n", cp->name, priority[0], priority[1]);
59                         }
60                         if (!of_property_read_u32(cp, "rockchip,mode", &mode)) {
61                                 MAP(base);
62                                 CPU_AXI_SET_QOS_MODE(mode, base);
63                                 pr_debug("qos: %s mode %x\n", cp->name, mode);
64                         }
65                         if (!of_property_read_u32(cp, "rockchip,bandwidth", &bandwidth)) {
66                                 MAP(base);
67                                 CPU_AXI_SET_QOS_BANDWIDTH(bandwidth, base);
68                                 pr_debug("qos: %s bandwidth %x\n", cp->name, bandwidth);
69                         }
70                         if (!of_property_read_u32(cp, "rockchip,saturation", &saturation)) {
71                                 MAP(base);
72                                 CPU_AXI_SET_QOS_SATURATION(saturation, base);
73                                 pr_debug("qos: %s saturation %x\n", cp->name, saturation);
74                         }
75                         if (!of_property_read_u32(cp, "rockchip,extcontrol", &extcontrol)) {
76                                 MAP(base);
77                                 CPU_AXI_SET_QOS_EXTCONTROL(extcontrol, base);
78                                 pr_debug("qos: %s extcontrol %x\n", cp->name, extcontrol);
79                         }
80                         if (base)
81                                 iounmap(base);
82                 }
83         };
84
85         gp = of_get_child_by_name(np, "msch");
86         if (gp) {
87                 for_each_child_of_node(gp, cp) {
88                         u32 val;
89                         base = NULL;
90 #ifdef DEBUG
91                         {
92                                 struct resource r;
93                                 of_address_to_resource(cp, 0, &r);
94                                 pr_debug("msch: %s [%x ~ %x]\n", cp->name, r.start, r.end);
95                         }
96 #endif
97                         if (!of_property_read_u32(cp, "rockchip,read-latency", &val)) {
98                                 MAP(base);
99                                 writel_relaxed(val, base + 0x0014);     // memory scheduler read latency
100                                 pr_debug("msch: %s read latency %x\n", cp->name, val);
101                         }
102                         if (base)
103                                 iounmap(base);
104                 }
105         }
106         dsb();
107
108 #undef MAP
109
110         return 0;
111 }
112 early_initcall(rockchip_cpu_axi_init);
113
114 static int __init rockchip_pl330_l2_cache_init(void)
115 {
116         struct device_node *np;
117         void __iomem *base;
118         u32 aux[2] = { 0, ~0 }, prefetch, power;
119
120         if (read_cpuid_part_number() != ARM_CPU_PART_CORTEX_A9)
121                 return -ENODEV;
122
123         np = of_find_compatible_node(NULL, NULL, "rockchip,pl310-cache");
124         if (!np)
125                 return -ENODEV;
126
127         base = of_iomap(np, 0);
128         if (!base)
129                 return -EINVAL;
130
131         if (!of_property_read_u32(np, "rockchip,prefetch-ctrl", &prefetch)) {
132                 /* L2X0 Prefetch Control */
133                 writel_relaxed(prefetch, base + L2X0_PREFETCH_CTRL);
134                 pr_debug("l2c: prefetch %x\n", prefetch);
135         }
136
137         if (!of_property_read_u32(np, "rockchip,power-ctrl", &power)) {
138                 /* L2X0 Power Control */
139                 writel_relaxed(power, base + L2X0_POWER_CTRL);
140                 pr_debug("l2c: power %x\n", power);
141         }
142
143         iounmap(base);
144
145         of_property_read_u32_array(np, "rockchip,aux-ctrl", aux, ARRAY_SIZE(aux));
146         pr_debug("l2c: aux %08x mask %08x\n", aux[0], aux[1]);
147
148         l2x0_of_init(aux[0], aux[1]);
149
150         return 0;
151 }
152 early_initcall(rockchip_pl330_l2_cache_init);
153
154 struct gen_pool *rockchip_sram_pool = NULL;
155 struct pie_chunk *rockchip_pie_chunk = NULL;
156 void *rockchip_sram_virt = NULL;
157 size_t rockchip_sram_size = 0;
158 char *rockchip_sram_stack = NULL;
159
160 #ifdef CONFIG_PIE
161 int __init rockchip_pie_init(void)
162 {
163         struct device_node *np;
164
165         np = of_find_node_by_path("/");
166         if (!np)
167                 return -ENODEV;
168
169         rockchip_sram_pool = of_get_named_gen_pool(np, "rockchip,sram", 0);
170         if (!rockchip_sram_pool) {
171                 pr_err("%s: failed to get sram pool\n", __func__);
172                 return -ENODEV;
173         }
174         rockchip_sram_size = gen_pool_size(rockchip_sram_pool);
175
176         return 0;
177 }
178 #endif
179
180 static bool is_panic = false;
181 extern void console_disable_suspend(void);
182
183 static int panic_event(struct notifier_block *this, unsigned long event, void *ptr)
184 {
185 #if CONFIG_RK_DEBUG_UART >= 0
186         console_disable_suspend();
187 #endif
188         is_panic = true;
189         return NOTIFY_DONE;
190 }
191
192 static struct notifier_block panic_block = {
193         .notifier_call  = panic_event,
194 };
195
196 static int boot_mode;
197
198 int rockchip_boot_mode(void)
199 {
200         return boot_mode;
201 }
202 EXPORT_SYMBOL(rockchip_boot_mode);
203
204 static inline const char *boot_flag_name(u32 flag)
205 {
206         flag -= SYS_KERNRL_REBOOT_FLAG;
207         switch (flag) {
208         case BOOT_NORMAL: return "NORMAL";
209         case BOOT_LOADER: return "LOADER";
210         case BOOT_MASKROM: return "MASKROM";
211         case BOOT_RECOVER: return "RECOVER";
212         case BOOT_NORECOVER: return "NORECOVER";
213         case BOOT_SECONDOS: return "SECONDOS";
214         case BOOT_WIPEDATA: return "WIPEDATA";
215         case BOOT_WIPEALL: return "WIPEALL";
216         case BOOT_CHECKIMG: return "CHECKIMG";
217         case BOOT_FASTBOOT: return "FASTBOOT";
218         case BOOT_CHARGING: return "CHARGING";
219         default: return "";
220         }
221 }
222
223 static inline const char *boot_mode_name(u32 mode)
224 {
225         switch (mode) {
226         case BOOT_MODE_NORMAL: return "NORMAL";
227         case BOOT_MODE_FACTORY2: return "FACTORY2";
228         case BOOT_MODE_RECOVERY: return "RECOVERY";
229         case BOOT_MODE_CHARGE: return "CHARGE";
230         case BOOT_MODE_POWER_TEST: return "POWER_TEST";
231         case BOOT_MODE_OFFMODE_CHARGING: return "OFFMODE_CHARGING";
232         case BOOT_MODE_REBOOT: return "REBOOT";
233         case BOOT_MODE_PANIC: return "PANIC";
234         case BOOT_MODE_WATCHDOG: return "WATCHDOG";
235         case BOOT_MODE_TSADC: return "TSADC";
236         default: return "";
237         }
238 }
239
240 void __init rockchip_boot_mode_init(u32 flag, u32 mode)
241 {
242         boot_mode = mode;
243         if (mode || ((flag & 0xff) && ((flag & 0xffffff00) == SYS_KERNRL_REBOOT_FLAG)))
244                 printk("Boot mode: %s (%d) flag: %s (0x%08x)\n", boot_mode_name(mode), mode, boot_flag_name(flag), flag);
245         atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
246 }
247
248 void rockchip_restart_get_boot_mode(const char *cmd, u32 *flag, u32 *mode)
249 {
250         *flag = SYS_LOADER_REBOOT_FLAG + BOOT_NORMAL;
251         *mode = BOOT_MODE_REBOOT;
252
253         if (cmd) {
254                 if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader"))
255                         *flag = SYS_LOADER_REBOOT_FLAG + BOOT_LOADER;
256                 else if(!strcmp(cmd, "recovery"))
257                         *flag = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;
258                 else if (!strcmp(cmd, "fastboot"))
259                         *flag = SYS_LOADER_REBOOT_FLAG + BOOT_FASTBOOT;
260                 else if (!strcmp(cmd, "charge")) {
261                         *flag = SYS_LOADER_REBOOT_FLAG + BOOT_CHARGING;
262                         *mode = BOOT_MODE_CHARGE;
263                 }
264         } else {
265                 if (is_panic)
266                         *mode = BOOT_MODE_PANIC;
267         }
268 }
269
270 struct rockchip_pmu_operations rockchip_pmu_ops;
271 void (*ddr_bandwidth_get)(struct ddr_bw_info *ddr_bw_ch0,
272                           struct ddr_bw_info *ddr_bw_ch1);
273 int (*ddr_change_freq)(uint32_t nMHz) = NULL;
274 long (*ddr_round_rate)(uint32_t nMHz) = NULL;
275 void (*ddr_set_auto_self_refresh)(bool en) = NULL;
276
277 extern struct ion_platform_data ion_pdata;
278 extern void __init ion_reserve(struct ion_platform_data *data);
279 extern int __init rockchip_ion_find_heap(unsigned long node,
280                                 const char *uname, int depth, void *data);
281 void __init rockchip_ion_reserve(void)
282 {
283 #ifdef CONFIG_ION_ROCKCHIP
284         printk("%s\n", __func__);
285         of_scan_flat_dt(rockchip_ion_find_heap, (void*)&ion_pdata);
286         ion_reserve(&ion_pdata);
287 #endif
288 }
289
290 bool rockchip_jtag_enabled = false;
291 static int __init rockchip_jtag_enable(char *__unused)
292 {
293         rockchip_jtag_enabled = true;
294         printk("rockchip jtag enabled\n");
295         return 1;
296 }
297 __setup("rockchip_jtag", rockchip_jtag_enable);
298
299 phys_addr_t uboot_logo_base=0;
300 phys_addr_t uboot_logo_size=0;
301 phys_addr_t uboot_logo_offset=0;
302
303 void __init rockchip_uboot_mem_reserve(void)
304 {
305         if (uboot_logo_size) {
306                 if (!memblock_is_region_reserved(uboot_logo_base, uboot_logo_size)
307                         && !memblock_reserve(uboot_logo_base, uboot_logo_size)){
308                         pr_info("%s: reserve %zx@%zx for uboot logo\n", __func__,
309                                 uboot_logo_size, uboot_logo_base);
310                 } else {
311                         pr_err("%s: reserve of %zx@%zx failed\n", __func__,
312                                uboot_logo_size, uboot_logo_base);
313                 }
314         }
315 }
316
317 static int __init rockchip_uboot_logo_setup(char *p)
318 {
319         char *endp;
320
321         uboot_logo_size = memparse(p, &endp);
322         if (*endp == '@') {
323                 uboot_logo_base = memparse(endp + 1, &endp);
324                 if (*endp == ':') {
325                         uboot_logo_offset = memparse(endp + 1, NULL);
326                 }
327         }
328
329         pr_info("%s: mem: %zx@%zx, offset:%zx\n", __func__,
330                 uboot_logo_size, uboot_logo_base, uboot_logo_offset);
331
332         return 0;
333 }
334 early_param("uboot_logo", rockchip_uboot_logo_setup);
335
336 static int __init rockchip_uboot_mem_late_init(void)
337 {
338         phys_addr_t addr = 0;
339         phys_addr_t end = 0;
340
341         if (uboot_logo_size) {
342                 addr = PAGE_ALIGN(uboot_logo_base);
343                 end = (uboot_logo_base+uboot_logo_size)&PAGE_MASK;
344
345                 pr_info("%s: Freeing uboot logo memory: %zx@%zx\n", __func__,
346                         uboot_logo_size, uboot_logo_base);
347
348                 memblock_free(uboot_logo_base, uboot_logo_size);
349
350                 for (; addr < end; addr += PAGE_SIZE)
351                         free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT));
352         }
353
354         return 0;
355 }
356 late_initcall(rockchip_uboot_mem_late_init);