rk3026: i2s add several attempts to double confirm i2s frac effect
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rk3026 / reset.c
1 #include <linux/io.h>
2 #include <linux/kernel.h>
3 #include <mach/system.h>
4 #include <linux/string.h>
5 #include <mach/cru.h>
6 #include <mach/grf.h>
7 #include <mach/loader.h>
8 #include <mach/board.h>
9
10 //#define DEBUG // for jtag debug
11
12 #define cru_readl(offset)     readl_relaxed(RK30_CRU_BASE + offset)
13 #define cru_writel(v, offset) do { writel_relaxed(v, RK30_CRU_BASE + offset); } while (0)
14 #define grf_readl(offset)     readl_relaxed(RK30_GRF_BASE + offset)
15 #define grf_writel(v, offset) do { writel_relaxed(v, RK30_GRF_BASE + offset); dsb(); } while (0)
16
17 static bool is_panic = false;
18
19 static int panic_event(struct notifier_block *this, unsigned long event, void *ptr)
20 {
21         is_panic = true;
22         return NOTIFY_DONE;
23 }
24
25 static struct notifier_block panic_block = {
26         .notifier_call  = panic_event,
27 };
28
29 static int __init arch_reset_init(void)
30 {
31         atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
32         return 0;
33 }
34 core_initcall(arch_reset_init);
35
36 #ifdef DEBUG
37 __sramdata volatile int reset_loop = 1;
38 #endif
39
40 static void __sramfunc __noreturn soft_reset(void)
41 {
42         /* pll enter slow mode */
43         cru_writel(0xffff0000, CRU_MODE_CON);
44         dsb();
45
46         /* restore clock select and divide */
47         cru_writel(0xffff0200, CRU_CLKSELS_CON(0));
48         cru_writel(0xffff3113, CRU_CLKSELS_CON(1));
49         cru_writel(0xfff00000, CRU_CLKSELS_CON(2)); // 3:0 reserved
50         cru_writel(0xffff0200, CRU_CLKSELS_CON(3));
51         cru_writel(0x003f0000, CRU_CLKSELS_CON(4)); // 15:6 reserved
52         cru_writel(0x003f0000, CRU_CLKSELS_CON(5)); // 15:6 reserved
53         cru_writel(0x0bb8ea60, CRU_CLKSELS_CON(6));
54         cru_writel(0x0bb8ea60, CRU_CLKSELS_CON(7));
55         cru_writel(0xffff2100, CRU_CLKSELS_CON(10));
56         cru_writel(0x007f0017, CRU_CLKSELS_CON(11)); // 15:7 reserved
57         cru_writel(0xffff1717, CRU_CLKSELS_CON(12));
58         cru_writel(0xffff0200, CRU_CLKSELS_CON(13));
59         cru_writel(0xffff0200, CRU_CLKSELS_CON(14));
60         cru_writel(0xffff0200, CRU_CLKSELS_CON(15));
61         cru_writel(0x0bb8ea60, CRU_CLKSELS_CON(17));
62         cru_writel(0x0bb8ea60, CRU_CLKSELS_CON(18));
63         cru_writel(0x0bb8ea60, CRU_CLKSELS_CON(19));
64         cru_writel(0x0bb8ea60, CRU_CLKSELS_CON(23));
65         cru_writel(0xffff1700, CRU_CLKSELS_CON(24));
66         cru_writel(0x017f0107, CRU_CLKSELS_CON(25)); // 15:9 7 reserved
67         cru_writel(0xffff0000, CRU_CLKSELS_CON(26));
68         cru_writel(0xffff0700, CRU_CLKSELS_CON(27));
69         cru_writel(0xffff0700, CRU_CLKSELS_CON(28));
70         cru_writel(0xffff0012, CRU_CLKSELS_CON(29));
71         cru_writel(0xffff0300, CRU_CLKSELS_CON(30));
72         cru_writel(0xffff0001, CRU_CLKSELS_CON(31));
73         cru_writel(0xffff0303, CRU_CLKSELS_CON(32));
74         cru_writel(0xffff0003, CRU_CLKSELS_CON(34));
75         dsb();
76
77         /* idle request PERI/VIO/VPU/GPU */
78         grf_writel(0x1e00ffff, GRF_SOC_CON2);
79         while ((grf_readl(GRF_SOC_STATUS0) & (0x1e << 16)) != (0x1e << 16))
80                 ;
81         while ((grf_readl(GRF_SOC_STATUS0) & (0x1e << 22)) != (0x1e << 22))
82                 ;
83
84         /* software reset modules */
85 #ifdef DEBUG
86         cru_writel(0xfff3ffff, CRU_SOFTRSTS_CON(8)); // CORE_DBG/DBG_APB
87 #else
88         cru_writel(0xffffffff, CRU_SOFTRSTS_CON(8));
89 #endif
90         cru_writel(0xffffffff, CRU_SOFTRSTS_CON(7));
91         cru_writel(0xffffffff, CRU_SOFTRSTS_CON(6));
92         cru_writel(0xffffffff, CRU_SOFTRSTS_CON(5));
93         cru_writel(0x7fffffff, CRU_SOFTRSTS_CON(4)); // DDRMSCH
94 #ifdef DEBUG
95         cru_writel(0xff63ffff, CRU_SOFTRSTS_CON(3)); // DAP_PO/DAP/DAP_SYS
96 #else
97         cru_writel(0xff7fffff, CRU_SOFTRSTS_CON(3)); // GRF
98 #endif
99         cru_writel(0xfff0ffff, CRU_SOFTRSTS_CON(2)); // GPIO0/1/2/3
100         cru_writel(0xffdfffff, CRU_SOFTRSTS_CON(1)); // INTMEM
101 #ifdef DEBUG
102         cru_writel(0x1e60ffff, CRU_SOFTRSTS_CON(0)); // MCORE_DBG/CORE0_DBG
103 #else
104         cru_writel(0x1fe0ffff, CRU_SOFTRSTS_CON(0)); // CORE_SRST_WDT_SEL/MCORE/CORE0/CORE1/ACLK_CORE/STRC_SYS_AXI/L2C
105 #endif
106         dsb();
107
108         sram_udelay(1000);
109
110         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(0));
111         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(1));
112         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(2));
113         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(3));
114         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(4));
115         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(5));
116         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(6));
117         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(7));
118         cru_writel(0xffff0000, CRU_SOFTRSTS_CON(8));
119         dsb();
120
121         /* disable idle request */
122         grf_writel(0x3f000000, GRF_SOC_CON2);
123         while (grf_readl(GRF_SOC_STATUS0) & (0x3f << 16))
124                 ;
125         while (grf_readl(GRF_SOC_STATUS0) & (0x3f << 22))
126                 ;
127
128 #ifdef DEBUG
129 //      while (reset_loop);
130 #endif
131
132         cru_writel(0x801cffff, CRU_SOFTRSTS_CON(0)); // MCORE/CORE0/CORE1/L2C
133         dsb();
134
135         while (1);
136 }
137
138 static void rk30_arch_reset(char mode, const char *cmd)
139 {
140         unsigned i;
141         u32 boot_flag = 0;
142         u32 boot_mode = BOOT_MODE_REBOOT;
143
144         if (cmd) {
145                 if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader"))
146                         boot_flag = SYS_LOADER_REBOOT_FLAG + BOOT_LOADER;
147                 else if(!strcmp(cmd, "recovery"))
148                         boot_flag = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;
149                 else if (!strcmp(cmd, "charge"))
150                         boot_mode = BOOT_MODE_CHARGE;
151         } else {
152                 if (is_panic)
153                         boot_mode = BOOT_MODE_PANIC;
154         }
155         grf_writel(boot_flag, GRF_OS_REG4);     // for loader
156         grf_writel(boot_mode, GRF_OS_REG5);     // for linux
157
158         /* enable all clock */
159         for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
160                 cru_writel(0xffff0000, CRU_CLKGATES_CON(i));
161
162         /* disable remap */
163         grf_writel(1 << (12 + 16), GRF_SOC_CON0);
164
165         ((void(*)(void))((u32)soft_reset - (u32)RK30_IMEM_BASE + (u32)RK30_IMEM_NONCACHED))();
166 }
167
168 void (*arch_reset)(char, const char *) = rk30_arch_reset;