MIPS: mach-ar231x: add lowlevel init pbl macros
Signed-off-by: Oleksij Rempel <linux@rempel-privat.de> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
24b0d2effd
commit
ed61198836
|
@ -0,0 +1,177 @@
|
|||
#ifndef __ASM_MACH_AR2312_PBL_MACROS_H
|
||||
#define __ASM_MACH_AR2312_PBL_MACROS_H
|
||||
|
||||
#include <asm/regdef.h>
|
||||
#include <mach/ar2312_regs.h>
|
||||
|
||||
.macro pbl_ar2312_pll
|
||||
.set push
|
||||
.set noreorder
|
||||
|
||||
mfc0 k0, CP0_STATUS
|
||||
li k1, ST0_NMI
|
||||
and k1, k1, k0
|
||||
bnez k1, pllskip
|
||||
nop
|
||||
|
||||
/* Clear any prior AHB errors by reading both addr registers */
|
||||
li t0, KSEG1 | AR2312_PROCADDR
|
||||
lw zero, 0(t0)
|
||||
li t0, KSEG1 | AR2312_DMAADDR
|
||||
lw zero, 0(t0)
|
||||
|
||||
pbl_sleep t2, 4000
|
||||
|
||||
li t0, KSEG1 | AR2312_CLOCKCTL2
|
||||
lw t1, (t0)
|
||||
bgez t1, pllskip /* upper bit guaranteed non-0 at reset */
|
||||
nop
|
||||
|
||||
/* For Viper 0xbc003064 register has to be programmed with 0x91000 to
|
||||
* get 180Mhz Processor clock
|
||||
* Set /2 clocking and turn OFF AR2312_CLOCKCTL2_STATUS_PLL_BYPASS.
|
||||
* Processor RESETs at this point; the CLOCKCTL registers retain
|
||||
* their new values across the reset.
|
||||
*/
|
||||
|
||||
li t0, KSEG1 | AR2312_CLOCKCTL1
|
||||
li t1, AR2313_CLOCKCTL1_SELECTION
|
||||
sw t1, (t0)
|
||||
|
||||
li t0, KSEG1 | AR2312_CLOCKCTL2
|
||||
li t1, AR2312_CLOCKCTL2_WANT_RESET
|
||||
sw t1, (t0) /* reset CPU */
|
||||
1: b 1b /* NOTREACHED */
|
||||
nop
|
||||
pllskip:
|
||||
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro pbl_ar2312_rst_uart0
|
||||
.set push
|
||||
.set noreorder
|
||||
|
||||
li a0, KSEG1 | AR2312_RESET
|
||||
lw t0, 0(a0)
|
||||
and t0, ~AR2312_RESET_APB
|
||||
or t0, AR2312_RESET_UART0
|
||||
sw t0, 0(a0)
|
||||
lw zero, 0(a0) /* flush */
|
||||
|
||||
and t0, ~AR2312_RESET_UART0
|
||||
sw t0, 0(a0)
|
||||
lw zero, 0(a0) /* flush */
|
||||
|
||||
1: /* Use internal clocking */
|
||||
li a0, KSEG1 | AR2312_CLOCKCTL0
|
||||
lw t0, 0(a0)
|
||||
and t0, ~AR2312_CLOCKCTL_UART0
|
||||
sw t0, 0(a0)
|
||||
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro pbl_ar2312_x16_sdram
|
||||
.set push
|
||||
.set noreorder
|
||||
|
||||
li a0, KSEG1 | AR2312_MEM_CFG0
|
||||
li a1, KSEG1 | AR2312_MEM_CFG1
|
||||
li a2, KSEG1 | AR2312_MEM_REF
|
||||
|
||||
li a3, MEM_CFG1_E0 | (MEM_CFG1_AC_128 << MEM_CFG1_AC0_S)
|
||||
|
||||
/* Set the I and M bits to issue an SDRAM nop */
|
||||
ori t0, a3, MEM_CFG1_M | MEM_CFG1_I
|
||||
sw t0, 0(a1) /* AR2312_MEM_CFG1 */
|
||||
|
||||
pbl_sleep t2, 50
|
||||
|
||||
/* Reset the M bit to issue an SDRAM PRE-ALL */
|
||||
ori t0, a3, MEM_CFG1_I
|
||||
sw t0, 0(a1) /* AR2312_MEM_CFG1 */
|
||||
sync
|
||||
|
||||
/* Generate a refresh every 16 clocks (spec says 10) */
|
||||
li t0, 16 /* very fast refresh for now */
|
||||
sw t0, 0(a2) /* AR2312_MEM_REF */
|
||||
|
||||
pbl_sleep t2, 5
|
||||
|
||||
/* Set command write mode, and read SDRAM */
|
||||
ori t0, a3, MEM_CFG1_M
|
||||
sw t0, 0(a1) /* AR2312_MEM_CFG1 */
|
||||
sync
|
||||
|
||||
li t0, KSEG1 | AR2312_SDRAM0
|
||||
or t0, 0x23000 /* 16bit burst */
|
||||
lw zero, 0(t0)
|
||||
|
||||
/* Program configuration register */
|
||||
li t0, MEM_CFG0_C | MEM_CFG0_C2 | MEM_CFG0_R1 | \
|
||||
MEM_CFG0_B0 | MEM_CFG0_X
|
||||
sw t0, 0(a0) /* AR2312_MEM_CFG0 */
|
||||
sync
|
||||
|
||||
li t0, AR2312_SDRAM_MEMORY_REFRESH_VALUE
|
||||
sw t0, 0(a2) /* AR2312_MEM_REF */
|
||||
sync
|
||||
|
||||
/* Clear I and M and set cfg1 to the normal operational value */
|
||||
sw a3, 0(a1) /* AR2312_MEM_CFG1 */
|
||||
sync
|
||||
|
||||
pbl_sleep t2, 10
|
||||
|
||||
/* Now we need to set size of RAM to prevent some wired errors.
|
||||
* Since I do not have access to any board with two SDRAM chips, or
|
||||
* any was registered in the wild - we will support only one. */
|
||||
/* So, lets find the beef */
|
||||
li a0, KSEG1 | AR2312_MEM_CFG1
|
||||
li a1, KSEG1 | AR2312_SDRAM0
|
||||
li a2, 0xdeadbeef
|
||||
li t0, 0x200000
|
||||
li t1, MEM_CFG1_AC_2
|
||||
|
||||
/* We will write some magic word to the beginning of RAM,
|
||||
* and see if it appears somewhere else. If yes, we made
|
||||
* a travel around the world. */
|
||||
|
||||
/* But first of all save original state of the first RAM word. */
|
||||
lw a3, 0(a1)
|
||||
sw a2, 0(a1)
|
||||
|
||||
find_the_beef:
|
||||
or t2, a1, t0
|
||||
lw t3, 0(t2)
|
||||
beq a2, t3, 1f
|
||||
nop
|
||||
sll t0, 1
|
||||
add t1, 1
|
||||
/* we should have some limit here. */
|
||||
blt t1, MEM_CFG1_AC_64, find_the_beef
|
||||
nop
|
||||
b make_beefsteak
|
||||
nop
|
||||
|
||||
/* additional paranoid check */
|
||||
1:
|
||||
sw zero, 0(a1)
|
||||
lw t3, 0(t2)
|
||||
bne zero, t3, find_the_beef
|
||||
nop
|
||||
|
||||
make_beefsteak:
|
||||
/* create new config for AR2312_MEM_CFG1 and overwrite it */
|
||||
sll t1, MEM_CFG1_AC0_S
|
||||
or t2, t1, MEM_CFG1_E0
|
||||
sw t2, 0(a0) /* AR2312_MEM_CFG1 */
|
||||
|
||||
/* restore original state of the first RAM word */
|
||||
sw a3, 0(a1)
|
||||
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_MACH_AR2312_PBL_MACROS_H */
|
Loading…
Reference in New Issue