arm64: configs: synchronize with other 3399 config for 3399 linux
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rk3188.c
1 /*
2  * Device Tree support for Rockchip RK3188
3  *
4  * Copyright (C) 2013-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/init.h>
20 #include <linux/irqchip.h>
21 #include <linux/kernel.h>
22 #include <linux/of_address.h>
23 #include <linux/of_platform.h>
24 #include <linux/rockchip/dvfs.h>
25 #include <linux/rockchip/common.h>
26 #include <linux/rockchip/cpu.h>
27 #include <linux/rockchip/cpu_axi.h>
28 #include <linux/rockchip/cru.h>
29 #include <linux/rockchip/grf.h>
30 #include <linux/rockchip/iomap.h>
31 #include <linux/rockchip/pmu.h>
32 #include <asm/mach/arch.h>
33 #include <asm/mach/map.h>
34 #include "loader.h"
35 #include "sram.h"
36
37 #define RK3188_DEVICE(name) \
38         { \
39                 .virtual        = (unsigned long) RK_##name##_VIRT, \
40                 .pfn            = __phys_to_pfn(RK3188_##name##_PHYS), \
41                 .length         = RK3188_##name##_SIZE, \
42                 .type           = MT_DEVICE, \
43         }
44
45 static struct map_desc rk3188_io_desc[] __initdata = {
46         RK3188_DEVICE(CRU),
47         RK3188_DEVICE(GRF),
48         RK3188_DEVICE(PMU),
49         RK3188_DEVICE(ROM),
50         RK3188_DEVICE(EFUSE),
51         RK3188_DEVICE(CPU_AXI_BUS),
52         RK_DEVICE(RK_DDR_VIRT, RK3188_DDR_PCTL_PHYS, RK3188_DDR_PCTL_SIZE),
53         RK_DEVICE(RK_DDR_VIRT + RK3188_DDR_PCTL_SIZE, RK3188_DDR_PUBL_PHYS, RK3188_DDR_PUBL_SIZE),
54         RK_DEVICE(RK_GPIO_VIRT(0), RK3188_GPIO0_PHYS, RK3188_GPIO_SIZE),
55         RK_DEVICE(RK_GPIO_VIRT(1), RK3188_GPIO1_PHYS, RK3188_GPIO_SIZE),
56         RK_DEVICE(RK_GPIO_VIRT(2), RK3188_GPIO2_PHYS, RK3188_GPIO_SIZE),
57         RK_DEVICE(RK_GPIO_VIRT(3), RK3188_GPIO3_PHYS, RK3188_GPIO_SIZE),
58         RK_DEVICE(RK_DEBUG_UART_VIRT, RK3188_UART2_PHYS, RK3188_UART_SIZE),
59 };
60
61 static void __init rk3188_boot_mode_init(void)
62 {
63         u32 flag = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_SYS_REG0);
64         u32 mode = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_SYS_REG1);
65
66         if (flag == (SYS_KERNRL_REBOOT_FLAG | BOOT_RECOVER)) {
67                 mode = BOOT_MODE_RECOVERY;
68         }
69         rockchip_boot_mode_init(flag, mode);
70 #ifdef CONFIG_RK29_WATCHDOG
71         writel_relaxed(BOOT_MODE_WATCHDOG, RK_PMU_VIRT + RK3188_PMU_SYS_REG1);
72 #endif
73 }
74 static void usb_uart_init(void)
75 {
76         u32 soc_status0;
77
78         writel_relaxed(0x03100000, RK_GRF_VIRT + RK3188_GRF_UOC0_CON0);
79         soc_status0 = (readl_relaxed(RK_GRF_VIRT + RK3188_GRF_SOC_STATUS0));
80
81 #ifdef CONFIG_RK_USB_UART
82         if (!(soc_status0 & (1<<10)) && (soc_status0 & (1<<13))) {
83                 /* software control usb phy enable */
84                 writel_relaxed(0x00040004, RK_GRF_VIRT + RK3188_GRF_UOC0_CON2);
85                 /* usb phy enter suspend */
86                 writel_relaxed(0x003f002a, RK_GRF_VIRT + RK3188_GRF_UOC0_CON3);
87                 writel_relaxed(0x03000300, RK_GRF_VIRT + RK3188_GRF_UOC0_CON0);
88     }    
89 #endif
90 }
91
92 static void __init rk3188_dt_map_io(void)
93 {
94         iotable_init(rk3188_io_desc, ARRAY_SIZE(rk3188_io_desc));
95         debug_ll_io_init();
96         usb_uart_init();
97
98         rockchip_soc_id = ROCKCHIP_SOC_RK3188;
99         if (readl_relaxed(RK_ROM_VIRT + 0x27f0) == 0x33313042
100          && readl_relaxed(RK_ROM_VIRT + 0x27f4) == 0x32303133
101          && readl_relaxed(RK_ROM_VIRT + 0x27f8) == 0x30313331
102          && readl_relaxed(RK_ROM_VIRT + 0x27fc) == 0x56313031)
103                 rockchip_soc_id = ROCKCHIP_SOC_RK3188PLUS;
104
105         /* rki2c is used instead of old i2c */
106         writel_relaxed(0xF800F800, RK_GRF_VIRT + RK3188_GRF_SOC_CON1);
107
108         rk3188_boot_mode_init();
109 }
110
111 static const u8 pmu_pd_map[] = {
112         [PD_CPU_0] = 0,
113         [PD_CPU_1] = 1,
114         [PD_CPU_2] = 2,
115         [PD_CPU_3] = 3,
116         [PD_SCU] = 4,
117         [PD_BUS] = 5,
118         [PD_PERI] = 6,
119         [PD_VIO] = 7,
120         [PD_VIDEO] = 8,
121         [PD_GPU] = 9,
122         [PD_CS] = 10,
123 };
124
125 static bool rk3188_pmu_power_domain_is_on(enum pmu_power_domain pd)
126 {
127         /* 1'b0: power on, 1'b1: power off */
128         return !(readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & BIT(pmu_pd_map[pd]));
129 }
130
131 static noinline void rk3188_do_pmu_set_power_domain(enum pmu_power_domain domain, bool on)
132 {
133         u8 pd = pmu_pd_map[domain];
134         u32 val = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_CON);
135         if (on)
136                 val &= ~BIT(pd);
137         else
138                 val |=  BIT(pd);
139         writel_relaxed(val, RK_PMU_VIRT + RK3188_PMU_PWRDN_CON);
140         dsb();
141
142         while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & BIT(pd)) == on)
143                 ;
144 }
145
146 static DEFINE_SPINLOCK(pmu_misc_con1_lock);
147
148 static const u8 pmu_req_map[] = {
149         [IDLE_REQ_BUS] = 1,
150         [IDLE_REQ_PERI] = 2,
151         [IDLE_REQ_GPU] = 3,
152         [IDLE_REQ_VIDEO] = 4,
153         [IDLE_REQ_VIO] = 5,
154 };
155
156 static const u8 pmu_idle_map[] = {
157         [IDLE_REQ_DMA] = 14,
158         [IDLE_REQ_CORE] = 15,
159         [IDLE_REQ_VIO] = 22,
160         [IDLE_REQ_VIDEO] = 23,
161         [IDLE_REQ_GPU] = 24,
162         [IDLE_REQ_PERI] = 25,
163         [IDLE_REQ_BUS] = 26,
164 };
165
166 static const u8 pmu_ack_map[] = {
167         [IDLE_REQ_DMA] = 17,
168         [IDLE_REQ_CORE] = 18,
169         [IDLE_REQ_VIO] = 27,
170         [IDLE_REQ_VIDEO] = 28,
171         [IDLE_REQ_GPU] = 29,
172         [IDLE_REQ_PERI] = 30,
173         [IDLE_REQ_BUS] = 31,
174 };
175
176 static int rk3188_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
177 {
178         u32 idle_mask = BIT(pmu_idle_map[req]);
179         u32 idle_target = idle << pmu_idle_map[req];
180         u32 ack_mask = BIT(pmu_ack_map[req]);
181         u32 ack_target = idle << pmu_ack_map[req];
182         u32 mask = BIT(pmu_req_map[req]);
183         u32 val;
184         unsigned long flags;
185
186         spin_lock_irqsave(&pmu_misc_con1_lock, flags);
187         val = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_MISC_CON1);
188         if (idle)
189                 val |=  mask;
190         else
191                 val &= ~mask;
192         writel_relaxed(val, RK_PMU_VIRT + RK3188_PMU_MISC_CON1);
193         dsb();
194
195         while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & ack_mask) != ack_target)
196                 ;
197         while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & idle_mask) != idle_target)
198                 ;
199         spin_unlock_irqrestore(&pmu_misc_con1_lock, flags);
200
201         return 0;
202 }
203
204 /*
205  *  software should power down or power up power domain one by one. Power down or
206  *  power up multiple power domains simultaneously will result in chip electric current
207  *  change dramatically which will affect the chip function.
208  */
209 static DEFINE_SPINLOCK(pmu_pd_lock);
210 static u32 lcdc0_qos[CPU_AXI_QOS_NUM_REGS];
211 static u32 lcdc1_qos[CPU_AXI_QOS_NUM_REGS];
212 static u32 cif0_qos[CPU_AXI_QOS_NUM_REGS];
213 static u32 cif1_qos[CPU_AXI_QOS_NUM_REGS];
214 static u32 ipp_qos[CPU_AXI_QOS_NUM_REGS];
215 static u32 rga_qos[CPU_AXI_QOS_NUM_REGS];
216 static u32 gpu_qos[CPU_AXI_QOS_NUM_REGS];
217 static u32 vpu_qos[CPU_AXI_QOS_NUM_REGS];
218
219 #define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_VIRT)
220 #define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_VIRT)
221
222 static int rk3188_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
223 {
224         unsigned long flags;
225
226         spin_lock_irqsave(&pmu_pd_lock, flags);
227         if (rk3188_pmu_power_domain_is_on(pd) == on) {
228                 spin_unlock_irqrestore(&pmu_pd_lock, flags);
229                 return 0;
230         }
231         if (!on) {
232                 /* if power down, idle request to NIU first */
233                 if (pd == PD_VIO) {
234                         SAVE_QOS(lcdc0_qos, LCDC0);
235                         SAVE_QOS(lcdc1_qos, LCDC1);
236                         SAVE_QOS(cif0_qos, CIF0);
237                         SAVE_QOS(cif1_qos, CIF1);
238                         SAVE_QOS(ipp_qos, IPP);
239                         SAVE_QOS(rga_qos, RGA);
240                         rk3188_pmu_set_idle_request(IDLE_REQ_VIO, true);
241                 } else if (pd == PD_VIDEO) {
242                         SAVE_QOS(vpu_qos, VPU);
243                         rk3188_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
244                 } else if (pd == PD_GPU) {
245                         SAVE_QOS(gpu_qos, GPU);
246                         rk3188_pmu_set_idle_request(IDLE_REQ_GPU, true);
247                 }
248         }
249         rk3188_do_pmu_set_power_domain(pd, on);
250         if (on) {
251                 /* if power up, idle request release to NIU */
252                 if (pd == PD_VIO) {
253                         rk3188_pmu_set_idle_request(IDLE_REQ_VIO, false);
254                         RESTORE_QOS(lcdc0_qos, LCDC0);
255                         RESTORE_QOS(lcdc1_qos, LCDC1);
256                         RESTORE_QOS(cif0_qos, CIF0);
257                         RESTORE_QOS(cif1_qos, CIF1);
258                         RESTORE_QOS(ipp_qos, IPP);
259                         RESTORE_QOS(rga_qos, RGA);
260                 } else if (pd == PD_VIDEO) {
261                         rk3188_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
262                         RESTORE_QOS(vpu_qos, VPU);
263                 } else if (pd == PD_GPU) {
264                         rk3188_pmu_set_idle_request(IDLE_REQ_GPU, false);
265                         RESTORE_QOS(gpu_qos, GPU);
266                 }
267         }
268         spin_unlock_irqrestore(&pmu_pd_lock, flags);
269
270         return 0;
271 }
272
273 static void __init rk3188_dt_init_timer(void)
274 {
275         rockchip_pmu_ops.set_power_domain = rk3188_pmu_set_power_domain;
276         rockchip_pmu_ops.power_domain_is_on = rk3188_pmu_power_domain_is_on;
277         rockchip_pmu_ops.set_idle_request = rk3188_pmu_set_idle_request;
278         of_clk_init(NULL);
279         clocksource_of_init();
280         of_dvfs_init();
281 }
282
283 static void __init rk3188_reserve(void)
284 {
285         /* reserve memory for ION */
286         rockchip_ion_reserve();
287 }
288
289 static const char * const rk3188_dt_compat[] __initconst = {
290         "rockchip,rk3188",
291         NULL,
292 };
293
294 static void rk3188_restart(char mode, const char *cmd)
295 {
296         u32 boot_flag, boot_mode;
297
298         rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);
299
300         writel_relaxed(boot_flag, RK_PMU_VIRT + RK3188_PMU_SYS_REG0);   // for loader
301         writel_relaxed(boot_mode, RK_PMU_VIRT + RK3188_PMU_SYS_REG1);   // for linux
302         dsb();
303
304         /* disable remap */
305         writel_relaxed(1 << (12 + 16), RK_GRF_VIRT + RK3188_GRF_SOC_CON0);
306         /* pll enter slow mode */
307         writel_relaxed(RK3188_PLL_MODE_SLOW(RK3188_APLL_ID) |
308                        RK3188_PLL_MODE_SLOW(RK3188_CPLL_ID) |
309                        RK3188_PLL_MODE_SLOW(RK3188_GPLL_ID),
310                        RK_CRU_VIRT + RK3188_CRU_MODE_CON);
311         dsb();
312         writel_relaxed(0xeca8, RK_CRU_VIRT + RK3188_CRU_GLB_SRST_SND);
313         dsb();
314 }
315 #ifdef CONFIG_PM
316 static void __init rk3188_init_suspend(void);
317 #endif
318 DT_MACHINE_START(RK3188_DT, "RK30board")
319         .smp            = smp_ops(rockchip_smp_ops),
320         .map_io         = rk3188_dt_map_io,
321         .init_time      = rk3188_dt_init_timer,
322         .dt_compat      = rk3188_dt_compat,
323 #ifdef CONFIG_PM
324         .init_late      = rk3188_init_suspend,
325 #endif
326         .reserve        = rk3188_reserve,
327         .restart        = rk3188_restart,
328 MACHINE_END
329
330 #define CPU 3188
331 char PIE_DATA(sram_stack)[1024];
332 EXPORT_PIE_SYMBOL(DATA(sram_stack));
333
334 static int __init rk3188_pie_init(void)
335 {
336         int err;
337
338         if (!cpu_is_rk3188())
339                 return 0;
340
341         err = rockchip_pie_init();
342         if (err)
343                 return err;
344
345         rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk3188);
346         if (IS_ERR(rockchip_pie_chunk)) {
347                 err = PTR_ERR(rockchip_pie_chunk);
348                 pr_err("%s: failed to load section %d\n", __func__, err);
349                 rockchip_pie_chunk = NULL;
350                 return err;
351         }
352
353         rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk, &__pie_common_start[0]);
354         rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk, (char *) DATA(sram_stack) + sizeof(DATA(sram_stack)));
355
356         return 0;
357 }
358 arch_initcall(rk3188_pie_init);
359
360 #ifdef CONFIG_PM
361 #include "pm-rk3188.c"
362 static void __init rk3188_init_suspend(void)
363 {
364         rockchip_suspend_init();
365         rkpm_pie_init();
366         rk3188_suspend_init();
367 }
368 #endif
369 #define CONFIG_ARCH_RK3188
370 #define RK30_DDR_PCTL_BASE RK_DDR_VIRT
371 #define RK30_DDR_PUBL_BASE (RK_DDR_VIRT + RK3188_DDR_PCTL_SIZE)
372 #define rk_pll_flag() 0 /* FIXME */
373 #define sram_printascii(s) do {} while (0) /* FIXME */
374 #include "ddr_rk30.c"
375
376 static int __init rk3188_ddr_init(void)
377 {
378         if (cpu_is_rk3188()) {
379
380                 ddr_change_freq = _ddr_change_freq;
381                 ddr_round_rate = _ddr_round_rate;
382                 ddr_set_auto_self_refresh = _ddr_set_auto_self_refresh;
383
384                 ddr_init(DDR3_DEFAULT, 300);
385         }
386
387         return 0;
388 }
389 arch_initcall_sync(rk3188_ddr_init);
390
391