diff options
Diffstat (limited to 'roms/u-boot/arch/arm/cpu/arm920t')
34 files changed, 2532 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/cpu/arm920t/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/Makefile new file mode 100644 index 00000000..aac8043f --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +extra-y	= start.o + +obj-y	+= cpu.o +obj-$(CONFIG_USE_IRQ)	+= interrupts.o diff --git a/roms/u-boot/arch/arm/cpu/arm920t/a320/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/a320/Makefile new file mode 100644 index 00000000..bbdab588 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/a320/Makefile @@ -0,0 +1,9 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	+= reset.o +obj-y	+= timer.o diff --git a/roms/u-boot/arch/arm/cpu/arm920t/a320/reset.S b/roms/u-boot/arch/arm/cpu/arm920t/a320/reset.S new file mode 100644 index 00000000..81f9dc98 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/a320/reset.S @@ -0,0 +1,10 @@ +/* + * (C) Copyright 2009 Faraday Technology + * Po-Yu Chuang <ratbert@faraday-tech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +.global reset_cpu +reset_cpu: +	b	reset_cpu diff --git a/roms/u-boot/arch/arm/cpu/arm920t/a320/timer.c b/roms/u-boot/arch/arm/cpu/arm920t/a320/timer.c new file mode 100644 index 00000000..1ac5b601 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/a320/timer.c @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2009 Faraday Technology + * Po-Yu Chuang <ratbert@faraday-tech.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <faraday/ftpmu010.h> +#include <faraday/fttmr010.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define TIMER_CLOCK	32768 +#define TIMER_LOAD_VAL	0xffffffff + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ +	tick *= CONFIG_SYS_HZ; +	do_div(tick, gd->arch.timer_rate_hz); + +	return tick; +} + +static inline unsigned long long usec_to_tick(unsigned long long usec) +{ +	usec *= gd->arch.timer_rate_hz; +	do_div(usec, 1000000); + +	return usec; +} + +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); + +	/* use 32768Hz oscillator for RTC, WDT, TIMER */ +	ftpmu010_32768osc_enable(); + +	/* 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); +	cr |= FTTMR010_TM3_CLOCK;	/* use external clock */ +	cr |= FTTMR010_TM3_ENABLE; +	writel(cr, &tmr->cr); + +	gd->arch.timer_rate_hz = TIMER_CLOCK; +	gd->arch.tbu = gd->arch.tbl = 0; + +	return 0; +} + +/* + * Get the current 64 bit timer tick count + */ +unsigned long long get_ticks(void) +{ +	struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE; +	ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter); + +	/* increment tbu if tbl has rolled over */ +	if (now < gd->arch.tbl) +		gd->arch.tbu++; +	gd->arch.tbl = now; +	return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; +} + +void __udelay(unsigned long usec) +{ +	unsigned long long start; +	ulong tmo; + +	start = get_ticks();		/* get current timestamp */ +	tmo = usec_to_tick(usec);	/* convert usecs to ticks */ +	while ((get_ticks() - start) < tmo) +		;			/* loop till time has passed */ +} + +/* + * get_timer(base) can be used to check for timeouts or + * to measure elasped time relative to an event: + * + * ulong start_time = get_timer(0) sets start_time to the current + * time value. + * get_timer(start_time) returns the time elapsed since then. + * + * The time is used in CONFIG_SYS_HZ units! + */ +ulong get_timer(ulong base) +{ +	return tick_to_time(get_ticks()) - base; +} + +/* + * Return the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ +	return gd->arch.timer_rate_hz; +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/at91/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/at91/Makefile new file mode 100644 index 00000000..561b4b4c --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/at91/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	+= lowlevel_init.o +obj-y	+= reset.o +obj-y	+= timer.o +obj-y	+= clock.o +obj-y	+= cpu.o +obj-y	+= at91rm9200_devices.o diff --git a/roms/u-boot/arch/arm/cpu/arm920t/at91/at91rm9200_devices.c b/roms/u-boot/arch/arm/cpu/arm920t/at91/at91rm9200_devices.c new file mode 100644 index 00000000..fc54327c --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/at91/at91rm9200_devices.c @@ -0,0 +1,67 @@ +/* + * [partely copied from arch/arm/cpu/arm926ejs/at91/arm9260_devices.c] + * + * (C) Copyright 2011 + * Andreas Bießmann <andreas.devel@googlemail.com> + * + * (C) Copyright 2007-2008 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/at91_common.h> +#include <asm/arch/at91_pmc.h> +#include <asm/arch/gpio.h> + +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif + +void at91_serial0_hw_init(void) +{ +	at91_pmc_t	*pmc	= (at91_pmc_t *)ATMEL_BASE_PMC; + +	at91_set_a_periph(AT91_PIO_PORTA, 17, 1);		/* TXD0 */ +	at91_set_a_periph(AT91_PIO_PORTA, 18, PUP);		/* RXD0 */ +	writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ +	at91_pmc_t	*pmc	= (at91_pmc_t *)ATMEL_BASE_PMC; + +	at91_set_a_periph(AT91_PIO_PORTB, 20, PUP);		/* RXD1 */ +	at91_set_a_periph(AT91_PIO_PORTB, 21, 1);		/* TXD1 */ +	writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ +	at91_pmc_t	*pmc	= (at91_pmc_t *)ATMEL_BASE_PMC; + +	at91_set_a_periph(AT91_PIO_PORTA, 22, PUP);		/* RXD2 */ +	at91_set_a_periph(AT91_PIO_PORTA, 23, 1);		/* TXD2 */ +	writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_seriald_hw_init(void) +{ +	at91_set_a_periph(AT91_PIO_PORTA, 30, PUP);		/* DRXD */ +	at91_set_a_periph(AT91_PIO_PORTA, 31, 1);		/* DTXD */ +	/* writing SYS to PCER has no effect on AT91RM9200 */ +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/at91/clock.c b/roms/u-boot/arch/arm/cpu/arm920t/at91/clock.c new file mode 100644 index 00000000..2813bf78 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/at91/clock.c @@ -0,0 +1,157 @@ +/* + * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] + * + * Copyright (C) 2011 Andreas Bießmann + * Copyright (C) 2005 David Brownell + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_pmc.h> +#include <asm/arch/clk.h> + +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static unsigned long at91_css_to_rate(unsigned long css) +{ +	switch (css) { +	case AT91_PMC_MCKR_CSS_SLOW: +		return CONFIG_SYS_AT91_SLOW_CLOCK; +	case AT91_PMC_MCKR_CSS_MAIN: +		return gd->arch.main_clk_rate_hz; +	case AT91_PMC_MCKR_CSS_PLLA: +		return gd->arch.plla_rate_hz; +	case AT91_PMC_MCKR_CSS_PLLB: +		return gd->arch.pllb_rate_hz; +	} + +	return 0; +} + +#ifdef CONFIG_USB_ATMEL +static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) +{ +	unsigned i, div = 0, mul = 0, diff = 1 << 30; +	unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; + +	/* PLL output max 240 MHz (or 180 MHz per errata) */ +	if (out_freq > 240000000) +		goto fail; + +	for (i = 1; i < 256; i++) { +		int diff1; +		unsigned input, mul1; + +		/* +		 * PLL input between 1MHz and 32MHz per spec, but lower +		 * frequences seem necessary in some cases so allow 100K. +		 * Warning: some newer products need 2MHz min. +		 */ +		input = main_freq / i; +		if (input < 100000) +			continue; +		if (input > 32000000) +			continue; + +		mul1 = out_freq / input; +		if (mul1 > 2048) +			continue; +		if (mul1 < 2) +			goto fail; + +		diff1 = out_freq - input * mul1; +		if (diff1 < 0) +			diff1 = -diff1; +		if (diff > diff1) { +			diff = diff1; +			div = i; +			mul = mul1; +			if (diff == 0) +				break; +		} +	} +	if (i == 256 && diff > (out_freq >> 5)) +		goto fail; +	return ret | ((mul - 1) << 16) | div; +fail: +	return 0; +} +#endif + +static u32 at91_pll_rate(u32 freq, u32 reg) +{ +	unsigned mul, div; + +	div = reg & 0xff; +	mul = (reg >> 16) & 0x7ff; +	if (div && mul) { +		freq /= div; +		freq *= mul + 1; +	} else +		freq = 0; + +	return freq; +} + +int at91_clock_init(unsigned long main_clock) +{ +	unsigned freq, mckr; +	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK +	unsigned tmp; +	/* +	 * When the bootloader initialized the main oscillator correctly, +	 * there's no problem using the cycle counter.  But if it didn't, +	 * or when using oscillator bypass mode, we must be told the speed +	 * of the main clock. +	 */ +	if (!main_clock) { +		do { +			tmp = readl(&pmc->mcfr); +		} while (!(tmp & AT91_PMC_MCFR_MAINRDY)); +		tmp &= AT91_PMC_MCFR_MAINF_MASK; +		main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); +	} +#endif +	gd->arch.main_clk_rate_hz = main_clock; + +	/* report if PLLA is more than mildly overclocked */ +	gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + +#ifdef CONFIG_USB_ATMEL +	/* +	 * USB clock init:  choose 48 MHz PLLB value, +	 * disable 48MHz clock during usb peripheral suspend. +	 * +	 * REVISIT:  assumes MCK doesn't derive from PLLB! +	 */ +	gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | +			     AT91_PMC_PLLBR_USBDIV_2; +	gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, +					      gd->arch.at91_pllb_usb_init); +#endif + +	/* +	 * MCK and CPU derive from one of those primary clocks. +	 * For now, assume this parentage won't change. +	 */ +	mckr = readl(&pmc->mckr); +	gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); +	freq = gd->arch.mck_rate_hz; + +	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */ +	/* mdiv */ +	gd->arch.mck_rate_hz = freq / +			(1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); +	gd->arch.cpu_clk_rate_hz = freq; + +	return 0; +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/at91/cpu.c b/roms/u-boot/arch/arm/cpu/arm920t/at91/cpu.c new file mode 100644 index 00000000..b0f411b1 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/at91/cpu.c @@ -0,0 +1,26 @@ +/* + * [origin: arch/arm/cpu/arm926ejs/at91/cpu.c] + * + * (C) Copyright 2011 + * Andreas Bießmann, andreas.devel@googlemail.com + * (C) Copyright 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * (C) Copyright 2009 + * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/clk.h> + +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK +#define CONFIG_SYS_AT91_MAIN_CLOCK 0 +#endif + +int arch_cpu_init(void) +{ +	return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/at91/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/arm920t/at91/lowlevel_init.S new file mode 100644 index 00000000..d2934a35 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/at91/lowlevel_init.S @@ -0,0 +1,152 @@ +/* + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + *		       Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the at91rm9200dk board by + * (C) Copyright 2004 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <config.h> + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + +#include <asm/arch/hardware.h> +#include <asm/arch/at91_mc.h> +#include <asm/arch/at91_pmc.h> +#include <asm/arch/at91_pio.h> + +#define ARM920T_CONTROL	0xC0000000	/* @ set bit 31 (iA) and 30 (nF) */ + +_MTEXT_BASE: +#undef START_FROM_MEM +#ifdef START_FROM_MEM +	.word	CONFIG_SYS_TEXT_BASE-PHYS_FLASH_1 +#else +	.word	CONFIG_SYS_TEXT_BASE +#endif + +.globl lowlevel_init +lowlevel_init: +	ldr     r1, =AT91_ASM_PMC_MOR +	/* Main oscillator Enable register */ +#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR +	ldr     r0, =0x0000FF01		/* Enable main oscillator */ +#else +	ldr     r0, =0x0000FF00		/* Disable main oscillator */ +#endif +	str     r0, [r1] /*AT91C_CKGR_MOR] */ +	/* Add loop to compensate Main Oscillator startup time */ +	ldr     r0, =0x00000010 +LoopOsc: +	subs    r0, r0, #1 +	bhi     LoopOsc + +	/* memory control configuration */ +	/* this isn't very elegant, but	 what the heck */ +	ldr	r0, =SMRDATA +	ldr	r1, _MTEXT_BASE +	sub	r0, r0, r1 +	ldr	r2, =SMRDATAE +	sub	r2, r2, r1 +pllloop: +	/* the address */ +	ldr	r1, [r0], #4 +	/* the value */ +	ldr	r3, [r0], #4 +	str	r3, [r1] +	cmp	r2, r0 +	bne	pllloop +	/* delay - this is all done by guess */ +	ldr	r0, =0x00010000 +	/* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */ +lock: +	subs	r0, r0, #1 +	bhi	lock +	ldr	r0, =SMRDATA1 +	ldr	r1, _MTEXT_BASE +	sub	r0, r0, r1 +	ldr	r2, =SMRDATA1E +	sub	r2, r2, r1 +sdinit: +	/* the address */ +	ldr	r1, [r0], #4 +	/* the value */ +	ldr	r3, [r0], #4 +	str	r3, [r1] +	cmp	r2, r0 +	bne	sdinit + +	/* switch from FastBus to Asynchronous clock mode */ +	mrc	p15, 0, r0, c1, c0, 0 +	orr	r0, r0, #ARM920T_CONTROL +	mcr	p15, 0, r0, c1, c0, 0 + +	/* everything is fine now */ +	mov	pc, lr + +	.ltorg + +SMRDATA: +	.word AT91_ASM_MC_EBI_CFG +	.word CONFIG_SYS_EBI_CFGR_VAL +	.word AT91_ASM_MC_SMC_CSR0 +	.word CONFIG_SYS_SMC_CSR0_VAL +	.word AT91_ASM_PMC_PLLAR +	.word CONFIG_SYS_PLLAR_VAL +	.word AT91_ASM_PMC_PLLBR +	.word CONFIG_SYS_PLLBR_VAL +	.word AT91_ASM_PMC_MCKR +	.word CONFIG_SYS_MCKR_VAL +SMRDATAE: +	/* here there's a delay */ +SMRDATA1: +	.word AT91_ASM_PIOC_ASR +	.word CONFIG_SYS_PIOC_ASR_VAL +	.word AT91_ASM_PIOC_BSR +	.word CONFIG_SYS_PIOC_BSR_VAL +	.word AT91_ASM_PIOC_PDR +	.word CONFIG_SYS_PIOC_PDR_VAL +	.word AT91_ASM_MC_EBI_CSA +	.word CONFIG_SYS_EBI_CSA_VAL +	.word AT91_ASM_MC_SDRAMC_CR +	.word CONFIG_SYS_SDRC_CR_VAL +	.word AT91_ASM_MC_SDRAMC_MR +	.word CONFIG_SYS_SDRC_MR_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word AT91_ASM_MC_SDRAMC_MR +	.word CONFIG_SYS_SDRC_MR_VAL1 +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word AT91_ASM_MC_SDRAMC_MR +	.word CONFIG_SYS_SDRC_MR_VAL2 +	.word CONFIG_SYS_SDRAM1 +	.word CONFIG_SYS_SDRAM_VAL +	.word AT91_ASM_MC_SDRAMC_TR +	.word CONFIG_SYS_SDRC_TR_VAL +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +	.word AT91_ASM_MC_SDRAMC_MR +	.word CONFIG_SYS_SDRC_MR_VAL3 +	.word CONFIG_SYS_SDRAM +	.word CONFIG_SYS_SDRAM_VAL +SMRDATA1E: +	/* SMRDATA1 is 176 bytes long */ +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/roms/u-boot/arch/arm/cpu/arm920t/at91/reset.c b/roms/u-boot/arch/arm/cpu/arm920t/at91/reset.c new file mode 100644 index 00000000..d47777a3 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/at91/reset.c @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. <www.lineo.com> + * Bernhard Kuhn <bkuhn@lineo.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_st.h> + +void  __attribute__((weak)) board_reset(void) +{ +	/* true empty function for defining weak symbol */ +} + +void reset_cpu(ulong ignored) +{ +	at91_st_t *st = (at91_st_t *) ATMEL_BASE_ST; + +	board_reset(); + +	/* Reset the cpu by setting up the watchdog timer */ +	writel(AT91_ST_WDMR_RSTEN | AT91_ST_WDMR_EXTEN | AT91_ST_WDMR_WDV(2), +		&st->wdmr); +	writel(AT91_ST_CR_WDRST, &st->cr); +	/* and let it timeout */ +	while (1) +		; +	/* Never reached */ +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/at91/timer.c b/roms/u-boot/arch/arm/cpu/arm920t/at91/timer.c new file mode 100644 index 00000000..6aa29947 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/at91/timer.c @@ -0,0 +1,127 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. <www.lineo.com> + * Bernhard Kuhn <bkuhn@lineo.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_tc.h> +#include <asm/arch/at91_pmc.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* the number of clocks per CONFIG_SYS_HZ */ +#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) + +int timer_init(void) +{ +	at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC; +	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + +	/* enables TC1.0 clock */ +	writel(1 << ATMEL_ID_TC0, &pmc->pcer);	/* enable clock */ + +	writel(0, &tc->bcr); +	writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE | +		AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr); + +	writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr); +	/* set to MCLK/2 and restart the timer +	when the value in TC_RC is reached */ +	writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr); + +	writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interrupts */ +	writel(TIMER_LOAD_VAL, &tc->tc[0].rc); + +	writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr); +	gd->arch.lastinc = 0; +	gd->arch.tbl = 0; + +	return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer(ulong base) +{ +	return get_timer_masked() - base; +} + +void __udelay(unsigned long usec) +{ +	udelay_masked(usec); +} + +ulong get_timer_raw(void) +{ +	at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC; +	u32 now; + +	now = readl(&tc->tc[0].cv) & 0x0000ffff; + +	if (now >= gd->arch.lastinc) { +		/* normal mode */ +		gd->arch.tbl += now - gd->arch.lastinc; +	} else { +		/* we have an overflow ... */ +		gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc; +	} +	gd->arch.lastinc = now; + +	return gd->arch.tbl; +} + +ulong get_timer_masked(void) +{ +	return get_timer_raw()/TIMER_LOAD_VAL; +} + +void udelay_masked(unsigned long usec) +{ +	u32 tmo; +	u32 endtime; +	signed long diff; + +	tmo = CONFIG_SYS_HZ_CLOCK / 1000; +	tmo *= usec; +	tmo /= 1000; + +	endtime = get_timer_raw() + tmo; + +	do { +		u32 now = get_timer_raw(); +		diff = endtime - now; +	} while (diff >= 0); +} + +/* + * 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) +{ +	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) +{ +	return CONFIG_SYS_HZ; +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/config.mk b/roms/u-boot/arch/arm/cpu/arm920t/config.mk new file mode 100644 index 00000000..799afff0 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/config.mk @@ -0,0 +1,8 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +PLATFORM_CPPFLAGS += -march=armv4 diff --git a/roms/u-boot/arch/arm/cpu/arm920t/cpu.c b/roms/u-boot/arch/arm/cpu/arm920t/cpu.c new file mode 100644 index 00000000..d73b51dc --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/cpu.c @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ +	/* +	 * this function is called just before we call linux +	 * it prepares the processor for linux +	 * +	 * we turn off caches etc ... +	 */ + +	disable_interrupts (); + +	/* turn off I/D-cache */ +	icache_disable(); +	dcache_disable(); +	/* flush I/D-cache */ +	cache_flush(); + +	return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ +	unsigned long i = 0; + +	asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/Makefile new file mode 100644 index 00000000..638333a4 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/Makefile @@ -0,0 +1,21 @@ +# +# Cirrus Logic EP93xx CPU-specific Makefile +# +# Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> +# +# Copyright (C) 2004, 2005 +# Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> +# +# Copyright (C) 2006 +# Dominic Rath <Dominic.Rath@gmx.de> +# +# Based on an original Makefile, which is +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y   = cpu.o led.o speed.o timer.o +obj-y   += lowlevel_init.o diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/cpu.c b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/cpu.c new file mode 100644 index 00000000..bb5ffd29 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/cpu.c @@ -0,0 +1,37 @@ +/* + * Cirrus Logic EP93xx CPU-specific support. + * + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * Copyright (C) 2004, 2005 + * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/ep93xx.h> +#include <asm/io.h> + +/* We reset the CPU by generating a 1-->0 transition on DeviceCfg bit 31. */ +extern void reset_cpu(ulong addr) +{ +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; +	uint32_t value; + +	/* Unlock DeviceCfg and set SWRST */ +	writel(0xAA, &syscon->sysswlock); +	value = readl(&syscon->devicecfg); +	value |= SYSCON_DEVICECFG_SWRST; +	writel(value, &syscon->devicecfg); + +	/* Unlock DeviceCfg and clear SWRST */ +	writel(0xAA, &syscon->sysswlock); +	value = readl(&syscon->devicecfg); +	value &= ~SYSCON_DEVICECFG_SWRST; +	writel(value, &syscon->devicecfg); + +	/* Dying... */ +	while (1) +		; /* noop */ +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/led.c b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/led.c new file mode 100644 index 00000000..61447291 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/led.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010, 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/arch/ep93xx.h> +#include <config.h> +#include <status_led.h> + +static uint8_t saved_state[2] = {STATUS_LED_OFF, STATUS_LED_OFF}; +static uint32_t gpio_pin[2] = {1 << STATUS_LED_GREEN, +			       1 << STATUS_LED_RED}; + +inline void switch_LED_on(uint8_t led) +{ +	register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; + +	writel(readl(&gpio->pedr) | gpio_pin[led], &gpio->pedr); +	saved_state[led] = STATUS_LED_ON; +} + +inline void switch_LED_off(uint8_t led) +{ +	register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; + +	writel(readl(&gpio->pedr) & ~gpio_pin[led], &gpio->pedr); +	saved_state[led] = STATUS_LED_OFF; +} + +void red_led_on(void) +{ +	switch_LED_on(STATUS_LED_RED); +} + +void red_led_off(void) +{ +	switch_LED_off(STATUS_LED_RED); +} + +void green_led_on(void) +{ +	switch_LED_on(STATUS_LED_GREEN); +} + +void green_led_off(void) +{ +	switch_LED_off(STATUS_LED_GREEN); +} + +void __led_init(led_id_t mask, int state) +{ +	__led_set(mask, state); +} + +void __led_toggle(led_id_t mask) +{ +	if (STATUS_LED_RED == mask) { +		if (STATUS_LED_ON == saved_state[STATUS_LED_RED]) +			red_led_off(); +		else +			red_led_on(); +	} else if (STATUS_LED_GREEN == mask) { +		if (STATUS_LED_ON == saved_state[STATUS_LED_GREEN]) +			green_led_off(); +		else +			green_led_on(); +	} +} + +void __led_set(led_id_t mask, int state) +{ +	if (STATUS_LED_RED == mask) { +		if (STATUS_LED_ON == state) +			red_led_on(); +		else +			red_led_off(); +	} else if (STATUS_LED_GREEN == mask) { +		if (STATUS_LED_ON == state) +			green_led_on(); +		else +			green_led_off(); +	} +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S new file mode 100644 index 00000000..bf2fa2ac --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S @@ -0,0 +1,49 @@ +/* + * Low-level initialization for EP93xx + * + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <version.h> +#include <asm/arch/ep93xx.h> + +.globl lowlevel_init +lowlevel_init: +	/* backup return address */ +	ldr r1, =SYSCON_SCRATCH0 +	str lr, [r1] + +	/* Turn on both LEDs */ +	bl red_led_on +	bl green_led_on + +	/* Configure flash wait states before we switch to the PLL */ +	bl flash_cfg + +	/* Set up PLL */ +	bl pll_cfg + +	/* Turn off the Green LED and leave the Red LED on */ +	bl green_led_off + +	/* Setup SDRAM */ +	bl sdram_cfg + +	/* Turn on Green LED, Turn off the Red LED */ +	bl green_led_on +	bl red_led_off + +	/* FIXME: we use async mode for now */ +	mrc p15, 0, r0, c1, c0, 0 +	orr r0, r0, #0xc0000000 +	mcr p15, 0, r0, c1, c0, 0 + +	/* restore return address */ +	ldr r1, =SYSCON_SCRATCH0 +	ldr lr, [r1] + +	mov pc, lr diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/speed.c b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/speed.c new file mode 100644 index 00000000..9dc60b6f --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/speed.c @@ -0,0 +1,96 @@ +/* + * Cirrus Logic EP93xx PLL support. + * + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/ep93xx.h> +#include <asm/io.h> +#include <div64.h> + +/* + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ + +/* + * return the PLL output frequency + * + * PLL rate = CONFIG_SYS_CLK_FREQ * (X1FBD + 1) * (X2FBD + 1) + * / (X2IPD + 1) / 2^PS + */ +static ulong get_PLLCLK(uint32_t *pllreg) +{ +	uint8_t i; +	const uint32_t clkset = readl(pllreg); +	uint64_t rate = CONFIG_SYS_CLK_FREQ; +	rate *= ((clkset >> SYSCON_CLKSET_PLL_X1FBD1_SHIFT) & 0x1f) + 1; +	rate *= ((clkset >> SYSCON_CLKSET_PLL_X2FBD2_SHIFT) & 0x3f) + 1; +	do_div(rate, (clkset  & 0x1f) + 1);			/* X2IPD */ +	for (i = 0; i < ((clkset >> SYSCON_CLKSET_PLL_PS_SHIFT) & 3); i++) +		rate >>= 1; + +	return (ulong)rate; +} + +/* return FCLK frequency */ +ulong get_FCLK() +{ +	const uint8_t fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + +	const uint32_t clkset1 = readl(&syscon->clkset1); +	const uint8_t fclk_div = +		fclk_divisors[(clkset1 >> SYSCON_CLKSET1_FCLK_DIV_SHIFT) & 7]; +	const ulong fclk_rate = get_PLLCLK(&syscon->clkset1) / fclk_div; + +	return fclk_rate; +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ +	const uint8_t hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + +	const uint32_t clkset1 = readl(&syscon->clkset1); +	const uint8_t hclk_div = +		hclk_divisors[(clkset1 >> SYSCON_CLKSET1_HCLK_DIV_SHIFT) & 7]; +	const ulong hclk_rate = get_PLLCLK(&syscon->clkset1) / hclk_div; + +	return hclk_rate; +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ +	const uint8_t pclk_divisors[] = { 1, 2, 4, 8 }; +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + +	const uint32_t clkset1 = readl(&syscon->clkset1); +	const uint8_t pclk_div = +		pclk_divisors[(clkset1 >> SYSCON_CLKSET1_PCLK_DIV_SHIFT) & 3]; +	const ulong pclk_rate = get_HCLK() / pclk_div; + +	return pclk_rate; +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ +	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; +	ulong uclk_rate; + +	const uint32_t value = readl(&syscon->pwrcnt); +	if (value & SYSCON_PWRCNT_UART_BAUD) +		uclk_rate = CONFIG_SYS_CLK_FREQ; +	else +		uclk_rate = CONFIG_SYS_CLK_FREQ / 2; + +	return uclk_rate; +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c new file mode 100644 index 00000000..c2f239aa --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c @@ -0,0 +1,120 @@ +/* + * Cirrus Logic EP93xx timer support. + * + * Copyright (C) 2009, 2010 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * Copyright (C) 2004, 2005 + * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> + * + * Based on the original intr.c Cirrus Logic EP93xx Rev D. interrupt support, + * author unknown. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <linux/types.h> +#include <asm/arch/ep93xx.h> +#include <asm/io.h> +#include <div64.h> + +#define TIMER_CLKSEL	(1 << 3) +#define TIMER_ENABLE	(1 << 7) + +#define TIMER_FREQ			508469		/* ticks / second */ +#define TIMER_MAX_VAL			0xFFFFFFFF + +static struct ep93xx_timer +{ +	unsigned long long ticks; +	unsigned long last_read; +} timer; + +static inline unsigned long long usecs_to_ticks(unsigned long usecs) +{ +	unsigned long long ticks = (unsigned long long)usecs * TIMER_FREQ; +	do_div(ticks, 1000 * 1000); + +	return ticks; +} + +static inline void read_timer(void) +{ +	struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE; +	const unsigned long now = TIMER_MAX_VAL - readl(&timer_regs->timer3.value); + +	if (now >= timer.last_read) +		timer.ticks += now - timer.last_read; +	else +		/* an overflow occurred */ +		timer.ticks += TIMER_MAX_VAL - timer.last_read + now; + +	timer.last_read = now; +} + +/* + * Get the number of ticks (in CONFIG_SYS_HZ resolution) + */ +unsigned long long get_ticks(void) +{ +	unsigned long long sys_ticks; + +	read_timer(); + +	sys_ticks = timer.ticks * CONFIG_SYS_HZ; +	do_div(sys_ticks, TIMER_FREQ); + +	return sys_ticks; +} + +unsigned long get_timer_masked(void) +{ +	return get_ticks(); +} + +unsigned long get_timer(unsigned long base) +{ +	return get_timer_masked() - base; +} + +void __udelay(unsigned long usec) +{ +	unsigned long long target; + +	read_timer(); + +	target = timer.ticks + usecs_to_ticks(usec); + +	while (timer.ticks < target) +		read_timer(); +} + +int timer_init(void) +{ +	struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE; + +	/* use timer 3 with 508KHz and free running, not enabled now */ +	writel(TIMER_CLKSEL, &timer_regs->timer3.control); + +	/* set initial timer value */ +	writel(TIMER_MAX_VAL, &timer_regs->timer3.load); + +	/* Enable the timer */ +	writel(TIMER_ENABLE | TIMER_CLKSEL, +		&timer_regs->timer3.control); + +	/* Reset the timer */ +	read_timer(); +	timer.ticks = 0; + +	return 0; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ +	return CONFIG_SYS_HZ; +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/u-boot.lds b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/u-boot.lds new file mode 100644 index 00000000..96994043 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ep93xx/u-boot.lds @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ +	. = 0x00000000; + +	. = ALIGN(4); +	.text      : +	{ +		*(.__image_copy_start) +	  arch/arm/cpu/arm920t/start.o	(.text*) +		/* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */ +	  . = 0x1000; +	  LONG(0x53555243) +	  *(.text*) +	} + +	. = ALIGN(4); +	.rodata : { *(.rodata*) } + +	. = ALIGN(4); +	.data : { *(.data*) } + +	. = ALIGN(4); +	.got : { *(.got) } + +	. = .; + +	. = ALIGN(4); +	.u_boot_list : { +		KEEP(*(SORT(.u_boot_list*))); +	} + +	. = ALIGN(4); + +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	__bss_start = .; +	.bss : { *(.bss*) } +	__bss_end = .; + +	.end : +	{ +		*(.__end) +	} +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/imx/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/imx/Makefile new file mode 100644 index 00000000..54ce646d --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/imx/Makefile @@ -0,0 +1,10 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	+= generic.o +obj-y	+= speed.o +obj-y	+= timer.o diff --git a/roms/u-boot/arch/arm/cpu/arm920t/imx/generic.c b/roms/u-boot/arch/arm/cpu/arm920t/imx/generic.c new file mode 100644 index 00000000..1441ab43 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/imx/generic.c @@ -0,0 +1,77 @@ +/* + *  arch/arm/mach-imx/generic.c + * + *  author: Sascha Hauer + *  Created: april 20th, 2004 + *  Copyright: Synertronixx GmbH + * + *  Common code for i.MX machines + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +#ifdef CONFIG_IMX + +#include <asm/arch/imx-regs.h> + +void imx_gpio_mode(int gpio_mode) +{ +	unsigned int pin = gpio_mode & GPIO_PIN_MASK; +	unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5; +	unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10; +	unsigned int tmp; + +	/* Pullup enable */ +	if(gpio_mode & GPIO_PUEN) +		PUEN(port) |= (1<<pin); +	else +		PUEN(port) &= ~(1<<pin); + +	/* Data direction */ +	if(gpio_mode & GPIO_OUT) +		DDIR(port) |= 1<<pin; +	else +		DDIR(port) &= ~(1<<pin); + +	/* Primary / alternate function */ +	if(gpio_mode & GPIO_AF) +		GPR(port) |= (1<<pin); +	else +		GPR(port) &= ~(1<<pin); + +	/* use as gpio? */ +	if( ocr == 3 ) +		GIUS(port) |= (1<<pin); +	else +		GIUS(port) &= ~(1<<pin); + +	/* Output / input configuration */ +	/* FIXME: I'm not very sure about OCR and ICONF, someone +	 * should have a look over it +	 */ +	if(pin<16) { +		tmp = OCR1(port); +		tmp &= ~( 3<<(pin*2)); +		tmp |= (ocr << (pin*2)); +		OCR1(port) = tmp; + +		if( gpio_mode &	GPIO_AOUT ) +			ICONFA1(port) &= ~( 3<<(pin*2)); +		if( gpio_mode &	GPIO_BOUT ) +			ICONFB1(port) &= ~( 3<<(pin*2)); +	} else { +		tmp = OCR2(port); +		tmp &= ~( 3<<((pin-16)*2)); +		tmp |= (ocr << ((pin-16)*2)); +		OCR2(port) = tmp; + +		if( gpio_mode &	GPIO_AOUT ) +			ICONFA2(port) &= ~( 3<<((pin-16)*2)); +		if( gpio_mode &	GPIO_BOUT ) +			ICONFB2(port) &= ~( 3<<((pin-16)*2)); +	} +} + +#endif /* CONFIG_IMX */ diff --git a/roms/u-boot/arch/arm/cpu/arm920t/imx/speed.c b/roms/u-boot/arch/arm/cpu/arm920t/imx/speed.c new file mode 100644 index 00000000..1951313d --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/imx/speed.c @@ -0,0 +1,86 @@ +/* + * + * (c) 2004 Sascha Hauer <sascha@saschahauer.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + + +#include <common.h> +#if defined (CONFIG_IMX) + +#include <asm/arch/imx-regs.h> + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * SH FIXME: 16780000 in our case + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +ulong get_systemPLLCLK(void) +{ +	/* FIXME: We assume System_SEL = 0 here */ +	u32 spctl0 = SPCTL0; +	u32 mfi = (spctl0 >> 10) & 0xf; +	u32 mfn = spctl0 & 0x3f; +	u32 mfd = (spctl0 >> 16) & 0x3f; +	u32 pd =  (spctl0 >> 26) & 0xf; + +	mfi = mfi<=5 ? 5 : mfi; + +	return (2*(CONFIG_SYSPLL_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1); +} + +ulong get_mcuPLLCLK(void) +{ +	/* FIXME: We assume System_SEL = 0 here */ +	u32 mpctl0 = MPCTL0; +	u32 mfi = (mpctl0 >> 10) & 0xf; +	u32 mfn = mpctl0 & 0x3f; +	u32 mfd = (mpctl0 >> 16) & 0x3f; +	u32 pd =  (mpctl0 >> 26) & 0xf; + +	mfi = mfi<=5 ? 5 : mfi; + +	return (2*(CONFIG_SYS_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1); +} + +ulong get_FCLK(void) +{ +	return (( CSCR>>15)&1) ? get_mcuPLLCLK()>>1 : get_mcuPLLCLK(); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ +	u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1; +	printf("bclkdiv: %d\n", bclkdiv); +	return get_systemPLLCLK() / bclkdiv; +} + +/* return BCLK frequency */ +ulong get_BCLK(void) +{ +	return get_HCLK(); +} + +ulong get_PERCLK1(void) +{ +	return get_systemPLLCLK() / (((PCDR) & 0xf)+1); +} + +ulong get_PERCLK2(void) +{ +	return get_systemPLLCLK() / (((PCDR>>4) & 0xf)+1); +} + +ulong get_PERCLK3(void) +{ +	return get_systemPLLCLK() / (((PCDR>>16) & 0x7f)+1); +} + +#endif /* defined (CONFIG_IMX) */ diff --git a/roms/u-boot/arch/arm/cpu/arm920t/imx/timer.c b/roms/u-boot/arch/arm/cpu/arm920t/imx/timer.c new file mode 100644 index 00000000..b62558f9 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/imx/timer.c @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#if defined (CONFIG_IMX) + +#include <asm/arch/imx-regs.h> + +int timer_init (void) +{ +	int i; +	/* setup GP Timer 1 */ +	TCTL1 = TCTL_SWR; +	for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */ +	TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */ +	TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */ + +	/* Reset the timer */ +	TCTL1 &= ~TCTL_TEN; +	TCTL1 |= TCTL_TEN; /* Enable timer */ + +	return (0); +} + +/* + * timer without interrupts + */ +ulong get_timer (ulong base) +{ +	return get_timer_masked() - base; +} + +ulong get_timer_masked (void) +{ +	return TCN1; +} + +void udelay_masked (unsigned long usec) +{ +	ulong endtime = get_timer_masked() + usec; +	signed long diff; + +	do { +		ulong now = get_timer_masked (); +		diff = endtime - now; +	} while (diff >= 0); +} + +void __udelay (unsigned long usec) +{ +	udelay_masked(usec); +} + +/* + * 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) +{ +	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) +{ +	ulong tbclk; + +	tbclk = CONFIG_SYS_HZ; + +	return tbclk; +} + +/* + * Reset the cpu by setting up the watchdog timer and let him time out + */ +void reset_cpu (ulong ignored) +{ +	/* Disable watchdog and set Time-Out field to 0 */ +	WCR = 0x00000000; + +	/* Write Service Sequence */ +	WSR = 0x00005555; +	WSR = 0x0000AAAA; + +	/* Enable watchdog */ +	WCR = 0x00000001; + +	while (1); +	/*NOTREACHED*/ +} + +#endif /* defined (CONFIG_IMX) */ diff --git a/roms/u-boot/arch/arm/cpu/arm920t/interrupts.c b/roms/u-boot/arch/arm/cpu/arm920t/interrupts.c new file mode 100644 index 00000000..0e04d366 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/interrupts.c @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/proc-armv/ptrace.h> + +#if defined (CONFIG_ARCH_INTEGRATOR) +void do_irq (struct pt_regs *pt_regs) +{ +	/* ASSUMED to be a timer interrupt  */ +	/* Just clear it - count handled in */ +	/* integratorap.c                   */ +	*(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0x0C) = 0; +} +#endif diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ks8695/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/ks8695/Makefile new file mode 100644 index 00000000..400aa89e --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ks8695/Makefile @@ -0,0 +1,9 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	= lowlevel_init.o +obj-y	+= timer.o diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ks8695/lowlevel_init.S b/roms/u-boot/arch/arm/cpu/arm920t/ks8695/lowlevel_init.S new file mode 100644 index 00000000..a2a07f2f --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ks8695/lowlevel_init.S @@ -0,0 +1,189 @@ +/* + *  lowlevel_init.S - basic hardware initialization for the KS8695 CPU + * + *  Copyright (c) 2004-2005, Greg Ungerer <greg.ungerer@opengear.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <config.h> +#include <version.h> +#include <asm/arch/platform.h> + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + +/* + ************************************************************************* + * + * Handy dandy macros + * + ************************************************************************* + */ + +/* Delay a bit */ +.macro DELAY_FOR cycles, reg0 +	ldr     \reg0, =\cycles +	subs    \reg0, \reg0, #1 +	subne   pc,  pc, #0xc +.endm + +/* + ************************************************************************* + * + * Some local storage. + * + ************************************************************************* + */ + +/* Should we boot with an interactive console or not */ +.globl serial_console + +/* + ************************************************************************* + * + * Raw hardware initialization code. The important thing is to get + * SDRAM setup and running. We do some other basic things here too, + * like getting the PLL set for high speed, and init the LEDs. + * + ************************************************************************* + */ + +.globl lowlevel_init +lowlevel_init: + +#if DEBUG +	/* +	 * enable UART for early debug trace +	 */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_UART_DIVISOR) +	mov	r2, #((25000000+CONFIG_BAUDRATE/2) / CONFIG_BAUDRATE) +	str	r2, [r1] +	ldr	r1, =(KS8695_IO_BASE+KS8695_UART_LINE_CTRL) +	mov	r2, #KS8695_UART_LINEC_WLEN8 +	str	r2, [r1]		/* 8 data bits, no parity, 1 stop */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING) +	mov	r2, #0x41 +	str	r2, [r1]		/* write 'A' */ +#endif +#if DEBUG +	ldr	r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING) +	mov	r2, #0x42 +	str	r2, [r1] +#endif + +	/* +	 * remap the memory and flash regions. we want to end up with +	 * ram from address 0, and flash at 32MB. +	 */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL0) +	ldr	r2, =0xbfc00040 +	str	r2, [r1]		/* large flash map */ +	ldr	pc, =(highflash+0x02000000-0x00f00000)	/* jump to high flash address */ +highflash: +	ldr	r2, =0x8fe00040 +	str	r2, [r1]		/* remap flash range */ + +	/* +	 * remap the second select region to the 4MB immediately after +	 * the first region. This way if you have a larger flash (say 8Mb) +	 * then you can have it all mapped nicely. Has no effect if you +	 * only have a 4Mb or smaller flash. +	 */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL1) +	ldr	r2, =0x9fe40040 +	str	r2, [r1]		/* remap flash2 region, contiguous */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL) +	ldr	r2, =0x30000005 +	str	r2, [r1]		/* enable both flash selects */ + +#ifdef CONFIG_CM41xx +	/* +	 * map the second flash chip, using the external IO lines. +	 */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_IO_CTRL0) +	ldr	r2, =0xafe80b6d +	str	r2, [r1]		/* remap io0 region, contiguous */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_IO_CTRL1) +	ldr	r2, =0xbfec0b6d +	str	r2, [r1]		/* remap io1 region, contiguous */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL) +	ldr	r2, =0x30050005 +	str	r2, [r1]		/* enable second flash */ +#endif + +	/* +	 * before relocating, we have to setup RAM timing +	 */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL0) +#if (PHYS_SDRAM_1_SIZE == 0x02000000) +	ldr	r2, =0x7fc0000e		/* 32MB */ +#else +	ldr	r2, =0x3fc0000e		/* 16MB */ +#endif +	str	r2, [r1]		/* configure sdram bank0 setup */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL1) +	mov	r2, #0 +	str	r2, [r1]		/* configure sdram bank1 setup */ + +	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_GENERAL) +	ldr	r2, =0x0000000a +	str	r2, [r1]		/* set RAS/CAS timing */ + +	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER) +	ldr	r2, =0x00030000 +	str	r2, [r1]		/* send NOP command */ +	DELAY_FOR 0x100, r0 +	ldr	r2, =0x00010000 +	str	r2, [r1]		/* send PRECHARGE-ALL */ +	DELAY_FOR 0x100, r0 + +	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_REFRESH) +	ldr	r2, =0x00000020 +	str	r2, [r1]		/* set for fast refresh */ +	DELAY_FOR 0x100, r0 +	ldr	r2, =0x00000190 +	str	r2, [r1]		/* set normal refresh timing */ + +	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER) +	ldr	r2, =0x00020033 +	str	r2, [r1]		/* send mode command */ +	DELAY_FOR 0x100, r0 +	ldr	r2, =0x01f00000 +	str	r2, [r1]		/* enable sdram fifos */ + +	/* +	 * set pll to top speed +	 */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_SYSTEN_BUS_CLOCK) +	mov	r2, #0 +	str	r2, [r1]		/* set pll clock to 166MHz */ + +	ldr	r1, =(KS8695_IO_BASE+KS8695_SWITCH_CTRL0) +	ldr	r2, [r1]		/* Get switch ctrl0 register       */ +	and	r2, r2, #0x0fc00000	/* Mask out LED control bits       */ +	orr	r2, r2, #0x01800000	/* Set Link/activity/speed actions */ +	str	r2, [r1] + +#ifdef CONFIG_CM4008 +	ldr	r1, =(KS8695_IO_BASE+KS8695_GPIO_MODE) +	ldr	r2, =0x0000fe30 +	str	r2, [r1]		/* enable LED's as outputs	    */ +	ldr	r1, =(KS8695_IO_BASE+KS8695_GPIO_DATA) +	ldr	r2, =0x0000fe20 +	str	r2, [r1]		/* turn on power LED		    */ +#endif +#if defined(CONFIG_CM4008) || defined(CONFIG_CM41xx) +	ldr	r2, [r1]		/* get current GPIO input data	    */ +	tst	r2, #0x8		/* check if "erase" depressed	    */ +	beq	nobutton +	mov	r2, #0			/* be quiet on boot, no console	    */ +	ldr	r1, =serial_console +	str	r2, [r1] +nobutton: +#endif + +	add	lr, lr, #0x02000000	/* flash is now mapped high */ +	add	ip, ip, #0x02000000	/* this is a hack */ +	mov	pc, lr			/* all done, return */ + +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/roms/u-boot/arch/arm/cpu/arm920t/ks8695/timer.c b/roms/u-boot/arch/arm/cpu/arm920t/ks8695/timer.c new file mode 100644 index 00000000..23db5572 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/ks8695/timer.c @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/platform.h> + +/* + * Initial timer set constants. Nothing complicated, just set for a 1ms + * tick. + */ +#define	TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_1) +#define	TIMER_COUNT	(TIMER_INTERVAL / 2) +#define	TIMER_PULSE	TIMER_COUNT + +/* + * Handy KS8695 register access functions. + */ +#define	ks8695_read(a)    *((volatile ulong *) (KS8695_IO_BASE + (a))) +#define	ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v) + +ulong timer_ticks; + +int timer_init (void) +{ +	/* Set the hadware timer for 1ms */ +	ks8695_write(KS8695_TIMER1, TIMER_COUNT); +	ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE); +	ks8695_write(KS8695_TIMER_CTRL, 0x2); +	timer_ticks = 0; + +	return 0; +} + +ulong get_timer_masked(void) +{ +	/* Check for timer wrap */ +	if (ks8695_read(KS8695_INT_STATUS) & KS8695_INTMASK_TIMERINT1) { +		/* Clear interrupt condition */ +		ks8695_write(KS8695_INT_STATUS, KS8695_INTMASK_TIMERINT1); +		timer_ticks++; +	} +	return timer_ticks; +} + +ulong get_timer(ulong base) +{ +       return (get_timer_masked() - base); +} + +void __udelay(ulong usec) +{ +	ulong start = get_timer_masked(); +	ulong end; + +	/* Only 1ms resolution :-( */ +	end = usec / 1000; +	while (get_timer(start) < end) +		; +} + +void reset_cpu (ulong ignored) +{ +	ulong tc; + +	/* Set timer0 to watchdog, and let it timeout */ +	tc = ks8695_read(KS8695_TIMER_CTRL) & 0x2; +	ks8695_write(KS8695_TIMER_CTRL, tc); +	ks8695_write(KS8695_TIMER0, ((10 << 8) | 0xff)); +	ks8695_write(KS8695_TIMER_CTRL, (tc | 0x1)); + +	/* Should only wait here till watchdog resets */ +	for (;;) +		; +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/Makefile b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/Makefile new file mode 100644 index 00000000..e44c549b --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-$(CONFIG_USE_IRQ) += interrupts.o +obj-$(CONFIG_DISPLAY_CPUINFO)	+= cpu_info.o +obj-y	+= speed.o +obj-y	+= timer.o diff --git a/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/cpu_info.c b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/cpu_info.c new file mode 100644 index 00000000..fede51a1 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/cpu_info.c @@ -0,0 +1,38 @@ +/* + * (C) Copyright 2010 + * David Mueller <d.mueller@elsoft.ch> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/s3c24x0_cpu.h> + +typedef ulong (*getfreq)(void); + +static const getfreq freq_f[] = { +	get_FCLK, +	get_HCLK, +	get_PCLK, +}; + +static const char freq_c[] = { 'F', 'H', 'P' }; + +int print_cpuinfo(void) +{ +	int i; +	char buf[32]; +/* the S3C2400 seems to be lacking a CHIP ID register */ +#ifndef CONFIG_S3C2400 +	ulong cpuid; +	struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); + +	cpuid = readl(&gpio->gstatus1); +	printf("CPUID: %8lX\n", cpuid); +#endif +	for (i = 0; i < ARRAY_SIZE(freq_f); i++) +		printf("%cCLK: %8s MHz\n", freq_c[i], strmhz(buf, freq_f[i]())); + +	return 0; +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/interrupts.c b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/interrupts.c new file mode 100644 index 00000000..036e3b90 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/interrupts.c @@ -0,0 +1,26 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +#include <asm/arch/s3c24x0_cpu.h> +#include <asm/proc-armv/ptrace.h> + +void do_irq (struct pt_regs *pt_regs) +{ +	struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt(); +	u_int32_t intpnd = readl(&irq->INTPND); + +} diff --git a/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/speed.c b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/speed.c new file mode 100644 index 00000000..3701c5d9 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/speed.c @@ -0,0 +1,102 @@ +/* + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* This code should work for both the S3C2400 and the S3C2410 + * as they seem to have the same PLL and clock machinery inside. + * The different address mapping is handled by the s3c24xx.h files below. + */ + +#include <common.h> +#ifdef CONFIG_S3C24X0 + +#include <asm/io.h> +#include <asm/arch/s3c24x0_cpu.h> + +#define MPLL 0 +#define UPLL 1 + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +static ulong get_PLLCLK(int pllreg) +{ +	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); +	ulong r, m, p, s; + +	if (pllreg == MPLL) +		r = readl(&clk_power->mpllcon); +	else if (pllreg == UPLL) +		r = readl(&clk_power->upllcon); +	else +		hang(); + +	m = ((r & 0xFF000) >> 12) + 8; +	p = ((r & 0x003F0) >> 4) + 2; +	s = r & 0x3; + +#if defined(CONFIG_S3C2440) +	if (pllreg == MPLL) +		return 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s)); +#endif +	return (CONFIG_SYS_CLK_FREQ * m) / (p << s); + +} + +/* return FCLK frequency */ +ulong get_FCLK(void) +{ +	return get_PLLCLK(MPLL); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ +	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); +#ifdef CONFIG_S3C2440 +	switch (readl(&clk_power->clkdivn) & 0x6) { +	default: +	case 0: +		return get_FCLK(); +	case 2: +		return get_FCLK() / 2; +	case 4: +		return (readl(&clk_power->camdivn) & (1 << 9)) ? +			get_FCLK() / 8 : get_FCLK() / 4; +	case 6: +		return (readl(&clk_power->camdivn) & (1 << 8)) ? +			get_FCLK() / 6 : get_FCLK() / 3; +	} +#else +	return (readl(&clk_power->clkdivn) & 2) ? get_FCLK() / 2 : get_FCLK(); +#endif +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ +	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + +	return (readl(&clk_power->clkdivn) & 1) ? get_HCLK() / 2 : get_HCLK(); +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ +	return get_PLLCLK(UPLL); +} + +#endif /* CONFIG_S3C24X0 */ diff --git a/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/timer.c b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/timer.c new file mode 100644 index 00000000..ba1e616b --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/s3c24x0/timer.c @@ -0,0 +1,160 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#ifdef CONFIG_S3C24X0 + +#include <asm/io.h> +#include <asm/arch/s3c24x0_cpu.h> + +DECLARE_GLOBAL_DATA_PTR; + +int timer_init(void) +{ +	struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); +	ulong tmr; + +	/* use PWM Timer 4 because it has no output */ +	/* prescaler for Timer 4 is 16 */ +	writel(0x0f00, &timers->tcfg0); +	if (gd->arch.tbu == 0) { +		/* +		 * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 +		 * (default) and prescaler = 16. Should be 10390 +		 * @33.25MHz and 15625 @ 50 MHz +		 */ +		gd->arch.tbu = get_PCLK() / (2 * 16 * 100); +		gd->arch.timer_rate_hz = get_PCLK() / (2 * 16); +	} +	/* load value for 10 ms timeout */ +	writel(gd->arch.tbu, &timers->tcntb4); +	/* auto load, manual update of timer 4 */ +	tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000; +	writel(tmr, &timers->tcon); +	/* auto load, start timer 4 */ +	tmr = (tmr & ~0x0700000) | 0x0500000; +	writel(tmr, &timers->tcon); +	gd->arch.lastinc = 0; +	gd->arch.tbl = 0; + +	return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer(ulong base) +{ +	return get_timer_masked() - base; +} + +void __udelay (unsigned long usec) +{ +	ulong tmo; +	ulong start = get_ticks(); + +	tmo = usec / 1000; +	tmo *= (gd->arch.tbu * 100); +	tmo /= 1000; + +	while ((ulong) (get_ticks() - start) < tmo) +		/*NOP*/; +} + +ulong get_timer_masked(void) +{ +	ulong tmr = get_ticks(); + +	return tmr / (gd->arch.timer_rate_hz / CONFIG_SYS_HZ); +} + +void udelay_masked(unsigned long usec) +{ +	ulong tmo; +	ulong endtime; +	signed long diff; + +	if (usec >= 1000) { +		tmo = usec / 1000; +		tmo *= (gd->arch.tbu * 100); +		tmo /= 1000; +	} else { +		tmo = usec * (gd->arch.tbu * 100); +		tmo /= (1000 * 1000); +	} + +	endtime = get_ticks() + tmo; + +	do { +		ulong now = get_ticks(); +		diff = endtime - now; +	} while (diff >= 0); +} + +/* + * 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) +{ +	struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); +	ulong now = readl(&timers->tcnto4) & 0xffff; + +	if (gd->arch.lastinc >= now) { +		/* normal mode */ +		gd->arch.tbl += gd->arch.lastinc - now; +	} else { +		/* we have an overflow ... */ +		gd->arch.tbl += gd->arch.lastinc + gd->arch.tbu - now; +	} +	gd->arch.lastinc = now; + +	return gd->arch.tbl; +} + +/* + * 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) +{ +	return CONFIG_SYS_HZ; +} + +/* + * reset the cpu by setting up the watchdog timer and let him time out + */ +void reset_cpu(ulong ignored) +{ +	struct s3c24x0_watchdog *watchdog; + +	watchdog = s3c24x0_get_base_watchdog(); + +	/* Disable watchdog */ +	writel(0x0000, &watchdog->wtcon); + +	/* Initialize watchdog timer count register */ +	writel(0x0001, &watchdog->wtcnt); + +	/* Enable watchdog timer; assert reset at timer timeout */ +	writel(0x0021, &watchdog->wtcon); + +	while (1) +		/* loop forever and wait for reset to happen */; + +	/*NOTREACHED*/ +} + +#endif /* CONFIG_S3C24X0 */ diff --git a/roms/u-boot/arch/arm/cpu/arm920t/start.S b/roms/u-boot/arch/arm/cpu/arm920t/start.S new file mode 100644 index 00000000..7bf094ae --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/arm920t/start.S @@ -0,0 +1,361 @@ +/* + *  armboot - Startup Code for ARM920 CPU-core + * + *  Copyright (c) 2001	Marius Gröger <mag@sysgo.de> + *  Copyright (c) 2002	Alex Züpke <azu@sysgo.de> + *  Copyright (c) 2002	Gary Jennejohn <garyj@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <common.h> +#include <config.h> + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start:	b	start_code +	ldr	pc, _undefined_instruction +	ldr	pc, _software_interrupt +	ldr	pc, _prefetch_abort +	ldr	pc, _data_abort +	ldr	pc, _not_used +	ldr	pc, _irq +	ldr	pc, _fiq + +_undefined_instruction:	.word undefined_instruction +_software_interrupt:	.word software_interrupt +_prefetch_abort:	.word prefetch_abort +_data_abort:		.word data_abort +_not_used:		.word not_used +_irq:			.word irq +_fiq:			.word fiq + +	.balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (called from the ARM reset exception vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +#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 actual start code + */ + +start_code: +	/* +	 * set the cpu to SVC32 mode +	 */ +	mrs	r0, cpsr +	bic	r0, r0, #0x1f +	orr	r0, r0, #0xd3 +	msr	cpsr, r0 + +#if	defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) +	/* +	 * relocate exception table +	 */ +	ldr	r0, =_start +	ldr	r1, =0x0 +	mov	r2, #16 +copyex: +	subs	r2, r2, #1 +	ldr	r3, [r0], #4 +	str	r3, [r1], #4 +	bne	copyex +#endif + +#ifdef CONFIG_S3C24X0 +	/* turn off the watchdog */ + +# if defined(CONFIG_S3C2400) +#  define pWTCON	0x15300000 +#  define INTMSK	0x14400008	/* Interrupt-Controller base addresses */ +#  define CLKDIVN	0x14800014	/* clock divisor register */ +#else +#  define pWTCON	0x53000000 +#  define INTMSK	0x4A000008	/* Interrupt-Controller base addresses */ +#  define INTSUBMSK	0x4A00001C +#  define CLKDIVN	0x4C000014	/* clock divisor register */ +# endif + +	ldr	r0, =pWTCON +	mov	r1, #0x0 +	str	r1, [r0] + +	/* +	 * mask all IRQs by setting all bits in the INTMR - default +	 */ +	mov	r1, #0xffffffff +	ldr	r0, =INTMSK +	str	r1, [r0] +# if defined(CONFIG_S3C2410) +	ldr	r1, =0x3ff +	ldr	r0, =INTSUBMSK +	str	r1, [r0] +# endif + +	/* FCLK:HCLK:PCLK = 1:2:4 */ +	/* default FCLK is 120 MHz ! */ +	ldr	r0, =CLKDIVN +	mov	r1, #3 +	str	r1, [r0] +#endif	/* CONFIG_S3C24X0 */ + +	/* +	 * we do sys-critical inits only at reboot, +	 * not when booting from ram! +	 */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +	bl	cpu_init_crit +#endif + +	bl	_main + +/*------------------------------------------------------------------------------*/ + +	.globl	c_runtime_cpu_setup +c_runtime_cpu_setup: + +	mov	pc, lr + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: +	/* +	 * flush v4 I/D caches +	 */ +	mov	r0, #0 +	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */ +	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */ + +	/* +	 * disable MMU stuff and caches +	 */ +	mrc	p15, 0, r0, c1, c0, 0 +	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS) +	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM) +	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align +	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache +	mcr	p15, 0, r0, c1, c0, 0 + +	/* +	 * before relocating, we have to setup RAM timing +	 * because memory timing is board-dependend, you will +	 * find a lowlevel_init.S in your board directory. +	 */ +	mov	ip, lr + +	bl	lowlevel_init + +	mov	lr, ip +	mov	pc, lr +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE	72 + +#define S_OLD_R0	68 +#define S_PSR		64 +#define S_PC		60 +#define S_LR		56 +#define S_SP		52 + +#define S_IP		48 +#define S_FP		44 +#define S_R10		40 +#define S_R9		36 +#define S_R8		32 +#define S_R7		28 +#define S_R6		24 +#define S_R5		20 +#define S_R4		16 +#define S_R3		12 +#define S_R2		8 +#define S_R1		4 +#define S_R0		0 + +#define MODE_SVC	0x13 +#define I_BIT		0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + +	.macro	bad_save_user_regs +	sub	sp, sp, #S_FRAME_SIZE +	stmia	sp, {r0 - r12}			@ Calling r0-r12 +	ldr	r2, IRQ_STACK_START_IN +	ldmia	r2, {r2 - r3}			@ get pc, cpsr +	add	r0, sp, #S_FRAME_SIZE		@ restore sp_SVC + +	add	r5, sp, #S_SP +	mov	r1, lr +	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr +	mov	r0, sp +	.endm + +	.macro	irq_save_user_regs +	sub	sp, sp, #S_FRAME_SIZE +	stmia	sp, {r0 - r12}			@ Calling r0-r12 +	add	r7, sp, #S_PC +	stmdb	r7, {sp, lr}^			@ Calling SP, LR +	str	lr, [r7, #0]			@ Save calling PC +	mrs	r6, spsr +	str	r6, [r7, #4]			@ Save CPSR +	str	r0, [r7, #8]			@ Save OLD_R0 +	mov	r0, sp +	.endm + +	.macro	irq_restore_user_regs +	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr +	mov	r0, r0 +	ldr	lr, [sp, #S_PC]			@ Get PC +	add	sp, sp, #S_FRAME_SIZE +	/* return & move spsr_svc into cpsr */ +	subs	pc, lr, #4 +	.endm + +	.macro get_bad_stack +	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack + +	str	lr, [r13]			@ save caller lr / spsr +	mrs	lr, spsr +	str	lr, [r13, #4] + +	mov	r13, #MODE_SVC			@ prepare SVC-Mode +	@ msr	spsr_c, r13 +	msr	spsr, r13 +	mov	lr, pc +	movs	pc, lr +	.endm + +	.macro get_irq_stack			@ setup IRQ stack +	ldr	sp, IRQ_STACK_START +	.endm + +	.macro get_fiq_stack			@ setup FIQ stack +	ldr	sp, FIQ_STACK_START +	.endm + +/* + * exception handlers + */ +	.align  5 +undefined_instruction: +	get_bad_stack +	bad_save_user_regs +	bl	do_undefined_instruction + +	.align	5 +software_interrupt: +	get_bad_stack +	bad_save_user_regs +	bl	do_software_interrupt + +	.align	5 +prefetch_abort: +	get_bad_stack +	bad_save_user_regs +	bl	do_prefetch_abort + +	.align	5 +data_abort: +	get_bad_stack +	bad_save_user_regs +	bl	do_data_abort + +	.align	5 +not_used: +	get_bad_stack +	bad_save_user_regs +	bl	do_not_used + +#ifdef CONFIG_USE_IRQ + +	.align	5 +irq: +	get_irq_stack +	irq_save_user_regs +	bl	do_irq +	irq_restore_user_regs + +	.align	5 +fiq: +	get_fiq_stack +	/* someone ought to write a more effiction fiq_save_user_regs */ +	irq_save_user_regs +	bl	do_fiq +	irq_restore_user_regs + +#else + +	.align	5 +irq: +	get_bad_stack +	bad_save_user_regs +	bl	do_irq + +	.align	5 +fiq: +	get_bad_stack +	bad_save_user_regs +	bl	do_fiq + +#endif  | 
