blob: e4a6c03580820c8779c3f48ae480e0e991c6f7a5 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2020 MediaTek Inc.
*
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <config.h>
#include <asm-offsets.h>
#include <asm/cacheops.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/asm.h>
#include "mt7628.h"
/* Set temporary stack address range */
#ifndef CONFIG_SYS_INIT_SP_ADDR
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
CONFIG_SYS_INIT_SP_OFFSET)
#endif
#define CACHE_STACK_SIZE 0x4000
#define CACHE_STACK_BASE (CONFIG_SYS_INIT_SP_ADDR - CACHE_STACK_SIZE)
#define DELAY_USEC(us) ((58 * (us)) / 3)
.set noreorder
LEAF(mips_sram_init)
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/* Setup CPU PLL */
li t0, DELAY_USEC(1000000)
li t1, KSEG1ADDR(SYSCTL_BASE + SYSCTL_ROM_STATUS_REG)
li t2, KSEG1ADDR(SYSCTL_BASE + SYSCTL_CLKCFG0_REG)
_check_rom_status:
lw t3, 0(t1)
andi t3, t3, 1
bnez t3, _rom_normal
subu t0, t0, 1
bnez t0, _check_rom_status
nop
lw t3, 0(t2)
ori t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)
xori t3, CPU_PLL_FROM_BBP
b _cpu_pll_done
nop
_rom_normal:
lw t3, 0(t2)
ori t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL | \
DIS_BBP_SLEEP | EN_BBP_CLK)
xori t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)
_cpu_pll_done:
sw t3, 0(t2)
li t2, KSEG1ADDR(RBUSCTL_BASE + RBUSCTL_DYN_CFG0_REG)
lw t3, 0(t2)
ori t3, t3, (CPU_FDIV_M | CPU_FFRAC_M)
xori t3, t3, (CPU_FDIV_M | CPU_FFRAC_M)
ori t3, t3, ((1 << CPU_FDIV_S) | (1 << CPU_FFRAC_S))
sw t3, 0(t2)
/* Clear WST & SPR bits in ErrCtl */
mfc0 t0, CP0_ECC
ins t0, zero, 30, 2
mtc0 t0, CP0_ECC
ehb
/* Simply initialize I-Cache */
li a0, 0
li a1, CONFIG_SYS_ICACHE_SIZE
mtc0 zero, CP0_TAGLO /* Zero to DDataLo */
1: cache INDEX_STORE_TAG_I, 0(a0)
addiu a0, CONFIG_SYS_ICACHE_LINE_SIZE
bne a0, a1, 1b
nop
/* Simply initialize D-Cache */
li a0, 0
li a1, CONFIG_SYS_DCACHE_SIZE
mtc0 zero, CP0_TAGLO, 2
2: cache INDEX_STORE_TAG_D, 0(a0)
addiu a0, CONFIG_SYS_DCACHE_LINE_SIZE
bne a0, a1, 2b
nop
/* Set KSEG0 Cachable */
mfc0 t0, CP0_CONFIG
and t0, t0, MIPS_CONF_IMPL
or t0, t0, CONF_CM_CACHABLE_NONCOHERENT
mtc0 t0, CP0_CONFIG
ehb
/* Lock D-Cache */
PTR_LI a0, CACHE_STACK_BASE /* D-Cache lock base */
li a1, CACHE_STACK_SIZE /* D-Cache lock size */
li a2, 0x1ffff800 /* Mask of DTagLo[PTagLo] */
3:
/* Lock one cacheline */
and t0, a0, a2
ori t0, 0xe0 /* Valid & Dirty & Lock bits */
mtc0 t0, CP0_TAGLO, 2 /* Write to DTagLo */
ehb
cache INDEX_STORE_TAG_D, 0(a0)
addiu a0, CONFIG_SYS_DCACHE_LINE_SIZE
sub a1, CONFIG_SYS_DCACHE_LINE_SIZE
bnez a1, 3b
nop
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
jr ra
nop
END(mips_sram_init)
NESTED(lowlevel_init, 0, ra)
/* Save ra and do real lowlevel initialization */
move s0, ra
PTR_LA t9, mt7628_init
jalr t9
nop
move ra, s0
#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
/* Set malloc base */
li t0, (CONFIG_SYS_INIT_SP_ADDR + 15) & (~15)
PTR_S t0, GD_MALLOC_BASE(k0) # gd->malloc_base offset
#endif
/* Write back data in locked cache to DRAM */
PTR_LI a0, CACHE_STACK_BASE /* D-Cache unlock base */
li a1, CACHE_STACK_SIZE /* D-Cache unlock size */
1:
cache HIT_WRITEBACK_INV_D, 0(a0)
addiu a0, CONFIG_SYS_DCACHE_LINE_SIZE
sub a1, CONFIG_SYS_DCACHE_LINE_SIZE
bnez a1, 1b
nop
/* Set KSEG0 Uncached */
mfc0 t0, CP0_CONFIG
and t0, t0, MIPS_CONF_IMPL
or t0, t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
ehb
jr ra
nop
END(lowlevel_init)