Merge remote-tracking branch 'origin/upstream/linux-linaro-lsk-v3.10-android' into...
[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 <asm/hardware/cache-l2x0.h>
23 #include "common.h"
24 #include "cpu_axi.h"
25 #include "loader.h"
26 #include "pmu.h"
27 #include "sram.h"
28
29 static int __init rockchip_cpu_axi_init(void)
30 {
31         struct device_node *np, *cp;
32         void __iomem *base, *cbase;
33
34         np = of_find_compatible_node(NULL, NULL, "rockchip,cpu_axi_bus");
35         if (!np)
36                 return -ENODEV;
37
38         base = of_iomap(np, 0);
39
40         np = of_get_child_by_name(np, "qos");
41         if (np) {
42                 for_each_child_of_node(np, cp) {
43                         u32 offset, priority[2], mode, bandwidth, saturation;
44                         if (of_property_read_u32(cp, "rockchip,offset", &offset))
45                                 continue;
46                         pr_debug("qos: %s offset %x\n", cp->name, offset);
47                         cbase = base + offset;
48                         if (!of_property_read_u32_array(cp, "rockchip,priority", priority, ARRAY_SIZE(priority))) {
49                                 CPU_AXI_SET_QOS_PRIORITY(priority[0], priority[1], cbase);
50                                 pr_debug("qos: %s priority %x %x\n", cp->name, priority[0], priority[1]);
51                         }
52                         if (!of_property_read_u32(cp, "rockchip,mode", &mode)) {
53                                 CPU_AXI_SET_QOS_MODE(mode, cbase);
54                                 pr_debug("qos: %s mode %x\n", cp->name, mode);
55                         }
56                         if (!of_property_read_u32(cp, "rockchip,bandwidth", &bandwidth)) {
57                                 CPU_AXI_SET_QOS_BANDWIDTH(bandwidth, cbase);
58                                 pr_debug("qos: %s bandwidth %x\n", cp->name, bandwidth);
59                         }
60                         if (!of_property_read_u32(cp, "rockchip,saturation", &saturation)) {
61                                 CPU_AXI_SET_QOS_SATURATION(saturation, cbase);
62                                 pr_debug("qos: %s saturation %x\n", cp->name, saturation);
63                         }
64                 }
65         };
66
67         writel_relaxed(0x3f, base + 0x0014);    // memory scheduler read latency
68         dsb();
69
70         iounmap(base);
71
72         return 0;
73 }
74 early_initcall(rockchip_cpu_axi_init);
75
76 static int __init rockchip_pl330_l2_cache_init(void)
77 {
78         struct device_node *np;
79         void __iomem *base;
80         u32 aux[2] = { 0, ~0 }, prefetch, power;
81
82         np = of_find_compatible_node(NULL, NULL, "rockchip,pl310-cache");
83         if (!np)
84                 return -ENODEV;
85
86         base = of_iomap(np, 0);
87         if (!base)
88                 return -EINVAL;
89
90         if (!of_property_read_u32(np, "rockchip,prefetch-ctrl", &prefetch)) {
91                 /* L2X0 Prefetch Control */
92                 writel_relaxed(prefetch, base + L2X0_PREFETCH_CTRL);
93                 pr_debug("l2c: prefetch %x\n", prefetch);
94         }
95
96         if (!of_property_read_u32(np, "rockchip,power-ctrl", &power)) {
97                 /* L2X0 Power Control */
98                 writel_relaxed(power, base + L2X0_POWER_CTRL);
99                 pr_debug("l2c: power %x\n", power);
100         }
101
102         iounmap(base);
103
104         of_property_read_u32_array(np, "rockchip,aux-ctrl", aux, ARRAY_SIZE(aux));
105         pr_debug("l2c: aux %08x mask %08x\n", aux[0], aux[1]);
106
107         l2x0_of_init(aux[0], aux[1]);
108
109         return 0;
110 }
111 early_initcall(rockchip_pl330_l2_cache_init);
112
113 struct gen_pool *rockchip_sram_pool = NULL;
114 struct pie_chunk *rockchip_pie_chunk = NULL;
115 void *rockchip_sram_virt = NULL;
116 size_t rockchip_sram_size = 0;
117 char *rockchip_sram_stack = NULL;
118
119 int __init rockchip_pie_init(void)
120 {
121         struct device_node *np;
122
123         np = of_find_node_by_path("/");
124         if (!np)
125                 return -ENODEV;
126
127         rockchip_sram_pool = of_get_named_gen_pool(np, "rockchip,sram", 0);
128         if (!rockchip_sram_pool) {
129                 pr_err("%s: failed to get sram pool\n", __func__);
130                 return -ENODEV;
131         }
132         rockchip_sram_size = gen_pool_size(rockchip_sram_pool);
133
134         return 0;
135 }
136
137 static bool is_panic = false;
138
139 static int panic_event(struct notifier_block *this, unsigned long event, void *ptr)
140 {
141         is_panic = true;
142         return NOTIFY_DONE;
143 }
144
145 static struct notifier_block panic_block = {
146         .notifier_call  = panic_event,
147 };
148
149 static int boot_mode;
150
151 int rockchip_boot_mode(void)
152 {
153         return boot_mode;
154 }
155 EXPORT_SYMBOL(rockchip_boot_mode);
156
157 static inline const char *boot_flag_name(u32 flag)
158 {
159         flag -= SYS_KERNRL_REBOOT_FLAG;
160         switch (flag) {
161         case BOOT_NORMAL: return "NORMAL";
162         case BOOT_LOADER: return "LOADER";
163         case BOOT_MASKROM: return "MASKROM";
164         case BOOT_RECOVER: return "RECOVER";
165         case BOOT_NORECOVER: return "NORECOVER";
166         case BOOT_SECONDOS: return "SECONDOS";
167         case BOOT_WIPEDATA: return "WIPEDATA";
168         case BOOT_WIPEALL: return "WIPEALL";
169         case BOOT_CHECKIMG: return "CHECKIMG";
170         case BOOT_FASTBOOT: return "FASTBOOT";
171         default: return "";
172         }
173 }
174
175 static inline const char *boot_mode_name(u32 mode)
176 {
177         switch (mode) {
178         case BOOT_MODE_NORMAL: return "NORMAL";
179         case BOOT_MODE_FACTORY2: return "FACTORY2";
180         case BOOT_MODE_RECOVERY: return "RECOVERY";
181         case BOOT_MODE_CHARGE: return "CHARGE";
182         case BOOT_MODE_POWER_TEST: return "POWER_TEST";
183         case BOOT_MODE_OFFMODE_CHARGING: return "OFFMODE_CHARGING";
184         case BOOT_MODE_REBOOT: return "REBOOT";
185         case BOOT_MODE_PANIC: return "PANIC";
186         case BOOT_MODE_WATCHDOG: return "WATCHDOG";
187         default: return "";
188         }
189 }
190
191 void __init rockchip_boot_mode_init(u32 flag, u32 mode)
192 {
193         boot_mode = mode;
194         if (mode || ((flag & 0xff) && ((flag & 0xffffff00) == SYS_KERNRL_REBOOT_FLAG)))
195                 printk("Boot mode: %s (%d) flag: %s (0x%08x)\n", boot_mode_name(mode), mode, boot_flag_name(flag), flag);
196         atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
197 }
198
199 void rockchip_restart_get_boot_mode(const char *cmd, u32 *flag, u32 *mode)
200 {
201         *flag = 0;
202         *mode = BOOT_MODE_REBOOT;
203
204         if (cmd) {
205                 if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader"))
206                         *flag = SYS_LOADER_REBOOT_FLAG + BOOT_LOADER;
207                 else if(!strcmp(cmd, "recovery"))
208                         *flag = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;
209                 else if (!strcmp(cmd, "charge"))
210                         *mode = BOOT_MODE_CHARGE;
211         } else {
212                 if (is_panic)
213                         *mode = BOOT_MODE_PANIC;
214         }
215 }
216
217 struct rockchip_pmu_operations rockchip_pmu_ops;