diff options
Diffstat (limited to 'roms/u-boot/arch/nds32/cpu/n1213')
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/Makefile | 15 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag101/Makefile | 21 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag101/cpu.c | 68 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag101/lowlevel_init.S | 332 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag101/timer.c | 191 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag101/watchdog.S | 33 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag102/Makefile | 21 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag102/cpu.c | 67 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag102/lowlevel_init.S | 307 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag102/timer.c | 191 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/ag102/watchdog.S | 33 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/start.S | 529 | ||||
| -rw-r--r-- | roms/u-boot/arch/nds32/cpu/n1213/u-boot.lds | 56 | 
13 files changed, 1864 insertions, 0 deletions
diff --git a/roms/u-boot/arch/nds32/cpu/n1213/Makefile b/roms/u-boot/arch/nds32/cpu/n1213/Makefile new file mode 100644 index 00000000..206d304d --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/Makefile @@ -0,0 +1,15 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2011 Andes Technology Corporation +# Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> +# Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +# necessary to create built-in.o +obj- := __dummy__.o + +extra-y	= start.o diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag101/Makefile b/roms/u-boot/arch/nds32/cpu/n1213/ag101/Makefile new file mode 100644 index 00000000..c21ce028 --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag101/Makefile @@ -0,0 +1,21 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar <prafulla@marvell.com> +# +# Copyright (C) 2011 Andes Technology Corporation +# Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> +# Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	:= cpu.o timer.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +obj-y	+= lowlevel_init.o +endif + +ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG +obj-y	+= watchdog.o +endif diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag101/cpu.c b/roms/u-boot/arch/nds32/cpu/n1213/ag101/cpu.c new file mode 100644 index 00000000..31d72712 --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag101/cpu.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * Copyright (C) 2011 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* CPU specific code */ +#include <common.h> +#include <command.h> +#include <watchdog.h> +#include <asm/cache.h> + +#include <faraday/ftwdt010_wdt.h> + +/* + * cleanup_before_linux() is called just before we call linux + * it prepares the processor for linux + * + * we disable interrupt and caches. + */ +int cleanup_before_linux(void) +{ +	disable_interrupts(); + +#ifdef CONFIG_MMU +	/* turn off I/D-cache */ +	icache_disable(); +	dcache_disable(); + +	/* flush I/D-cache */ +	invalidate_icac(); +	invalidate_dcac(); +#endif + +	return 0; +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	disable_interrupts(); + +	/* +	 * reset to the base addr of andesboot. +	 * currently no ROM loader at addr 0. +	 * do not use reset_cpu(0); +	 */ +#ifdef CONFIG_FTWDT010_WATCHDOG +	/* +	 * workaround: if we use CONFIG_HW_WATCHDOG with ftwdt010, will lead +	 * automatic hardware reset when booting Linux. +	 * Please do not use CONFIG_HW_WATCHDOG and WATCHDOG_RESET() here. +	 */ +	ftwdt010_wdt_reset(); +	while (1) +		; +#endif /* CONFIG_FTWDT010_WATCHDOG */ + +	/*NOTREACHED*/ +} diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag101/lowlevel_init.S b/roms/u-boot/arch/nds32/cpu/n1213/ag101/lowlevel_init.S new file mode 100644 index 00000000..d6484b9c --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag101/lowlevel_init.S @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2011 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +.text + +#include <common.h> +#include <config.h> + +#include <asm/macro.h> +#include <generated/asm-offsets.h> + +/* + * parameters for the SDRAM controller + */ +#define SDMC_TP1_A		(CONFIG_FTSDMC021_BASE + FTSDMC021_TP1) +#define SDMC_TP2_A		(CONFIG_FTSDMC021_BASE + FTSDMC021_TP2) +#define SDMC_CR1_A		(CONFIG_FTSDMC021_BASE + FTSDMC021_CR1) +#define SDMC_CR2_A		(CONFIG_FTSDMC021_BASE + FTSDMC021_CR2) +#define SDMC_B0_BSR_A		(CONFIG_FTSDMC021_BASE + FTSDMC021_BANK0_BSR) +#define SDMC_B1_BSR_A		(CONFIG_FTSDMC021_BASE + FTSDMC021_BANK1_BSR) + +#define SDMC_TP1_D		CONFIG_SYS_FTSDMC021_TP1 +#define SDMC_TP2_D		CONFIG_SYS_FTSDMC021_TP2 +#define SDMC_CR1_D		CONFIG_SYS_FTSDMC021_CR1 +#define SDMC_CR2_D		CONFIG_SYS_FTSDMC021_CR2 + +#define SDMC_B0_BSR_D		CONFIG_SYS_FTSDMC021_BANK0_BSR +#define SDMC_B1_BSR_D		CONFIG_SYS_FTSDMC021_BANK1_BSR + + +/* + * for Orca and Emerald + */ +#define BOARD_ID_REG		0x104 +#define BOARD_ID_FAMILY_MASK 	0xfff000 +#define BOARD_ID_FAMILY_V5   	0x556000 +#define BOARD_ID_FAMILY_K7   	0x74b000 + +/* + * parameters for the static memory controller + */ +#define SMC_BANK0_CR_A		(CONFIG_FTSMC020_BASE + FTSMC020_BANK0_CR) +#define SMC_BANK0_TPR_A		(CONFIG_FTSMC020_BASE + FTSMC020_BANK0_TPR) + +#define SMC_BANK0_CR_D		FTSMC020_BANK0_LOWLV_CONFIG +#define SMC_BANK0_TPR_D		FTSMC020_BANK0_LOWLV_TIMING + +/* + * parameters for the ahbc controller + */ +#define AHBC_CR_A		(CONFIG_FTAHBC020S_BASE + FTAHBC020S_CR) +#define AHBC_BSR6_A	(CONFIG_FTAHBC020S_BASE + FTAHBC020S_SLAVE_BSR_6) + +/* + * for Orca and Emerald + */ +#define AHBC_BSR4_A	(CONFIG_FTAHBC020S_BASE + FTAHBC020S_SLAVE_BSR_4) +#define AHBC_BSR6_D		CONFIG_SYS_FTAHBC020S_SLAVE_BSR_6 + +/* + * parameters for the pmu controoler + */ +#define PMU_PDLLCR0_A		(CONFIG_FTPMU010_BASE + FTPMU010_PDLLCR0) + +/* + * numeric 7 segment display + */ +.macro	led, num +	write32	CONFIG_DEBUG_LED, \num +.endm + +/* + * Waiting for SDRAM to set up + */ +.macro	wait_sdram +	li	$r0, CONFIG_FTSDMC021_BASE +1: +	lwi	$r1, [$r0+FTSDMC021_CR2] +	bnez	$r1, 1b +.endm + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +.globl	lowlevel_init +lowlevel_init: +	move	$r10, $lp + +	led	0x0 +	jal	mem_init + +	led	0x10 +	jal	remap + +#if (defined(NDS32_EXT_FPU_DP) || defined(NDS32_EXT_FPU_SP)) +	led	0x1f +	jal	enable_fpu +#endif + +	led	0x20 +	ret	$r10 + +mem_init: +	move	$r11, $lp + +	/* +	 * mem_init: +	 *	There are 2 bank connected to FTSMC020 on AG101 +	 *	BANK0: FLASH/ROM (SW5, J16), BANK1: OnBoard SDRAM. +	 *	we need to set onboard SDRAM before remap and relocation. +	 */ +	led	0x01 + +  /* +   * for Orca and Emerald +   * disable write protection and reset bank size +   */ +	li	$r0, SMC_BANK0_CR_A +	lwi $r1, [$r0+#0x00] +	ori $r1, $r1, 0x8f0 +	xori $r1, $r1, 0x8f0 +  /* +   * check board +   */ +	li      $r3, CONFIG_FTPMU010_BASE + BOARD_ID_REG +  lwi     $r3, [$r3] +  li      $r4, BOARD_ID_FAMILY_MASK +  and     $r3, $r3, $r4 +  li      $r4, BOARD_ID_FAMILY_K7 +  xor     $r4, $r3, $r4 +  beqz    $r4, use_flash_16bit_boot +  /* +   * 32-bit mode +   */ +use_flash_32bit_boot: +	ori     $r1, $r1, 0x50 +  li      $r2, 0x00151151 +  j       sdram_b0_cr +  /* +   * 16-bit mode +   */ +use_flash_16bit_boot: +  ori     $r1, $r1, 0x60 +  li      $r2, 0x00153153 +  /* +   * SRAM bank0 config +   */ +sdram_b0_cr: +  swi     $r1, [$r0+#0x00] +  swi     $r2, [$r0+#0x04] + +	/* +	 * config AHB Controller +	 */ +	led	0x02 + +	/* +	 * config PMU controller +	 */ +	/* ftpmu010_dlldis_disable, must do it in lowleve_init */ +	led	0x03 +	setbf32	PMU_PDLLCR0_A, FTPMU010_PDLLCR0_DLLDIS		! 0x00010000 + +	/* +	 * config SDRAM controller +	 */ +	led	0x04 +	write32	SDMC_TP1_A, SDMC_TP1_D				! 0x00011312 +	led	0x05 +	write32	SDMC_TP2_A, SDMC_TP2_D				! 0x00480180 +	led	0x06 +	write32	SDMC_CR1_A, SDMC_CR1_D				! 0x00002326 + +	led	0x07 +	write32	SDMC_CR2_A, FTSDMC021_CR2_IPREC			! 0x00000010 +	wait_sdram + +	led	0x08 +	write32	SDMC_CR2_A, FTSDMC021_CR2_ISMR			! 0x00000004 +	wait_sdram + +	led	0x09 +	write32	SDMC_CR2_A, FTSDMC021_CR2_IREF			! 0x00000008 +	wait_sdram + +	led	0x0a +	move	$lp, $r11 +	ret + +remap: +	move	$r11, $lp +#ifdef __NDS32_N1213_43U1H__	/* NDS32 V0 ISA - AG101 Only */ +	bal	2f +relo_base: +	move	$r0, $lp +#else +relo_base: +	mfusr	$r0, $pc +#endif /* __NDS32_N1213_43U1H__ */ + +	/* +	 * Remapping +	 */ +	led	0x1a +	write32	SDMC_B0_BSR_A, SDMC_B0_BSR_D		! 0x00001100 +	write32	SDMC_B1_BSR_A, SDMC_B1_BSR_D		! 0x00001140 + +	/* clear empty BSR registers */ +	led	0x1b +	li	$r4, CONFIG_FTSDMC021_BASE +	li	$r5, 0x0 +	swi	$r5, [$r4 + FTSDMC021_BANK2_BSR] +	swi	$r5, [$r4 + FTSDMC021_BANK3_BSR] + +#ifdef CONFIG_MEM_REMAP +	/* +	 * Copy ROM code to SDRAM base for memory remap layout. +	 * This is not the real relocation, the real relocation is the function +	 * relocate_code() is start.S which supports the systems is memory +	 * remapped or not. +	 */ +	/* +	 * Doing memory remap is essential for preparing some non-OS or RTOS +	 * applications. +	 * +	 * This is also a must on ADP-AG101 board. +	 * The reason is because the ROM/FLASH circuit on PCB board. +	 * AG101-A0 board has 2 jumpers MA17 and SW5 to configure which +	 * ROM/FLASH is used to boot. +	 * +	 * When SW5 = "0101", MA17 = LO, the ROM is connected to BANK0, +	 * and the FLASH is connected to BANK1. +	 * When SW5 = "1010", MA17 = HI, the ROM is disabled (still at BANK0), +	 * and the FLASH is connected to BANK0. +	 * It will occur problem when doing flash probing if the flash is at +	 * BANK0 (0x00000000) while memory remapping was skipped. +	 * +	 * Other board like ADP-AG101P may not enable this since there is only +	 * a FLASH connected to bank0. +	 */ +	led	0x11 +   /* +    * for Orca and Emerald +    * read sdram base address automatically +    */ +	li	$r5, AHBC_BSR6_A +	lwi $r8, [$r5] +	li	$r4, 0xfff00000 +	and $r4, $r4, $r8 + + +	li	$r5, 0x0 +	la	$r1, relo_base				/* get $pc or $lp */ +	sub	$r2, $r0, $r1 +	sethi	$r6, hi20(_end) +	ori	$r6, $r6, lo12(_end) +	add	$r6, $r6, $r2 +1: +	lwi.p	$r7, [$r5], #4 +	swi.p	$r7, [$r4], #4 +	blt	$r5, $r6, 1b + +	/* set remap bit */ +	/* +	 * MEM remap bit is operational +	 * - use it to map writeable memory at 0x00000000, in place of flash +	 * - before remap: flash/rom 0x00000000, sdram: 0x10000000-0x4fffffff +	 * - after  remap: flash/rom 0x80000000, sdram: 0x00000000 +	 */ +	led	0x1c +	write32 SDMC_B0_BSR_A, 0x00001000 +	write32 SDMC_B1_BSR_A, 0x00001040 +	setbf15	AHBC_CR_A, FTAHBC020S_CR_REMAP		! 0x1 + +  /* +   * for Orca and Emerald +   * extend sdram size from 256MB to 2GB +   */ +	li	$r5, AHBC_BSR6_A +	lwi $r6, [$r5] +	li  $r4, 0xfff0ffff +	and $r6 ,$r4 , $r6 +	li	$r4, 0x000b0000 +	or  $r6, $r4,	$r6 +	swi	$r6, [$r5] + +  /* +   * for Orca and Emerald +   * extend rom base from 256MB to 2GB +   */ +	li	$r4, AHBC_BSR4_A +	lwi $r5, [$r4] +	li	$r6, 0xffffff +	and $r5, $r5, $r6 +	li  $r6, 0x80000000 +	or  $r5, $r5, $r6 +	swi $r5,	[$r4] +#endif /* #ifdef CONFIG_MEM_REMAP */ +	move	$lp, $r11 +2: +	ret + +	/* +	 * enable_fpu: +	 *  Some of Andes CPU version support FPU coprocessor, if so, +	 *  and toolchain support FPU instruction set, we should enable it. +	 */ +#if (defined(NDS32_EXT_FPU_DP) || defined(NDS32_EXT_FPU_SP)) +enable_fpu: +	mfsr    $r0, $CPU_VER     /* enable FPU if it exists */ +	srli    $r0, $r0, 3 +	andi    $r0, $r0, 1 +	beqz    $r0, 1f           /* skip if no COP */ +	mfsr    $r0, $FUCOP_EXIST +	srli    $r0, $r0, 31 +	beqz    $r0, 1f           /* skip if no FPU */ +	mfsr    $r0, $FUCOP_CTL +	ori     $r0, $r0, 1 +	mtsr    $r0, $FUCOP_CTL +1: +	ret +#endif + +.globl show_led +show_led: +    li      $r8, (CONFIG_DEBUG_LED) +    swi     $r7, [$r8] +    ret +#endif /* #ifndef CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag101/timer.c b/roms/u-boot/arch/nds32/cpu/n1213/ag101/timer.c new file mode 100644 index 00000000..758b3541 --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag101/timer.c @@ -0,0 +1,191 @@ +/* + * (C) Copyright 2009 Faraday Technology + * Po-Yu Chuang <ratbert@faraday-tech.com> + * + * Copyright (C) 2011 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <faraday/fttmr010.h> + +static ulong timestamp; +static ulong lastdec; + +int timer_init(void) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; +	unsigned int cr; + +	debug("%s()\n", __func__); + +	/* disable timers */ +	writel(0, &tmr->cr); + +#ifdef CONFIG_FTTMR010_EXT_CLK +	/* use 32768Hz oscillator for RTC, WDT, TIMER */ +	ftpmu010_32768osc_enable(); +#endif + +	/* setup timer */ +	writel(TIMER_LOAD_VAL, &tmr->timer3_load); +	writel(TIMER_LOAD_VAL, &tmr->timer3_counter); +	writel(0, &tmr->timer3_match1); +	writel(0, &tmr->timer3_match2); + +	/* we don't want timer to issue interrupts */ +	writel(FTTMR010_TM3_MATCH1 | +	       FTTMR010_TM3_MATCH2 | +	       FTTMR010_TM3_OVERFLOW, +	       &tmr->interrupt_mask); + +	cr = readl(&tmr->cr); +#ifdef CONFIG_FTTMR010_EXT_CLK +	cr |= FTTMR010_TM3_CLOCK;	/* use external clock */ +#endif +	cr |= FTTMR010_TM3_ENABLE; +	writel(cr, &tmr->cr); + +	/* init the timestamp and lastdec value */ +	reset_timer_masked(); + +	return 0; +} + +/* + * timer without interrupts + */ + +/* + * reset time + */ +void reset_timer_masked(void) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; + +	/* capure current decrementer value time */ +#ifdef CONFIG_FTTMR010_EXT_CLK +	lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ); +#else +	lastdec = readl(&tmr->timer3_counter) / +			(CONFIG_SYS_CLK_FREQ / 2 / CONFIG_SYS_HZ); +#endif +	timestamp = 0;		/* start "advancing" time stamp from 0 */ + +	debug("%s(): lastdec = %lx\n", __func__, lastdec); +} + +void reset_timer(void) +{ +	debug("%s()\n", __func__); +	reset_timer_masked(); +} + +/* + * return timer ticks + */ +ulong get_timer_masked(void) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; + +	/* current tick value */ +#ifdef CONFIG_FTTMR010_EXT_CLK +	ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ); +#else +	ulong now = readl(&tmr->timer3_counter) / +			(CONFIG_SYS_CLK_FREQ / 2 / CONFIG_SYS_HZ); +#endif + +	debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec); + +	if (lastdec >= now) { +		/* +		 * normal mode (non roll) +		 * move stamp fordward with absoulte diff ticks +		 */ +		timestamp += lastdec - now; +	} else { +		/* +		 * we have overflow of the count down timer +		 * +		 * nts = ts + ld + (TLV - now) +		 * ts=old stamp, ld=time that passed before passing through -1 +		 * (TLV-now) amount of time after passing though -1 +		 * nts = new "advancing time stamp"...it could also roll and +		 * cause problems. +		 */ +		timestamp += lastdec + TIMER_LOAD_VAL - now; +	} + +	lastdec = now; + +	debug("%s() returns %lx\n", __func__, timestamp); + +	return timestamp; +} + +/* + * return difference between timer ticks and base + */ +ulong get_timer(ulong base) +{ +	debug("%s(%lx)\n", __func__, base); +	return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ +	debug("%s(%lx)\n", __func__, t); +	timestamp = t; +} + +/* delay x useconds AND preserve advance timestamp value */ +void __udelay(unsigned long usec) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; + +#ifdef CONFIG_FTTMR010_EXT_CLK +	long tmo = usec * (TIMER_CLOCK / 1000) / 1000; +#else +	long tmo = usec * ((CONFIG_SYS_CLK_FREQ / 2) / 1000) / 1000; +#endif +	unsigned long now, last = readl(&tmr->timer3_counter); + +	debug("%s(%lu)\n", __func__, usec); +	while (tmo > 0) { +		now = readl(&tmr->timer3_counter); +		if (now > last) /* count down timer overflow */ +			tmo -= TIMER_LOAD_VAL + last - now; +		else +			tmo -= last - now; +		last = now; +	} +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ +	debug("%s()\n", __func__); +	return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ +	debug("%s()\n", __func__); +#ifdef CONFIG_FTTMR010_EXT_CLK +	return CONFIG_SYS_HZ; +#else +	return CONFIG_SYS_CLK_FREQ; +#endif +} diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag101/watchdog.S b/roms/u-boot/arch/nds32/cpu/n1213/ag101/watchdog.S new file mode 100644 index 00000000..8442241d --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag101/watchdog.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2011 Andes Technology Corporation + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm/arch-ag101/ag101.h> +#include <linux/linkage.h> + +.text + +#ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG +ENTRY(turnoff_watchdog) + +#define WD_CR		0xC +#define WD_ENABLE	0x1 + +	! Turn off the watchdog, according to Faraday FTWDT010 spec +	li 	$p0, (CONFIG_FTWDT010_BASE+WD_CR)	! Get the addr of WD CR +	lwi	$p1, [$p0]				! Get the config of WD +	andi	$p1, $p1, 0x1f				! Wipe out useless bits +	li	$r0, ~WD_ENABLE +	and	$p1, $p1, $r0				! Set WD disable +	sw	$p1, [$p0]				! Write back to WD CR + +	! Disable Interrupts by clear GIE in $PSW reg +	setgie.d + +	ret + +ENDPROC(turnoff_watchdog) +#endif diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag102/Makefile b/roms/u-boot/arch/nds32/cpu/n1213/ag102/Makefile new file mode 100644 index 00000000..c21ce028 --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag102/Makefile @@ -0,0 +1,21 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar <prafulla@marvell.com> +# +# Copyright (C) 2011 Andes Technology Corporation +# Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> +# Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	:= cpu.o timer.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +obj-y	+= lowlevel_init.o +endif + +ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG +obj-y	+= watchdog.o +endif diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag102/cpu.c b/roms/u-boot/arch/nds32/cpu/n1213/ag102/cpu.c new file mode 100644 index 00000000..2ee45d21 --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag102/cpu.c @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * Copyright (C) 2011 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* CPU specific code */ +#include <common.h> +#include <command.h> +#include <watchdog.h> +#include <asm/cache.h> + +#include <faraday/ftwdt010_wdt.h> + +/* + * cleanup_before_linux() is called just before we call linux + * it prepares the processor for linux + * + * we disable interrupt and caches. + */ +int cleanup_before_linux(void) +{ +	disable_interrupts(); + +#ifdef CONFIG_MMU +	/* turn off I/D-cache */ +	icache_disable(); +	dcache_disable(); + +	/* flush I/D-cache */ +	invalidate_icac(); +	invalidate_dcac(); +#endif + +	return 0; +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	disable_interrupts(); + +	/* +	 * reset to the base addr of andesboot. +	 * currently no ROM loader at addr 0. +	 * do not use reset_cpu(0); +	 */ +#ifdef CONFIG_FTWDT010_WATCHDOG +	/* +	 * workaround: if we use CONFIG_HW_WATCHDOG with ftwdt010, will lead +	 * automatic hardware reset when booting Linux. +	 * Please do not use CONFIG_HW_WATCHDOG and WATCHDOG_RESET() here. +	 */ +	ftwdt010_wdt_reset(); +#endif /* CONFIG_FTWDT010_WATCHDOG */ +	hang(); + +	/*NOTREACHED*/ +} diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag102/lowlevel_init.S b/roms/u-boot/arch/nds32/cpu/n1213/ag102/lowlevel_init.S new file mode 100644 index 00000000..238410dd --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag102/lowlevel_init.S @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2011 Andes Technology Corporation + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +.text + +#include <common.h> +#include <config.h> + +#include <asm/macro.h> +#include <generated/asm-offsets.h> + +/* + * parameters for Synopsys DWC DDR2/DDR1 Memory Controller + */ +#define DDR2C_BASE_A		(CONFIG_DWCDDR21MCTL_BASE) +#define DDR2C_CCR_A		(DDR2C_BASE_A + DWCDDR21MCTL_CCR) +#define DDR2C_DCR_A		(DDR2C_BASE_A + DWCDDR21MCTL_DCR) +#define DDR2C_IOCR_A		(DDR2C_BASE_A + DWCDDR21MCTL_IOCR) +#define DDR2C_CSR_A		(DDR2C_BASE_A + DWCDDR21MCTL_CSR) +#define DDR2C_DRR_A		(DDR2C_BASE_A + DWCDDR21MCTL_DRR) +#define DDR2C_DLLCR0_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR0) +#define DDR2C_DLLCR1_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR1) +#define DDR2C_DLLCR2_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR2) +#define DDR2C_DLLCR3_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR3) +#define DDR2C_DLLCR4_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR4) +#define DDR2C_DLLCR5_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR5) +#define DDR2C_DLLCR6_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR6) +#define DDR2C_DLLCR7_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR7) +#define DDR2C_DLLCR8_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR8) +#define DDR2C_DLLCR9_A		(DDR2C_BASE_A + DWCDDR21MCTL_DLLCR9) +#define DDR2C_RSLR0_A		(DDR2C_BASE_A + DWCDDR21MCTL_RSLR0) +#define DDR2C_RDGR0_A		(DDR2C_BASE_A + DWCDDR21MCTL_RDGR0) +#define DDR2C_DTAR_A		(DDR2C_BASE_A + DWCDDR21MCTL_DTAR) +#define DDR2C_MR_A		(DDR2C_BASE_A + DWCDDR21MCTL_MR) + +#define DDR2C_CCR_D		CONFIG_SYS_DWCDDR21MCTL_CCR +#define DDR2C_CCR_D2		CONFIG_SYS_DWCDDR21MCTL_CCR2 +#define DDR2C_DCR_D		CONFIG_SYS_DWCDDR21MCTL_DCR +#define DDR2C_IOCR_D		CONFIG_SYS_DWCDDR21MCTL_IOCR +#define DDR2C_CSR_D		CONFIG_SYS_DWCDDR21MCTL_CSR +#define DDR2C_DRR_D		CONFIG_SYS_DWCDDR21MCTL_DRR +#define DDR2C_RSLR0_D		CONFIG_SYS_DWCDDR21MCTL_RSLR0 +#define DDR2C_RDGR0_D		CONFIG_SYS_DWCDDR21MCTL_RDGR0 +#define DDR2C_DTAR_D		CONFIG_SYS_DWCDDR21MCTL_DTAR +#define DDR2C_MR_D		CONFIG_SYS_DWCDDR21MCTL_MR + +#define DDR2C_DLLCR0_D	CONFIG_SYS_DWCDDR21MCTL_DLLCR0	/* 0-9 are same */ + +/* + * parameters for the ahbc controller + */ +#define AHBC_CR_A		(CONFIG_FTAHBC020S_BASE + FTAHBC020S_CR) +#define AHBC_BSR6_A	(CONFIG_FTAHBC020S_BASE + FTAHBC020S_SLAVE_BSR_6) + +#define AHBC_BSR6_D		CONFIG_SYS_FTAHBC020S_SLAVE_BSR_6 + +/* + * parameters for the ANDES PCU controller + */ +#define PCU_PCS4_A		(CONFIG_ANDES_PCU_BASE + ANDES_PCU_PCS4) +#define PCU_PCS4_D		CONFIG_SYS_ANDES_CPU_PCS4 + +/* + * numeric 7 segment display + */ +.macro	led, num +	write32	CONFIG_DEBUG_LED, \num +.endm + +/* + * Waiting for SDRAM to set up + */ +/* +.macro	wait_sdram +	li	$r0, DDR2C_CSR_A +1: +	lwi	$r1, [$r0+FTSDMC021_CR2] +	bnez	$r1, 1b +.endm +*/ + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +.globl	lowlevel_init +lowlevel_init: +	move	$r10, $lp + +	/* U200 */ +!	led	0x00 +!	jal	scale_to_500mhz + +	led	0x10 +	jal	mem_init + +	led	0x20 +	jal	remap + +#if (defined(NDS32_EXT_FPU_DP) || defined(NDS32_EXT_FPU_SP)) +	led	0x2f +	jal	enable_fpu +#endif + +	led	0x30 +	ret	$r10 + +scale_to_500mhz: +	move	$r11, $lp + +	/* +	 * scale to 500Mhz +	 */ +	led	0x01 +	write32	PCU_PCS4_A, 0x1102000f			! save data to PCS4 + +	move	$lp, $r11 +	ret + +mem_init: +	move	$r11, $lp + +	/* +	 * config AHB Controller +	 */ +	led	0x12 +	write32	AHBC_BSR6_A, AHBC_BSR6_D + +	/* +	 * config Synopsys DWC DDR2/DDR1 Memory Controller +	 */ +ddr2c_init: +set_dcr: +	led	0x14 +	write32	DDR2C_DCR_A, DDR2C_DCR_D			! 0x000020d4 + +auto_sizing: +	/* +	 * ebios: $r10->$r7, $r11->$r8, $r12->$r9, $r13->$r12, $r14->$r13 +	 */ +set_iocr: +	led	0x19 +	write32 DDR2C_IOCR_A, DDR2C_IOCR_D +set_drr: +	led	0x16 +	write32	DDR2C_DRR_A, DDR2C_DRR_D			! 0x00034812 +set_dllcr: +	led	0x18 +	write32 DDR2C_DLLCR0_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR1_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR2_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR3_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR4_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR5_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR6_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR7_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR8_A, DDR2C_DLLCR0_D +	write32 DDR2C_DLLCR9_A, DDR2C_DLLCR0_D +set_rslr0: +	write32 DDR2C_RSLR0_A, DDR2C_RSLR0_D			! 0x00000040 +set_rdgr0: +	write32 DDR2C_RDGR0_A, DDR2C_RDGR0_D			! 0x000055cf +set_dtar: +	led	0x15 +	write32	DDR2C_DTAR_A, DDR2C_DTAR_D			! 0x00100000 +set_mode: +	led	0x17 +	write32	DDR2C_MR_A, DDR2C_MR_D				! 0x00000852 +set_ccr: +	write32 DDR2C_CCR_A, DDR2C_CCR_D + +#ifdef TRIGGER_INIT: +trigger_init: +	write32 DDR2C_CCR_A, DDR2C_CCR_D			! 0x80020000 + +	/* Wait for ddr init state to be set */ +	msync	ALL +	isb + +	/* Wait until the config initialization is finish */ +1: +	la	$r4, DDR2C_CSR_A +	lwi	$r5, [$r4] +	srli	$r5, $r5, 23 +	bnez	$r5, 1b +#endif + +data_training: +!	write32	DDR2C_CCR_A, DDR2C_CCR_D2			! 0x40020004 + +	/* Wait for ddr init state to be set */ +	msync	ALL +	isb + +	/* wait until the ddr data trainning is complete */ +1: +	la	$r4, DDR2C_CSR_A +	lwi	$r5, [$r4] +	srli	$r6, $r5, 23 +	bnez	$r6, 1b + +	lwi	$r1, [$r4] +	srli	$r6, $r5, 20 +	li	$r5, 0x00ffffff +	swi	$r1, [$r4] +	bnez	$r6, ddr2c_init + +	led	0x1a +	move	$lp, $r11 +	ret + +remap: +	move	$r11, $lp +#ifdef __NDS32_N1213_43U1H__	/* NDS32 V0 ISA - AG101 Only */ +	bal	2f +relo_base: +	move	$r0, $lp +#else +relo_base: +	mfusr	$r0, $pc +#endif /* __NDS32_N1213_43U1H__ */ + +	/* +	 * Remapping +	 */ +#ifdef CONFIG_MEM_REMAP +	/* +	 * Copy ROM code to SDRAM base for memory remap layout. +	 * This is not the real relocation, the real relocation is the function +	 * relocate_code() is start.S which supports the systems is memory +	 * remapped or not. +	 */ +	/* +	 * Doing memory remap is essential for preparing some non-OS or RTOS +	 * applications. +	 * +	 * This is also a must on ADP-AG101 board. +	 * The reason is because the ROM/FLASH circuit on PCB board. +	 * AG101-A0 board has 2 jumpers MA17 and SW5 to configure which +	 * ROM/FLASH is used to boot. +	 * +	 * When SW5 = "0101", MA17 = LO, the ROM is connected to BANK0, +	 * and the FLASH is connected to BANK1. +	 * When SW5 = "1010", MA17 = HI, the ROM is disabled (still at BANK0), +	 * and the FLASH is connected to BANK0. +	 * It will occur problem when doing flash probing if the flash is at +	 * BANK0 (0x00000000) while memory remapping was skipped. +	 * +	 * Other board like ADP-AG101P may not enable this since there is only +	 * a FLASH connected to bank0. +	 */ +	led	0x21 +	li	$r4, PHYS_SDRAM_0_AT_INIT		/* 0x10000000 */ +	li	$r5, 0x0 +	la	$r1, relo_base				/* get $pc or $lp */ +	sub	$r2, $r0, $r1 +	sethi	$r6, hi20(_end) +	ori	$r6, $r6, lo12(_end) +	add	$r6, $r6, $r2 +1: +	lwi.p	$r7, [$r5], #4 +	swi.p	$r7, [$r4], #4 +	blt	$r5, $r6, 1b + +	/* set remap bit */ +	/* +	 * MEM remap bit is operational +	 * - use it to map writeable memory at 0x00000000, in place of flash +	 * - before remap: flash/rom 0x00000000, sdram: 0x10000000-0x4fffffff +	 * - after  remap: flash/rom 0x80000000, sdram: 0x00000000 +	 */ +	led	0x2c +	setbf15	AHBC_CR_A, FTAHBC020S_CR_REMAP		! 0x1 + +#endif /* #ifdef CONFIG_MEM_REMAP */ +	move	$lp, $r11 +2: +	ret + +	/* +	 * enable_fpu: +	 *  Some of Andes CPU version support FPU coprocessor, if so, +	 *  and toolchain support FPU instruction set, we should enable it. +	 */ +#if (defined(NDS32_EXT_FPU_DP) || defined(NDS32_EXT_FPU_SP)) +enable_fpu: +	mfsr    $r0, $CPU_VER     /* enable FPU if it exists */ +	srli    $r0, $r0, 3 +	andi    $r0, $r0, 1 +	beqz    $r0, 1f           /* skip if no COP */ +	mfsr    $r0, $FUCOP_EXIST +	srli    $r0, $r0, 31 +	beqz    $r0, 1f           /* skip if no FPU */ +	mfsr    $r0, $FUCOP_CTL +	ori     $r0, $r0, 1 +	mtsr    $r0, $FUCOP_CTL +1: +	ret +#endif + +.globl show_led +show_led: +    li      $r8, (CONFIG_DEBUG_LED) +    swi     $r7, [$r8] +    ret +#endif /* #ifndef CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag102/timer.c b/roms/u-boot/arch/nds32/cpu/n1213/ag102/timer.c new file mode 100644 index 00000000..758b3541 --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag102/timer.c @@ -0,0 +1,191 @@ +/* + * (C) Copyright 2009 Faraday Technology + * Po-Yu Chuang <ratbert@faraday-tech.com> + * + * Copyright (C) 2011 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <faraday/fttmr010.h> + +static ulong timestamp; +static ulong lastdec; + +int timer_init(void) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; +	unsigned int cr; + +	debug("%s()\n", __func__); + +	/* disable timers */ +	writel(0, &tmr->cr); + +#ifdef CONFIG_FTTMR010_EXT_CLK +	/* use 32768Hz oscillator for RTC, WDT, TIMER */ +	ftpmu010_32768osc_enable(); +#endif + +	/* setup timer */ +	writel(TIMER_LOAD_VAL, &tmr->timer3_load); +	writel(TIMER_LOAD_VAL, &tmr->timer3_counter); +	writel(0, &tmr->timer3_match1); +	writel(0, &tmr->timer3_match2); + +	/* we don't want timer to issue interrupts */ +	writel(FTTMR010_TM3_MATCH1 | +	       FTTMR010_TM3_MATCH2 | +	       FTTMR010_TM3_OVERFLOW, +	       &tmr->interrupt_mask); + +	cr = readl(&tmr->cr); +#ifdef CONFIG_FTTMR010_EXT_CLK +	cr |= FTTMR010_TM3_CLOCK;	/* use external clock */ +#endif +	cr |= FTTMR010_TM3_ENABLE; +	writel(cr, &tmr->cr); + +	/* init the timestamp and lastdec value */ +	reset_timer_masked(); + +	return 0; +} + +/* + * timer without interrupts + */ + +/* + * reset time + */ +void reset_timer_masked(void) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; + +	/* capure current decrementer value time */ +#ifdef CONFIG_FTTMR010_EXT_CLK +	lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ); +#else +	lastdec = readl(&tmr->timer3_counter) / +			(CONFIG_SYS_CLK_FREQ / 2 / CONFIG_SYS_HZ); +#endif +	timestamp = 0;		/* start "advancing" time stamp from 0 */ + +	debug("%s(): lastdec = %lx\n", __func__, lastdec); +} + +void reset_timer(void) +{ +	debug("%s()\n", __func__); +	reset_timer_masked(); +} + +/* + * return timer ticks + */ +ulong get_timer_masked(void) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; + +	/* current tick value */ +#ifdef CONFIG_FTTMR010_EXT_CLK +	ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ); +#else +	ulong now = readl(&tmr->timer3_counter) / +			(CONFIG_SYS_CLK_FREQ / 2 / CONFIG_SYS_HZ); +#endif + +	debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec); + +	if (lastdec >= now) { +		/* +		 * normal mode (non roll) +		 * move stamp fordward with absoulte diff ticks +		 */ +		timestamp += lastdec - now; +	} else { +		/* +		 * we have overflow of the count down timer +		 * +		 * nts = ts + ld + (TLV - now) +		 * ts=old stamp, ld=time that passed before passing through -1 +		 * (TLV-now) amount of time after passing though -1 +		 * nts = new "advancing time stamp"...it could also roll and +		 * cause problems. +		 */ +		timestamp += lastdec + TIMER_LOAD_VAL - now; +	} + +	lastdec = now; + +	debug("%s() returns %lx\n", __func__, timestamp); + +	return timestamp; +} + +/* + * return difference between timer ticks and base + */ +ulong get_timer(ulong base) +{ +	debug("%s(%lx)\n", __func__, base); +	return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ +	debug("%s(%lx)\n", __func__, t); +	timestamp = t; +} + +/* delay x useconds AND preserve advance timestamp value */ +void __udelay(unsigned long usec) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; + +#ifdef CONFIG_FTTMR010_EXT_CLK +	long tmo = usec * (TIMER_CLOCK / 1000) / 1000; +#else +	long tmo = usec * ((CONFIG_SYS_CLK_FREQ / 2) / 1000) / 1000; +#endif +	unsigned long now, last = readl(&tmr->timer3_counter); + +	debug("%s(%lu)\n", __func__, usec); +	while (tmo > 0) { +		now = readl(&tmr->timer3_counter); +		if (now > last) /* count down timer overflow */ +			tmo -= TIMER_LOAD_VAL + last - now; +		else +			tmo -= last - now; +		last = now; +	} +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ +	debug("%s()\n", __func__); +	return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ +	debug("%s()\n", __func__); +#ifdef CONFIG_FTTMR010_EXT_CLK +	return CONFIG_SYS_HZ; +#else +	return CONFIG_SYS_CLK_FREQ; +#endif +} diff --git a/roms/u-boot/arch/nds32/cpu/n1213/ag102/watchdog.S b/roms/u-boot/arch/nds32/cpu/n1213/ag102/watchdog.S new file mode 100644 index 00000000..8f450af1 --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/ag102/watchdog.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2011 Andes Technology Corporation + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm/arch-ag102/ag102.h> +#include <linux/linkage.h> + +.text + +#ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG +ENTRY(turnoff_watchdog) + +#define WD_CR		0xC +#define WD_ENABLE	0x1 + +	! Turn off the watchdog, according to Faraday FTWDT010 spec +	li 	$p0, (CONFIG_FTWDT010_BASE+WD_CR)	! Get the addr of WD CR +	lwi	$p1, [$p0]				! Get the config of WD +	andi	$p1, $p1, 0x1f				! Wipe out useless bits +	li	$r0, ~WD_ENABLE +	and	$p1, $p1, $r0				! Set WD disable +	sw	$p1, [$p0]				! Write back to WD CR + +	! Disable Interrupts by clear GIE in $PSW reg +	setgie.d + +	ret + +ENDPROC(turnoff_watchdog) +#endif diff --git a/roms/u-boot/arch/nds32/cpu/n1213/start.S b/roms/u-boot/arch/nds32/cpu/n1213/start.S new file mode 100644 index 00000000..34db79dd --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/start.S @@ -0,0 +1,529 @@ +/* + *	Andesboot - Startup Code for Whitiger core + * + *	Copyright (C) 2006	Andes Technology Corporation + *	Copyright (C) 2006	Shawn Lin <nobuhiro@andestech.com> + *	Copyright (C) 2011	Macpaul Lin <macpaul@andestech.com> + *				Greentime Hu <greentime@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <common.h> +#include <asm/macro.h> +#include <version.h> + +/* + * Jump vector table for EVIC mode + */ +#define ENA_DCAC		2UL +#define DIS_DCAC		~ENA_DCAC +#define ICAC_MEM_KBF_ISET	(0x07)	 	! I Cache sets per way +#define ICAC_MEM_KBF_IWAY	(0x07<<3)	! I cache ways +#define ICAC_MEM_KBF_ISZ	(0x07<<6)	! I cache line size +#define DCAC_MEM_KBF_DSET	(0x07)		! D Cache sets per way +#define DCAC_MEM_KBF_DWAY	(0x07<<3)	! D cache ways +#define DCAC_MEM_KBF_DSZ	(0x07<<6)	! D cache line size + +#define PSW			$ir0 +#define EIT_INTR_PSW		$ir1		! interruption $PSW +#define EIT_PREV_IPSW		$ir2		! previous $IPSW +#define EIT_IVB			$ir3		! intr vector base address +#define EIT_EVA			$ir4		! MMU related Exception VA reg +#define EIT_PREV_EVA		$ir5		! previous $eva +#define EIT_ITYPE		$ir6		! interruption type +#define EIT_PREV_ITYPE		$ir7		! prev intr type +#define EIT_MACH_ERR		$ir8		! machine error log +#define EIT_INTR_PC		$ir9		! Interruption PC +#define EIT_PREV_IPC		$ir10		! previous $IPC +#define EIT_OVL_INTR_PC		$ir11		! overflow interruption PC +#define EIT_PREV_P0		$ir12		! prev $P0 +#define EIT_PREV_P1		$ir13		! prev $p1 +#define CR_ICAC_MEM		$cr1		! I-cache/memory config reg +#define CR_DCAC_MEM		$cr2		! D-cache/memory config reg +#define MR_CAC_CTL		$mr8 + +.globl _start + +_start:	j	reset +	j	tlb_fill +	j	tlb_not_present +	j	tlb_misc +	j	tlb_vlpt_miss +	j	machine_error +	j	debug +	j	general_exception +	j	syscall +	j	internal_interrupt		! H0I +	j	internal_interrupt		! H1I +	j	internal_interrupt		! H2I +	j	internal_interrupt		! H3I +	j	internal_interrupt		! H4I +	j	internal_interrupt		! H5I +	j	software_interrupt		! S0I + +	.balign 16 + +/* + * Andesboot Startup Code (reset vector) + * + *	1.	bootstrap + *		1.1 reset - start of u-boot + *		1.2 to superuser mode - as is when reset + *		1.4 Do lowlevel_init + *			- (this will jump out to lowlevel_init.S in SoC) + *			- (lowlevel_init) + *		1.3 Turn off watchdog timer + *			- (this will jump out to watchdog.S in SoC) + *			- (turnoff_watchdog) + *	2.	Do critical init when reboot (not from mem) + *	3.	Relocate andesboot to ram + *	4.	Setup stack + *	5.	Jump to second stage (board_init_r) + */ + +/* Note: TEXT_BASE is defined by the (board-dependent) linker script */ +.globl _TEXT_BASE +_TEXT_BASE: +	.word	CONFIG_SYS_TEXT_BASE + +/* + * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. + */ +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: +	.word 0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: +	.word 0x0badc0de +#endif + +/* IRQ stack memory (calculated at run-time) + 8 bytes */ +.globl IRQ_STACK_START_IN +IRQ_STACK_START_IN: +	.word 0x0badc0de + +/* + * The bootstrap code of nds32 core + */ + +reset: +set_ivb: +	li	$r0, 0x0 + +	/* turn on BTB */ +	mtsr	$r0, $misc_ctl +	/* set IVIC, vector size: 4 bytes, base: 0x0 */ +	mtsr	$r0, $ivb + +load_lli: +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +	jal	load_lowlevel_init +	jral	$p0 +#endif + +/* + * Set the N1213 (Whitiger) core to superuser mode + * According to spec, it is already when reset + */ +turnoff_wtdog: +#ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG +	jal	load_turnoff_watchdog +	jral	$p0 +#endif + +/* + * Do CPU critical regs init only at reboot, + * not when booting from ram + */ +#ifdef CONFIG_INIT_CRITICAL +	bal	cpu_init_crit		! Do CPU critical regs init +#endif + +/* + * Set stackpointer in internal RAM to call board_init_f + * $sp must be 8-byte alignment for ABI compliance. + */ +call_board_init_f: +	li	$sp, CONFIG_SYS_INIT_SP_ADDR +	li	$r0, 0x00000000 + +#ifdef __PIC__ +#ifdef __NDS32_N1213_43U1H__ +/* __NDS32_N1213_43U1H__ implies NDS32 V0 ISA */ +	la	$r15, board_init_f	! store function address into $r15 +#endif +#endif +	j	board_init_f		! jump to board_init_f() in lib/board.c + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + */ +.globl	relocate_code +relocate_code: +	move	$r4, $r0		/* save addr_sp */ +	move	$r5, $r1		/* save addr of gd */ +	move	$r6, $r2		/* save addr of destination */ + +/* Set up the stack */ +stack_setup: +	move	$sp, $r4 + +	la	$r0, _start + +	beq	$r0, $r6, clear_bss	/* skip relocation */ + +	move	$r1, $r6		/* r1 <- scratch for copy_loop */ +	la	$r3, __bss_start +	sub	$r3, $r3, $r0		/* r3 <- __bss_start_ofs */ +	add	$r2, $r0, $r3		/* r2 <- source end address */ + +copy_loop: +	lwi.p	$r7, [$r0], #4 +	swi.p	$r7, [$r1], #4 +	blt	$r0, $r2, copy_loop + +/* + * fix relocations related issues + */ +fix_relocations: +	l.w	$r0, _TEXT_BASE		/* r0 <- Text base */ +	sub	$r9, $r6, $r0		/* r9 <- relocation offset */ + +fix_got: +/* + * Now we want to update GOT. + * + * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object + * generated by GNU ld. Skip these reserved entries from relocation. + */ +	la	$r2, __got_start	/* r2 <- rel __got_start in FLASH */ +	add	$r2, $r2, $r9		/* r2 <- rel __got_start in RAM */ +	la	$r3, __got_end		/* r3 <- rel __got_end in FLASH */ +	add	$r3, $r3, $r9		/* r3 <- rel __got_end in RAM */ +	addi	$r2, $r2, #8		/* skipping first two entries */ +fix_got_loop: +	lwi	$r0, [$r2]		/* r0 <- location in FLASH to fix up */ +	add	$r0, $r0, $r9		/* r0 <- location fix up to RAM */ +	swi.p	$r0, [$r2], #4		/* r0 <- store fix into .got in RAM */ +	blt	$r2, $r3, fix_got_loop + +clear_bss: +	la	$r0, __bss_start	/* r0 <- rel __bss_start in FLASH */ +	add	$r0, $r0, $r9		/* r0 <- rel __bss_start in FLASH */ +	la	$r1, __bss_end		/* r1 <- rel __bss_end in RAM */ +	add	$r1, $r1, $r9		/* r0 <- rel __bss_end in RAM */ +	li	$r2, 0x00000000		/* clear */ + +clbss_l: +	sw	$r2, [$r0]		/* clear loop... */ +	addi	$r0, $r0, #4 +	bne	$r0, $r1, clbss_l + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ +call_board_init_r: +	la	$r0, board_init_r +	move	$lp, $r0		/* offset of board_init_r() */ +	add	$lp, $lp, $r9		/* real address of board_init_r() */ +	/* setup parameters for board_init_r */ +	move	$r0, $r5		/* gd_t */ +	move	$r1, $r6		/* dest_addr */ + +#ifdef __PIC__ +#ifdef __NDS32_N1213_43U1H__		/* NDS32 V0 ISA	*/ +	move	$r15, $lp		/* store function address into $r15 */ +#endif +#endif + +	/* jump to it ... */ +	jr	$lp			/* jump to board_init_r() */ + +/* + * Initialize CPU critical registers + * + *	1.	Setup control registers + *		1.1 Mask all IRQs + *		1.2 Flush cache and TLB + *		1.3 Disable MMU and cache + *	2.	Setup memory timing + */ + +cpu_init_crit: + +	move	$r0, $lp		/* push	ra */ + +	/* Disable Interrupts by clear GIE in $PSW reg */ +	setgie.d + +	/* Flush caches and TLB */ +	/* Invalidate caches */ +	bal	invalidate_icac +	bal	invalidate_dcac + +	/* Flush TLB */ +	mfsr	$p0, $MMU_CFG +	andi	$p0, $p0, 0x3			! MMPS +	li	$p1, 0x2			! TLB MMU +	bne	$p0, $p1, 1f +	tlbop	flushall			! Flush TLB + +1: +	! Disable MMU, Dcache +	! Whitiger is MMU disabled when reset +	! Disable the D$ +	mfsr	$p0, MR_CAC_CTL			! Get the $CACHE_CTL reg +	li	$p1, DIS_DCAC +	and	$p0, $p0, $p1			! Set DC_EN bit +	mtsr	$p0, MR_CAC_CTL			! write back the $CACHE_CTL reg +	isb + +	move	$lp, $r0 +2: +	ret + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +load_lowlevel_init: +	la  $r6, lowlevel_init +	la  $r7, load_lli + 4 +	sub $p0, $r6, $r7 +	add $p0, $p0, $lp +ret +#endif + +#ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG +load_turnoff_watchdog: +	la  $r6, turnoff_watchdog +	la  $r7, turnoff_wtdog + 4 +	sub $p0, $r6, $r7 +	add $p0, $p0, $lp +ret +#endif + +/* + * Invalidate I$ + */ +invalidate_icac: +	! read $cr1(I CAC/MEM cfg. reg.) configuration +	mfsr	$t0, CR_ICAC_MEM + +	! Get the ISZ field +	andi	$p0, $t0, ICAC_MEM_KBF_ISZ + +	! if $p0=0, then no I CAC existed +	beqz	$p0, end_flush_icache + +	! get $p0 the index of I$ block +	srli	$p0, $p0, 6 + +	! $t1= bit width of I cache line size(ISZ) +	addi	$t1, $p0, 2 + +	li	$t4, 1 +	sll	$t5, $t4, $t1			! get $t5 cache line size +	andi	$p1, $t0, ICAC_MEM_KBF_ISET	! get the ISET field +	addi	$t2, $p1, 6			! $t2= bit width of ISET +	andi	$p1, $t0, ICAC_MEM_KBF_IWAY	! get bitfield of Iway +	srli	$p1, $p1, 3 +	addi	$p1, $p1, 1			! then $p1 is I way number +	add	$t3, $t2, $t1			! SHIFT +	sll	$p1, $p1, $t3			! GET the total cache size +ICAC_LOOP: +	sub	$p1, $p1, $t5 +	cctl	$p1, L1I_IX_INVAL +	bnez	$p1, ICAC_LOOP +end_flush_icache: +	ret + +/* + * Invalidate D$ + */ +invalidate_dcac: +	! read $cr2(D CAC/MEM cfg. reg.) configuration +	mfsr	$t0, CR_DCAC_MEM + +	! Get the DSZ field +	andi	$p0, $t0, DCAC_MEM_KBF_DSZ + +	! if $p0=0, then no D CAC existed +	beqz	$p0, end_flush_dcache + +	! get $p0 the index of D$ block +	srli	$p0, $p0, 6 + +	! $t1= bit width of D cache line size(DSZ) +	addi	$t1, $p0, 2 + +	li	$t4, 1 +	sll	$t5, $t4, $t1			! get $t5 cache line size +	andi	$p1, $t0, DCAC_MEM_KBF_DSET	! get the DSET field +	addi	$t2, $p1, 6			! $t2= bit width of DSET +	andi	$p1, $t0, DCAC_MEM_KBF_DWAY	! get bitfield of D way +	srli	$p1, $p1, 3 +	addi	$p1, $p1, 1			! then $p1 is D way number +	add	$t3, $t2, $t1			! SHIFT +	sll	$p1, $p1, $t3			! GET the total cache size +DCAC_LOOP: +	sub	$p1, $p1, $t5 +	cctl	$p1, L1D_IX_INVAL +	bnez	$p1, DCAC_LOOP +end_flush_dcache: +	ret + +/* + * Interrupt handling + */ + +/* + * exception handlers + */ +	.align	5 + +.macro	SAVE_ALL +	! FIXME: Other way to get PC? +	! FIXME: Update according to the newest spec!! +1: +	la	 $r28, 1 +	push $r28 +	mfsr $r28, PSW			! $PSW +	push $r28 +	mfsr $r28, EIT_EVA		! $ir1 $EVA +	push $r28 +	mfsr $r28, EIT_ITYPE		! $ir2 $ITYPE +	push $r28 +	mfsr $r28, EIT_MACH_ERR		! $ir3 Mach Error +	push $r28 +	mfsr $r28, EIT_INTR_PSW		! $ir5 $IPSW +	push $r28 +	mfsr $r28, EIT_PREV_IPSW	! $ir6 prev $IPSW +	push $r28 +	mfsr $r28, EIT_PREV_EVA		! $ir7 prev $EVA +	push $r28 +	mfsr $r28, EIT_PREV_ITYPE	! $ir8 prev $ITYPE +	push $r28 +	mfsr $r28, EIT_INTR_PC		! $ir9 Interruption PC +	push $r28 +	mfsr $r28, EIT_PREV_IPC		! $ir10 prev INTR_PC +	push $r28 +	mfsr $r28, EIT_OVL_INTR_PC	! $ir11 Overflowed INTR_PC +	push $r28 +	mfusr $r28, $d1.lo +	push $r28 +	mfusr $r28, $d1.hi +	push $r28 +	mfusr $r28, $d0.lo +	push $r28 +	mfusr $r28, $d0.hi +	push $r28 +	pushm $r0, $r30		! store $sp-$r31, ra-$r30, $gp-$r29, $r28-$fp +	addi	$sp, $sp, -4	! make room for implicit pt_regs parameters +.endm + +	.align	5 +tlb_fill: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 1				! Determine interruption type +	bal 	do_interruption + +	.align	5 +tlb_not_present: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 2				! Determine interruption type +	bal 	do_interruption + +	.align	5 +tlb_misc: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 3				! Determine interruption type +	bal 	do_interruption + +	.align	5 +tlb_vlpt_miss: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 4				! Determine interruption type +	bal	do_interruption + +	.align	5 +machine_error: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 5				! Determine interruption type +	bal	do_interruption + +	.align	5 +debug: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 6				! Determine interruption type +	bal	do_interruption + +	.align	5 +general_exception: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 7				! Determine interruption type +	bal	do_interruption + +	.align	5 +syscall: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 8				! Determine interruption type +	bal	do_interruption + +	.align	5 +internal_interrupt: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 9				! Determine interruption type +	bal	do_interruption + +	.align	5 +software_interrupt: +	SAVE_ALL +	move	$r0, $sp			! To get the kernel stack +	li	$r1, 10				! Determine interruption type +	bal	do_interruption + +	.align	5 + +/* + * void reset_cpu(ulong addr); + * $r0: input address to jump to + */ +.globl reset_cpu +reset_cpu: +/* No need to disable MMU because we never enable it */ + +	bal	invalidate_icac +	bal	invalidate_dcac +	mfsr	$p0, $MMU_CFG +	andi	$p0, $p0, 0x3			! MMPS +	li	$p1, 0x2			! TLB MMU +	bne	$p0, $p1, 1f +	tlbop	flushall			! Flush TLB +1: +	mfsr	$p0, MR_CAC_CTL			! Get the $CACHE_CTL reg +	li	$p1, DIS_DCAC +	and	$p0, $p0, $p1			! Clear the DC_EN bit +	mtsr	$p0, MR_CAC_CTL			! Write back the $CACHE_CTL reg +	br	$r0				! Jump to the input address diff --git a/roms/u-boot/arch/nds32/cpu/n1213/u-boot.lds b/roms/u-boot/arch/nds32/cpu/n1213/u-boot.lds new file mode 100644 index 00000000..b88d7426 --- /dev/null +++ b/roms/u-boot/arch/nds32/cpu/n1213/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2011 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com> + * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-nds32", "elf32-nds32", "elf32-nds32") +OUTPUT_ARCH(nds32) +ENTRY(_start) +SECTIONS +{ +	. = ALIGN(4); +	.text : +	{ +		arch/nds32/cpu/n1213/start.o	(.text) +		*(.text) +	} + +	. = ALIGN(4); +	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + +	. = ALIGN(4); +	.data : { *(.data*) } + +	. = ALIGN(4); + +	.got : { +		__got_start = .; +		 *(.got.plt) *(.got) +		__got_end = .; +	} + +	. = .; + +	. = ALIGN(4); +	.u_boot_list : { +		KEEP(*(SORT(.u_boot_list*))); +	} + +	. = ALIGN(4); + +	_end = .; + +	.bss : { +		__bss_start = .; +		*(.bss) +		 . = ALIGN(4); +		__bss_end = .; +	} + +}  | 
