Merge branch 'develop' of 10.10.10.29:/home/rockchip/kernel into develop
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rk29 / reset.c
1 #include <linux/kernel.h>\r
2 #include <linux/reboot.h>\r
3 \r
4 #include <asm/io.h>\r
5 #include <asm/proc-fns.h>\r
6 #include <asm/cacheflush.h>\r
7 #include <asm/tlb.h>\r
8 #include <asm/traps.h>\r
9 #include <asm/sections.h>\r
10 #include <asm/mach/arch.h>\r
11 #include <asm/mach/map.h>\r
12 #include <asm/stacktrace.h>\r
13 \r
14 #include <mach/rk29_iomap.h>\r
15 #include <mach/cru.h>\r
16 #include <mach/memory.h>\r
17 #include <mach/sram.h>\r
18 #include <mach/pmu.h>\r
19 #include <mach/loader.h>\r
20 #include <mach/board.h>\r
21 \r
22 #include <asm/delay.h>\r
23 #include <asm/tlbflush.h>\r
24 #include <asm/cacheflush.h>\r
25 \r
26 static void  pwm2gpiodefault(void)\r
27 {\r
28         #define     REG_FILE_BASE_ADDR         RK29_GRF_BASE\r
29         volatile unsigned int * pGRF_GPIO2L_IOMUX =  (volatile unsigned int *)(REG_FILE_BASE_ADDR + 0x58);\r
30         #define     GPIO2_BASE_ADDR            RK29_GPIO2_BASE\r
31         volatile unsigned int *pGPIO2_DIR = (volatile unsigned int *)(GPIO2_BASE_ADDR + 0x4);\r
32 \r
33         // iomux pwm2 to gpio2_a[3]\r
34         *pGRF_GPIO2L_IOMUX &= ~(0x3<<6);\r
35         // set gpio to input\r
36         *pGPIO2_DIR &= ~(0x1<<3);\r
37 \r
38         memset((void *)RK29_PWM_BASE, 0, 0x40);\r
39\r
40 \r
41 #if 0\r
42 extern void __rb( void*  );\r
43 static void rb( void )\r
44 {\r
45     void(*cb)(void* ) ;\r
46     \r
47     void * uart_base = (unsigned int *)ioremap( RK29_UART1_PHYS , RK29_UART1_SIZE );\r
48     local_irq_disable();\r
49     cb =  (void(*)(void* ))__pa(__rb);\r
50     __cpuc_flush_kern_all();\r
51     __cpuc_flush_user_all();\r
52     //printk("begin to jump to reboot,uart1 va=0x%p\n" , uart_base);\r
53     //while(testflag);    \r
54     cb( uart_base );\r
55 }\r
56 #endif\r
57 \r
58 static volatile u32 __sramdata reboot_reason = 0;\r
59 static void __sramfunc __noreturn rk29_rb_with_softreset(void)\r
60 {\r
61         u32 reg;\r
62         u32 reason = __raw_readl((u32)&reboot_reason - SRAM_CODE_OFFSET + 0x10130000);\r
63 \r
64         asm volatile (\r
65             "mrc        p15, 0, %0, c1, c0, 0\n\t"\r
66             "bic        %0, %0, #(1 << 0)       @disable MMU\n\t"\r
67             "bic        %0, %0, #(1 << 13)      @set vector to 0x00000000\n\t"\r
68             "bic        %0, %0, #(1 << 12)      @disable I CACHE\n\t"\r
69             "bic        %0, %0, #(1 << 2)       @disable D DACHE\n\t"\r
70             "bic        %0, %0, #(1 << 11)      @disable Branch prediction\n\t"\r
71             "bic        %0, %0, #(1 << 28)      @disable TEX Remap\n\t"\r
72             "mcr        p15, 0, %0, c1, c0, 0\n\t"\r
73             "mov        %0, #0\n\t"\r
74             "mcr        p15, 0, %0, c8, c7, 0   @invalidate whole TLB\n\t"\r
75             "mcr        p15, 0, %0, c7, c5, 6   @invalidate BTC\n\t"\r
76             "dsb\n\t"\r
77             "isb\n\t"\r
78             "b          1f\n\t"\r
79             ".align 5\n\t"\r
80             "1:\n\t"\r
81             : "=r" (reg));\r
82 \r
83         writel(0x00019a00, RK29_CRU_PHYS + CRU_SOFTRST2_CON);\r
84         dsb();\r
85         LOOP(10 * LOOPS_PER_USEC);\r
86 \r
87         writel(0xffffffff, RK29_CRU_PHYS + CRU_SOFTRST2_CON);\r
88         writel(0xffffffff, RK29_CRU_PHYS + CRU_SOFTRST1_CON);\r
89         writel(0xd9fdfdc0, RK29_CRU_PHYS + CRU_SOFTRST0_CON);\r
90         dsb();\r
91 \r
92         LOOP(100 * LOOPS_PER_USEC);\r
93 \r
94         writel(0, RK29_CRU_PHYS + CRU_SOFTRST0_CON);\r
95         writel(0, RK29_CRU_PHYS + CRU_SOFTRST1_CON);\r
96         writel(0x00019a00, RK29_CRU_PHYS + CRU_SOFTRST2_CON);\r
97         dsb();\r
98         LOOP(10 * LOOPS_PER_USEC);\r
99         writel(0, RK29_CRU_PHYS + CRU_SOFTRST2_CON);\r
100         dsb();\r
101         LOOP(10 * LOOPS_PER_USEC);\r
102 \r
103         if (reason) {\r
104                 __raw_writel(0, RK29_TIMER0_PHYS + 0x8);\r
105                 __raw_writel(reason, RK29_TIMER0_PHYS + 0x0);\r
106         }\r
107 \r
108         asm volatile (\r
109             "b 1f\n\t"\r
110             ".align 5\n\t"\r
111             "1:\n\t"\r
112             "dsb\n\t"\r
113             "isb\n\t"\r
114             "mov        pc, #0");\r
115 \r
116         while (1);\r
117 }\r
118 \r
119 void rk29_arch_reset(int mode, const char *cmd)\r
120 {\r
121         void (*rb2)(void);\r
122         u32 boot_mode = BOOT_MODE_REBOOT;\r
123 \r
124         if (cmd) {\r
125                 if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader")) {\r
126                         reboot_reason = SYS_LOADER_ERR_FLAG;\r
127                 } else if (!strcmp(cmd, "recovery")) {\r
128                         reboot_reason = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;\r
129                         boot_mode = BOOT_MODE_RECOVERY;\r
130                 } else if (!strcmp(cmd, "charge")) {\r
131                         boot_mode = BOOT_MODE_CHARGE;\r
132                 }\r
133         } else {\r
134                 if (system_state != SYSTEM_RESTART)\r
135                         boot_mode = BOOT_MODE_PANIC;\r
136         }\r
137         writel(boot_mode, RK29_GRF_BASE + 0xdc); // GRF_OS_REG3\r
138 \r
139         rb2 = (void(*)(void))((u32)rk29_rb_with_softreset - SRAM_CODE_OFFSET + 0x10130000);\r
140 \r
141         local_irq_disable();\r
142         local_fiq_disable();\r
143 \r
144 #ifdef CONFIG_MACH_RK29SDK\r
145         /* from panic? loop for debug */\r
146         if (system_state != SYSTEM_RESTART) {\r
147                 printk("\nLoop for debug...\n");\r
148                 while (1);\r
149         }\r
150 #endif\r
151 \r
152         cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON);\r
153         LOOP(LOOPS_PER_USEC);\r
154 \r
155         pwm2gpiodefault();\r
156 \r
157         cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_GENERAL_MODE_MASK) | CRU_GENERAL_MODE_SLOW, CRU_MODE_CON);\r
158         LOOP(LOOPS_PER_USEC);\r
159 \r
160         cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CODEC_MODE_MASK) | CRU_CODEC_MODE_SLOW, CRU_MODE_CON);\r
161         LOOP(LOOPS_PER_USEC);\r
162 \r
163         cru_writel(0, CRU_CLKGATE0_CON);\r
164         cru_writel(0, CRU_CLKGATE1_CON);\r
165         cru_writel(0, CRU_CLKGATE2_CON);\r
166         cru_writel(0, CRU_CLKGATE3_CON);\r
167         LOOP(LOOPS_PER_USEC);\r
168 \r
169         cru_writel(0, CRU_SOFTRST0_CON);\r
170         cru_writel(0, CRU_SOFTRST1_CON);\r
171         cru_writel(0, CRU_SOFTRST2_CON);\r
172         LOOP(LOOPS_PER_USEC);\r
173 \r
174         cru_writel(1 << 16 | 1 << 13 | 1 << 11 | 1 << 1, CRU_CLKGATE3_CON);\r
175         LOOP(LOOPS_PER_USEC);\r
176 \r
177         writel(readl(RK29_PMU_BASE + PMU_PD_CON) & ~(1 << PD_VCODEC), RK29_PMU_BASE + PMU_PD_CON);\r
178         dsb();\r
179         while (readl(RK29_PMU_BASE + PMU_PD_ST) & (1 << PD_VCODEC))\r
180                 ;\r
181         LOOP(10 * LOOPS_PER_MSEC);\r
182 \r
183         writel(readl(RK29_PMU_BASE + PMU_PD_CON) & ~(1 << PD_DISPLAY), RK29_PMU_BASE + PMU_PD_CON);\r
184         dsb();\r
185         while (readl(RK29_PMU_BASE + PMU_PD_ST) & (1 << PD_DISPLAY))\r
186                 ;\r
187         LOOP(10 * LOOPS_PER_MSEC);\r
188 \r
189         writel(readl(RK29_PMU_BASE + PMU_PD_CON) & ~(1 << PD_GPU), RK29_PMU_BASE + PMU_PD_CON);\r
190         dsb();\r
191         while (readl(RK29_PMU_BASE + PMU_PD_ST) & (1 << PD_GPU))\r
192                 ;\r
193         LOOP(10 * LOOPS_PER_MSEC);\r
194 \r
195         cru_writel(0, CRU_CLKGATE3_CON);\r
196         LOOP(LOOPS_PER_USEC);\r
197 \r
198         //SPI0 clock source = periph_pll_clk, SPI0 divider=8\r
199         cru_writel((cru_readl(CRU_CLKSEL6_CON) & ~0x1FF) | (7 << 2), CRU_CLKSEL6_CON);\r
200 \r
201         //eMMC divider=0x17, SD/MMC0 clock source=arm_pll_clk\r
202         cru_writel((cru_readl(CRU_CLKSEL7_CON) & ~(3 | (0x3f << 18))) | (0x17 << 18), CRU_CLKSEL7_CON);\r
203 \r
204         //UART1 clock divider=0, UART1 clk =24MHz , UART0 and UART1 clock source=periph_pll_clk\r
205         cru_writel((cru_readl(CRU_CLKSEL8_CON) & ~(7 | (0x3f << 14) | (3 << 20))) | (2 << 20), CRU_CLKSEL8_CON);\r
206 \r
207         // remap bit control = 0, normal mode\r
208         writel(readl(RK29_GRF_BASE + 0xc0) & ~(1 << 21), RK29_GRF_BASE + 0xc0);\r
209         // emmc_and_boot_en control=0, normal mode\r
210         writel(readl(RK29_GRF_BASE + 0xbc) & ~(1 << 9), RK29_GRF_BASE + 0xbc);\r
211         dsb();\r
212 \r
213         writel(0, RK29_CPU_AXI_BUS0_PHYS);\r
214         writel(0, RK29_AXI1_PHYS);\r
215         dsb();\r
216 \r
217         // SDMMC_CLKSRC=0, clk_source=clock divider 0\r
218         writel(0, RK29_EMMC_PHYS + 0x0c);\r
219         // SDMMC_CTYPE=0, card_width=1 bit mode\r
220         writel(0, RK29_EMMC_PHYS + 0x18);\r
221         // SDMMC_BLKSIZ=0x200, Block size=512\r
222         writel(0x200, RK29_EMMC_PHYS + 0x1c);\r
223         dsb();\r
224 \r
225         __cpuc_flush_kern_all();\r
226         __cpuc_flush_user_all();\r
227         \r
228         rb2();\r
229 }\r
230 \r
231 \r