1 #include <linux/kernel.h>
\r
2 #include <linux/reboot.h>
\r
5 #include <asm/proc-fns.h>
\r
6 #include <asm/cacheflush.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
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
22 #include <asm/delay.h>
\r
23 #include <asm/tlbflush.h>
\r
24 #include <asm/cacheflush.h>
\r
26 static void pwm2gpiodefault(void)
\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
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
38 memset((void *)RK29_PWM_BASE, 0, 0x40);
\r
42 extern void __rb( void* );
\r
43 static void rb( void )
\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
58 static volatile u32 __sramdata reboot_reason = 0;
\r
59 static void __sramfunc __noreturn rk29_rb_with_softreset(void)
\r
62 u32 reason = __raw_readl((u32)&reboot_reason - SRAM_CODE_OFFSET + 0x10130000);
\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
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
83 writel(0x00019a00, RK29_CRU_PHYS + CRU_SOFTRST2_CON);
\r
85 LOOP(10 * LOOPS_PER_USEC);
\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
92 LOOP(100 * LOOPS_PER_USEC);
\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
98 LOOP(10 * LOOPS_PER_USEC);
\r
99 writel(0, RK29_CRU_PHYS + CRU_SOFTRST2_CON);
\r
101 LOOP(10 * LOOPS_PER_USEC);
\r
103 /* reset GRF_MEM_CON, else bootloader usb function may not work properly */
\r
104 writel(0, RK29_GRF_PHYS + 0xac);
\r
108 __raw_writel(0, RK29_TIMER0_PHYS + 0x8);
\r
109 __raw_writel(reason, RK29_TIMER0_PHYS + 0x0);
\r
123 void rk29_arch_reset(int mode, const char *cmd)
\r
126 u32 boot_mode = BOOT_MODE_REBOOT;
\r
129 if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader")) {
\r
130 reboot_reason = SYS_LOADER_ERR_FLAG;
\r
131 } else if (!strcmp(cmd, "recovery")) {
\r
132 reboot_reason = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;
\r
133 boot_mode = BOOT_MODE_RECOVERY;
\r
134 } else if (!strcmp(cmd, "charge")) {
\r
135 boot_mode = BOOT_MODE_CHARGE;
\r
138 if (system_state != SYSTEM_RESTART)
\r
139 boot_mode = BOOT_MODE_PANIC;
\r
141 writel(boot_mode, RK29_GRF_BASE + 0xdc); // GRF_OS_REG3
\r
143 rb2 = (void(*)(void))((u32)rk29_rb_with_softreset - SRAM_CODE_OFFSET + 0x10130000);
\r
145 local_irq_disable();
\r
146 local_fiq_disable();
\r
148 #ifdef CONFIG_MACH_RK29SDK
\r
149 /* from panic? loop for debug */
\r
150 if (system_state != SYSTEM_RESTART) {
\r
151 printk("\nLoop for debug...\n");
\r
156 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON);
\r
157 LOOP(LOOPS_PER_USEC);
\r
161 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_GENERAL_MODE_MASK) | CRU_GENERAL_MODE_SLOW, CRU_MODE_CON);
\r
162 LOOP(LOOPS_PER_USEC);
\r
164 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CODEC_MODE_MASK) | CRU_CODEC_MODE_SLOW, CRU_MODE_CON);
\r
165 LOOP(LOOPS_PER_USEC);
\r
167 cru_writel(0, CRU_CLKGATE0_CON);
\r
168 cru_writel(0, CRU_CLKGATE1_CON);
\r
169 cru_writel(0, CRU_CLKGATE2_CON);
\r
170 cru_writel(0, CRU_CLKGATE3_CON);
\r
171 LOOP(LOOPS_PER_USEC);
\r
173 cru_writel(0, CRU_SOFTRST0_CON);
\r
174 cru_writel(0, CRU_SOFTRST1_CON);
\r
175 cru_writel(0, CRU_SOFTRST2_CON);
\r
176 LOOP(LOOPS_PER_USEC);
\r
178 cru_writel(1 << 16 | 1 << 13 | 1 << 11 | 1 << 1, CRU_CLKGATE3_CON);
\r
179 LOOP(LOOPS_PER_USEC);
\r
181 writel(readl(RK29_PMU_BASE + PMU_PD_CON) & ~(1 << PD_VCODEC), RK29_PMU_BASE + PMU_PD_CON);
\r
183 while (readl(RK29_PMU_BASE + PMU_PD_ST) & (1 << PD_VCODEC))
\r
185 LOOP(10 * LOOPS_PER_MSEC);
\r
187 writel(readl(RK29_PMU_BASE + PMU_PD_CON) & ~(1 << PD_DISPLAY), RK29_PMU_BASE + PMU_PD_CON);
\r
189 while (readl(RK29_PMU_BASE + PMU_PD_ST) & (1 << PD_DISPLAY))
\r
191 LOOP(10 * LOOPS_PER_MSEC);
\r
193 writel(readl(RK29_PMU_BASE + PMU_PD_CON) & ~(1 << PD_GPU), RK29_PMU_BASE + PMU_PD_CON);
\r
195 while (readl(RK29_PMU_BASE + PMU_PD_ST) & (1 << PD_GPU))
\r
197 LOOP(10 * LOOPS_PER_MSEC);
\r
199 cru_writel(0, CRU_CLKGATE3_CON);
\r
200 LOOP(LOOPS_PER_USEC);
\r
202 //SPI0 clock source = periph_pll_clk, SPI0 divider=8
\r
203 cru_writel((cru_readl(CRU_CLKSEL6_CON) & ~0x1FF) | (7 << 2), CRU_CLKSEL6_CON);
\r
205 //eMMC divider=0x17, SD/MMC0 clock source=arm_pll_clk
\r
206 cru_writel((cru_readl(CRU_CLKSEL7_CON) & ~(3 | (0x3f << 18))) | (0x17 << 18), CRU_CLKSEL7_CON);
\r
208 //UART1 clock divider=0, UART1 clk =24MHz , UART0 and UART1 clock source=periph_pll_clk
\r
209 cru_writel((cru_readl(CRU_CLKSEL8_CON) & ~(7 | (0x3f << 14) | (3 << 20))) | (2 << 20), CRU_CLKSEL8_CON);
\r
211 // remap bit control = 0, normal mode
\r
212 writel(readl(RK29_GRF_BASE + 0xc0) & ~(1 << 21), RK29_GRF_BASE + 0xc0);
\r
213 // emmc_and_boot_en control=0, normal mode
\r
214 writel(readl(RK29_GRF_BASE + 0xbc) & ~(1 << 9), RK29_GRF_BASE + 0xbc);
\r
217 writel(0, RK29_CPU_AXI_BUS0_PHYS);
\r
218 writel(0, RK29_AXI1_PHYS);
\r
221 // SDMMC_CLKSRC=0, clk_source=clock divider 0
\r
222 writel(0, RK29_EMMC_PHYS + 0x0c);
\r
223 // SDMMC_CTYPE=0, card_width=1 bit mode
\r
224 writel(0, RK29_EMMC_PHYS + 0x18);
\r
225 // SDMMC_BLKSIZ=0x200, Block size=512
\r
226 writel(0x200, RK29_EMMC_PHYS + 0x1c);
\r
229 __cpuc_flush_kern_all();
\r
230 __cpuc_flush_user_all();
\r