u-boot/arch/mips/mach-mtmips/mt7621/spl/start.S

227 lines
4.6 KiB
ArmAsm
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <asm-offsets.h>
#include <config.h>
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/cacheops.h>
#include <asm/addrspace.h>
#include <asm/mipsmtregs.h>
#include <asm/cm.h>
#include "../mt7621.h"
#include "dram.h"
#ifndef CFG_SYS_INIT_SP_ADDR
#define CFG_SYS_INIT_SP_ADDR (CFG_SYS_SDRAM_BASE + \
CFG_SYS_INIT_SP_OFFSET)
#endif
#define SP_ADDR_TEMP 0xbe10dff0
.macro init_wr sel
MTC0 zero, CP0_WATCHLO,\sel
mtc0 t1, CP0_WATCHHI,\sel
.endm
.macro setup_stack_gd
li t0, -16
PTR_LI t1, CFG_SYS_INIT_SP_ADDR
and sp, t1, t0 # force 16 byte alignment
PTR_SUBU \
sp, sp, GD_SIZE # reserve space for gd
and sp, sp, t0 # force 16 byte alignment
move k0, sp # save gd pointer
#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
!CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
PTR_SUBU \
sp, sp, t2 # reserve space for early malloc
and sp, sp, t0 # force 16 byte alignment
#endif
move fp, sp
/* Clear gd */
move t0, k0
1:
PTR_S zero, 0(t0)
PTR_ADDIU t0, PTRSIZE
blt t0, t1, 1b
nop
#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
!CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
#endif
.endm
.set noreorder
ENTRY(_start)
b 1f
mtc0 zero, CP0_COUNT
/* Stage header required by BootROM */
.org 0x8
.word 0 # ep, filled by mkimage
.word 0 # stage_size, filled by mkimage
.word 0 # has_stage2
.word 0 # next_ep
.word 0 # next_size
.word 0 # next_offset
1:
/* Init CP0 Status */
mfc0 t0, CP0_STATUS
and t0, ST0_IMPL
or t0, ST0_BEV | ST0_ERL
mtc0 t0, CP0_STATUS
ehb
/* Clear Watch Status bits and disable watch exceptions */
li t1, 0x7 # Clear I, R and W conditions
init_wr 0
init_wr 1
init_wr 2
init_wr 3
/* Clear WP, IV and SW interrupts */
mtc0 zero, CP0_CAUSE
/* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
mtc0 zero, CP0_COMPARE
/* VPE1 goes to wait code directly */
mfc0 t0, CP0_TCBIND
andi t0, TCBIND_CURVPE
bnez t0, launch_vpe_entry
nop
/* Core1 goes to specific launch entry */
PTR_LI t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
lw t1, GCR_Cx_ID(t0)
bnez t1, launch_core_entry
nop
/* MT7530 reset */
li t0, KSEG1ADDR(SYSCTL_BASE)
lw t1, SYSCTL_RSTCTL_REG(t0)
ori t1, MCM_RST
sw t1, SYSCTL_RSTCTL_REG(t0)
/* Disable DMA route for PSE SRAM set by BootROM */
PTR_LI t0, KSEG1ADDR(DMA_CFG_ARB_BASE)
sw zero, DMA_ROUTE_REG(t0)
/* Set CPU clock to 500MHz (Required if boot from NAND) */
li t0, KSEG1ADDR(SYSCTL_BASE)
lw t1, SYSCTL_CLKCFG0_REG(t0)
ins t1, zero, 30, 2 # CPU_CLK_SEL
sw t1, SYSCTL_CLKCFG0_REG(t0)
/* Set CPU clock divider to 1/1 */
li t0, KSEG1ADDR(RBUS_BASE)
li t1, 0x101
sw t1, RBUS_DYN_CFG0_REG(t0)
/* (Re-)initialize the SRAM */
bal mips_sram_init
nop
/* Set up temporary stack */
li sp, SP_ADDR_TEMP
/* Setup full CPS */
bal mips_cm_map
nop
bal mt7621_cps_init
nop
/* Prepare for CPU/DDR initialization binary blob */
bal prepare_stage_bin
nop
/* Call CPU/DDR initialization binary blob */
li t9, STAGE_LOAD_ADDR
jalr t9
nop
/* Switch CPU PLL source */
li t0, KSEG1ADDR(SYSCTL_BASE)
lw t1, SYSCTL_CLKCFG0_REG(t0)
li t2, 1
ins t1, t2, CPU_CLK_SEL_S, 2
sw t1, SYSCTL_CLKCFG0_REG(t0)
/*
* Currently SPL is running on locked L2 cache (on KSEG0).
* To reset the entire cache, we have to writeback SPL to DRAM first.
* Cache flush won't work here. Use memcpy instead.
*/
la a0, __text_start
move a1, a0
la a2, __image_copy_end
sub a2, a2, a1
li a3, 5
ins a0, a3, 29, 3 # convert to KSEG1
bal memcpy
nop
/* Disable caches */
bal mips_cache_disable
nop
/* Reset caches */
bal mips_cache_reset
nop
/* Disable SRAM */
li t0, KSEG1ADDR(FE_BASE)
li t1, FE_PSE_RESET
sw t1, FE_RST_GLO_REG(t0)
/* Clear the .bss section */
la a0, __bss_start
la a1, __bss_end
1: sw zero, 0(a0)
addiu a0, 4
ble a0, a1, 1b
nop
/* Set up initial stack and global data */
setup_stack_gd
#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
/* Set malloc base */
li t0, (CFG_SYS_INIT_SP_ADDR + 15) & (~15)
PTR_S t0, GD_MALLOC_BASE(k0) # gd->malloc_base offset
#endif
#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_SPL_SERIAL)
/* Earliest point to set up debug uart */
bal debug_uart_init
nop
#endif
/* Setup timer */
bal set_timer_freq_simple
nop
/* Bootup secondary CPUs */
bal secondary_cpu_init
nop
move a0, zero # a0 <-- boot_flags = 0
bal board_init_f
move ra, zero
END(_start)