diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/u-boot/arch/arm/cpu/arm920t/ep93xx | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/arch/arm/cpu/arm920t/ep93xx')
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm920t/ep93xx/Makefile | 21 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm920t/ep93xx/cpu.c | 37 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm920t/ep93xx/led.c | 85 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S | 49 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm920t/ep93xx/speed.c | 96 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c | 120 | ||||
| -rw-r--r-- | roms/u-boot/arch/arm/cpu/arm920t/ep93xx/u-boot.lds | 57 | 
7 files changed, 465 insertions, 0 deletions
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) +	} +}  | 
