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 := \
|
obj-y := \
|
||||||
entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
|
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 \
|
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_BF53x) += bfin_gpio.o
|
||||||
obj-$(CONFIG_BF561) += bfin_gpio.o
|
obj-$(CONFIG_BF561) += bfin_gpio.o
|
||||||
|
@ -80,6 +80,7 @@
|
|||||||
* GPIO_47 PH15 PF47
|
* GPIO_47 PH15 PF47
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <asm/blackfin.h>
|
#include <asm/blackfin.h>
|
||||||
@ -888,3 +889,20 @@ void gpio_direction_output(unsigned short gpio)
|
|||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(gpio_direction_output);
|
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)
|
void show_regs(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
printk(KERN_NOTICE "\n");
|
printk(KERN_NOTICE "\n");
|
||||||
|
@ -459,66 +459,6 @@ ENTRY(_start_dma_code)
|
|||||||
ENDPROC(_start_dma_code)
|
ENDPROC(_start_dma_code)
|
||||||
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
|
#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
|
#if CONFIG_DEBUG_KERNEL_START
|
||||||
debug_kernel_start_trap:
|
debug_kernel_start_trap:
|
||||||
/* Set up a temp stack in L1 - SDRAM might not be working */
|
/* Set up a temp stack in L1 - SDRAM might not be working */
|
||||||
|
@ -478,85 +478,6 @@ ENTRY(_start_dma_code)
|
|||||||
ENDPROC(_start_dma_code)
|
ENDPROC(_start_dma_code)
|
||||||
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
|
#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
|
.data
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -378,131 +378,6 @@ ENTRY(_start_dma_code)
|
|||||||
RTS;
|
RTS;
|
||||||
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
|
#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
|
.data
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -406,66 +406,6 @@ ENTRY(_start_dma_code)
|
|||||||
ENDPROC(_start_dma_code)
|
ENDPROC(_start_dma_code)
|
||||||
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
|
#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
|
.data
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user