mirror of https://gitee.com/openkylin/linux.git
Blackfin arch: rewrite our reboot code in C
rewrite our reboot code in C rather than assembly to be like other architectures and to allow board maintainers to define custom behavior Signed-off-by: Mike Frysinger <michael.frysinger@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
This commit is contained in:
parent
27d875f2c1
commit
168f1212c0
|
@ -7,7 +7,7 @@ extra-y := init_task.o vmlinux.lds
|
|||
obj-y := \
|
||||
entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
|
||||
sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
|
||||
fixed_code.o cplbinit.o cacheinit.o
|
||||
fixed_code.o cplbinit.o cacheinit.o reboot.o
|
||||
|
||||
obj-$(CONFIG_BF53x) += bfin_gpio.o
|
||||
obj-$(CONFIG_BF561) += bfin_gpio.o
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
* GPIO_47 PH15 PF47
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/blackfin.h>
|
||||
|
@ -888,3 +889,20 @@ void gpio_direction_output(unsigned short gpio)
|
|||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_direction_output);
|
||||
|
||||
/* If we are booting from SPI and our board lacks a strong enough pull up,
|
||||
* the core can reset and execute the bootrom faster than the resistor can
|
||||
* pull the signal logically high. To work around this (common) error in
|
||||
* board design, we explicitly set the pin back to GPIO mode, force /CS
|
||||
* high, and wait for the electrons to do their thing.
|
||||
*
|
||||
* This function only makes sense to be called from reset code, but it
|
||||
* lives here as we need to force all the GPIO states w/out going through
|
||||
* BUG() checks and such.
|
||||
*/
|
||||
void bfin_gpio_reset_spi0_ssel1(void)
|
||||
{
|
||||
port_setup(P_SPI0_SSEL1, GPIO_USAGE);
|
||||
gpio_bankb[gpio_bank(P_SPI0_SSEL1)]->data_set = gpio_bit(P_SPI0_SSEL1);
|
||||
udelay(1);
|
||||
}
|
||||
|
|
|
@ -134,31 +134,6 @@ void cpu_idle(void)
|
|||
}
|
||||
}
|
||||
|
||||
void machine_restart(char *__unused)
|
||||
{
|
||||
#if defined(CONFIG_BFIN_ICACHE)
|
||||
bfin_write_IMEM_CONTROL(0x01);
|
||||
SSYNC();
|
||||
#endif
|
||||
bfin_reset();
|
||||
/* Dont do anything till the reset occurs */
|
||||
while (1) {
|
||||
SSYNC();
|
||||
}
|
||||
}
|
||||
|
||||
void machine_halt(void)
|
||||
{
|
||||
for (;;)
|
||||
asm volatile ("idle");
|
||||
}
|
||||
|
||||
void machine_power_off(void)
|
||||
{
|
||||
for (;;)
|
||||
asm volatile ("idle");
|
||||
}
|
||||
|
||||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
printk(KERN_NOTICE "\n");
|
||||
|
|
|
@ -459,66 +459,6 @@ ENTRY(_start_dma_code)
|
|||
ENDPROC(_start_dma_code)
|
||||
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
|
||||
|
||||
ENTRY(_bfin_reset)
|
||||
/* No more interrupts to be handled*/
|
||||
CLI R6;
|
||||
SSYNC;
|
||||
|
||||
#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
|
||||
p0.h = hi(FIO_INEN);
|
||||
p0.l = lo(FIO_INEN);
|
||||
r0.l = ~(1 << CONFIG_ENET_FLASH_PIN);
|
||||
w[p0] = r0.l;
|
||||
|
||||
p0.h = hi(FIO_DIR);
|
||||
p0.l = lo(FIO_DIR);
|
||||
r0.l = (1 << CONFIG_ENET_FLASH_PIN);
|
||||
w[p0] = r0.l;
|
||||
|
||||
p0.h = hi(FIO_FLAG_C);
|
||||
p0.l = lo(FIO_FLAG_C);
|
||||
r0.l = (1 << CONFIG_ENET_FLASH_PIN);
|
||||
w[p0] = r0.l;
|
||||
#endif
|
||||
|
||||
/* Clear the IMASK register */
|
||||
p0.h = hi(IMASK);
|
||||
p0.l = lo(IMASK);
|
||||
r0 = 0x0;
|
||||
[p0] = r0;
|
||||
|
||||
/* Clear the ILAT register */
|
||||
p0.h = hi(ILAT);
|
||||
p0.l = lo(ILAT);
|
||||
r0 = [p0];
|
||||
[p0] = r0;
|
||||
SSYNC;
|
||||
|
||||
/* make sure SYSCR is set to use BMODE */
|
||||
P0.h = hi(SYSCR);
|
||||
P0.l = lo(SYSCR);
|
||||
R0.l = 0x0;
|
||||
W[P0] = R0.l;
|
||||
SSYNC;
|
||||
|
||||
/* issue a system soft reset */
|
||||
P1.h = hi(SWRST);
|
||||
P1.l = lo(SWRST);
|
||||
R1.l = 0x0007;
|
||||
W[P1] = R1;
|
||||
SSYNC;
|
||||
|
||||
/* clear system soft reset */
|
||||
R0.l = 0x0000;
|
||||
W[P0] = R0;
|
||||
SSYNC;
|
||||
|
||||
/* issue core reset */
|
||||
raise 1;
|
||||
|
||||
RTS;
|
||||
ENDPROC(_bfin_reset)
|
||||
|
||||
#if CONFIG_DEBUG_KERNEL_START
|
||||
debug_kernel_start_trap:
|
||||
/* Set up a temp stack in L1 - SDRAM might not be working */
|
||||
|
|
|
@ -478,85 +478,6 @@ ENTRY(_start_dma_code)
|
|||
ENDPROC(_start_dma_code)
|
||||
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
|
||||
|
||||
ENTRY(_bfin_reset)
|
||||
/* No more interrupts to be handled*/
|
||||
CLI R6;
|
||||
SSYNC;
|
||||
|
||||
#if defined(CONFIG_MTD_M25P80)
|
||||
/*
|
||||
* The following code fix the SPI flash reboot issue,
|
||||
* /CS signal of the chip which is using PF10 return to GPIO mode
|
||||
*/
|
||||
p0.h = hi(PORTF_FER);
|
||||
p0.l = lo(PORTF_FER);
|
||||
r0.l = 0x0000;
|
||||
w[p0] = r0.l;
|
||||
SSYNC;
|
||||
|
||||
/* /CS return to high */
|
||||
p0.h = hi(PORTFIO);
|
||||
p0.l = lo(PORTFIO);
|
||||
r0.l = 0xFFFF;
|
||||
w[p0] = r0.l;
|
||||
SSYNC;
|
||||
|
||||
/* Delay some time, This is necessary */
|
||||
r1.h = 0;
|
||||
r1.l = 0x400;
|
||||
p1 = r1;
|
||||
lsetup (.L_delay_lab1, .L_delay_lab1_end) lc1 = p1;
|
||||
.L_delay_lab1:
|
||||
r0.h = 0;
|
||||
r0.l = 0x8000;
|
||||
p0 = r0;
|
||||
lsetup (.L_delay_lab0, .L_delay_lab0_end) lc0 = p0;
|
||||
.L_delay_lab0:
|
||||
nop;
|
||||
.L_delay_lab0_end:
|
||||
nop;
|
||||
.L_delay_lab1_end:
|
||||
nop;
|
||||
#endif
|
||||
|
||||
/* Clear the IMASK register */
|
||||
p0.h = hi(IMASK);
|
||||
p0.l = lo(IMASK);
|
||||
r0 = 0x0;
|
||||
[p0] = r0;
|
||||
|
||||
/* Clear the ILAT register */
|
||||
p0.h = hi(ILAT);
|
||||
p0.l = lo(ILAT);
|
||||
r0 = [p0];
|
||||
[p0] = r0;
|
||||
SSYNC;
|
||||
|
||||
/* make sure SYSCR is set to use BMODE */
|
||||
P0.h = hi(SYSCR);
|
||||
P0.l = lo(SYSCR);
|
||||
R0.l = 0x0;
|
||||
W[P0] = R0.l;
|
||||
SSYNC;
|
||||
|
||||
/* issue a system soft reset */
|
||||
P1.h = hi(SWRST);
|
||||
P1.l = lo(SWRST);
|
||||
R1.l = 0x0007;
|
||||
W[P1] = R1;
|
||||
SSYNC;
|
||||
|
||||
/* clear system soft reset */
|
||||
R0.l = 0x0000;
|
||||
W[P0] = R0;
|
||||
SSYNC;
|
||||
|
||||
/* issue core reset */
|
||||
raise 1;
|
||||
|
||||
RTS;
|
||||
ENDPROC(_bfin_reset)
|
||||
|
||||
.data
|
||||
|
||||
/*
|
||||
|
|
|
@ -378,131 +378,6 @@ ENTRY(_start_dma_code)
|
|||
RTS;
|
||||
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
|
||||
|
||||
ENTRY(_bfin_reset)
|
||||
/* No more interrupts to be handled*/
|
||||
CLI R6;
|
||||
SSYNC;
|
||||
|
||||
#if 0 /* Need to determine later if this is here necessary for BF54x */
|
||||
#if defined(CONFIG_MTD_M25P80)
|
||||
/*
|
||||
* The following code fix the SPI flash reboot issue,
|
||||
* /CS signal of the chip which is using PF10 return to GPIO mode
|
||||
*/
|
||||
p0.h = hi(PORTF_FER);
|
||||
p0.l = lo(PORTF_FER);
|
||||
r0.l = 0x0000;
|
||||
w[p0] = r0.l;
|
||||
SSYNC;
|
||||
|
||||
/* /CS return to high */
|
||||
p0.h = hi(PORTFIO);
|
||||
p0.l = lo(PORTFIO);
|
||||
r0.l = 0xFFFF;
|
||||
w[p0] = r0.l;
|
||||
SSYNC;
|
||||
|
||||
/* Delay some time, This is necessary */
|
||||
r1.h = 0;
|
||||
r1.l = 0x400;
|
||||
p1 = r1;
|
||||
lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
|
||||
_delay_lab1:
|
||||
r0.h = 0;
|
||||
r0.l = 0x8000;
|
||||
p0 = r0;
|
||||
lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
|
||||
_delay_lab0:
|
||||
nop;
|
||||
_delay_lab0_end:
|
||||
nop;
|
||||
_delay_lab1_end:
|
||||
nop;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Clear the bits 13-15 in SWRST if they werent cleared */
|
||||
p0.h = hi(SWRST);
|
||||
p0.l = lo(SWRST);
|
||||
csync;
|
||||
r0.l = w[p0];
|
||||
|
||||
/* Clear the IMASK register */
|
||||
p0.h = hi(IMASK);
|
||||
p0.l = lo(IMASK);
|
||||
r0 = 0x0;
|
||||
[p0] = r0;
|
||||
|
||||
/* Clear the ILAT register */
|
||||
p0.h = hi(ILAT);
|
||||
p0.l = lo(ILAT);
|
||||
r0 = [p0];
|
||||
[p0] = r0;
|
||||
SSYNC;
|
||||
|
||||
/* Disable the WDOG TIMER */
|
||||
p0.h = hi(WDOG_CTL);
|
||||
p0.l = lo(WDOG_CTL);
|
||||
r0.l = 0xAD6;
|
||||
w[p0] = r0.l;
|
||||
SSYNC;
|
||||
|
||||
/* Clear the sticky bit incase it is already set */
|
||||
p0.h = hi(WDOG_CTL);
|
||||
p0.l = lo(WDOG_CTL);
|
||||
r0.l = 0x8AD6;
|
||||
w[p0] = r0.l;
|
||||
SSYNC;
|
||||
|
||||
/* Program the count value */
|
||||
R0.l = 0x100;
|
||||
R0.h = 0x0;
|
||||
P0.h = hi(WDOG_CNT);
|
||||
P0.l = lo(WDOG_CNT);
|
||||
[P0] = R0;
|
||||
SSYNC;
|
||||
|
||||
/* Program WDOG_STAT if necessary */
|
||||
P0.h = hi(WDOG_CTL);
|
||||
P0.l = lo(WDOG_CTL);
|
||||
R0 = W[P0](Z);
|
||||
CC = BITTST(R0,1);
|
||||
if !CC JUMP .LWRITESTAT;
|
||||
CC = BITTST(R0,2);
|
||||
if !CC JUMP .LWRITESTAT;
|
||||
JUMP .LSKIP_WRITE;
|
||||
|
||||
.LWRITESTAT:
|
||||
/* When watch dog timer is enabled,
|
||||
* a write to STAT will load the contents of CNT to STAT
|
||||
*/
|
||||
R0 = 0x0000(z);
|
||||
P0.h = hi(WDOG_STAT);
|
||||
P0.l = lo(WDOG_STAT)
|
||||
[P0] = R0;
|
||||
SSYNC;
|
||||
|
||||
.LSKIP_WRITE:
|
||||
/* Enable the reset event */
|
||||
P0.h = hi(WDOG_CTL);
|
||||
P0.l = lo(WDOG_CTL);
|
||||
R0 = W[P0](Z);
|
||||
BITCLR(R0,1);
|
||||
BITCLR(R0,2);
|
||||
W[P0] = R0.L;
|
||||
SSYNC;
|
||||
NOP;
|
||||
|
||||
/* Enable the wdog counter */
|
||||
R0 = W[P0](Z);
|
||||
BITCLR(R0,4);
|
||||
W[P0] = R0.L;
|
||||
SSYNC;
|
||||
|
||||
IDLE;
|
||||
|
||||
RTS;
|
||||
|
||||
.data
|
||||
|
||||
/*
|
||||
|
|
|
@ -406,66 +406,6 @@ ENTRY(_start_dma_code)
|
|||
ENDPROC(_start_dma_code)
|
||||
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
|
||||
|
||||
ENTRY(_bfin_reset)
|
||||
/* No more interrupts to be handled*/
|
||||
CLI R6;
|
||||
SSYNC;
|
||||
|
||||
#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
|
||||
p0.h = hi(FIO_INEN);
|
||||
p0.l = lo(FIO_INEN);
|
||||
r0.l = ~(PF1 | PF0);
|
||||
w[p0] = r0.l;
|
||||
|
||||
p0.h = hi(FIO_DIR);
|
||||
p0.l = lo(FIO_DIR);
|
||||
r0.l = (PF1 | PF0);
|
||||
w[p0] = r0.l;
|
||||
|
||||
p0.h = hi(FIO_FLAG_C);
|
||||
p0.l = lo(FIO_FLAG_C);
|
||||
r0.l = (PF1 | PF0);
|
||||
w[p0] = r0.l;
|
||||
#endif
|
||||
|
||||
/* Clear the IMASK register */
|
||||
p0.h = hi(IMASK);
|
||||
p0.l = lo(IMASK);
|
||||
r0 = 0x0;
|
||||
[p0] = r0;
|
||||
|
||||
/* Clear the ILAT register */
|
||||
p0.h = hi(ILAT);
|
||||
p0.l = lo(ILAT);
|
||||
r0 = [p0];
|
||||
[p0] = r0;
|
||||
SSYNC;
|
||||
|
||||
/* make sure SYSCR is set to use BMODE */
|
||||
P0.h = hi(SYSCR);
|
||||
P0.l = lo(SYSCR);
|
||||
R0.l = 0x20; /* on BF561, disable core b */
|
||||
W[P0] = R0.l;
|
||||
SSYNC;
|
||||
|
||||
/* issue a system soft reset */
|
||||
P1.h = hi(SWRST);
|
||||
P1.l = lo(SWRST);
|
||||
R1.l = 0x0007;
|
||||
W[P1] = R1;
|
||||
SSYNC;
|
||||
|
||||
/* clear system soft reset */
|
||||
R0.l = 0x0000;
|
||||
W[P0] = R0;
|
||||
SSYNC;
|
||||
|
||||
/* issue core reset */
|
||||
raise 1;
|
||||
|
||||
RTS;
|
||||
ENDPROC(_bfin_reset)
|
||||
|
||||
.data
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue