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/avr32/cpu | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/arch/avr32/cpu')
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/Makefile | 18 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/at32ap700x/Makefile | 7 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/at32ap700x/clk.c | 82 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/at32ap700x/mmu.c | 78 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/at32ap700x/portmux.c | 278 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/at32ap700x/sm.h | 204 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/cache.c | 81 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/config.mk | 6 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/cpu.c | 73 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/exception.c | 106 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/hsdramc.c | 101 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/hsdramc1.h | 143 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/hsmc3.h | 126 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/interrupts.c | 112 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/portmux-gpio.c | 91 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/portmux-pio.c | 76 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/start.S | 268 | ||||
| -rw-r--r-- | roms/u-boot/arch/avr32/cpu/u-boot.lds | 56 | 
18 files changed, 1906 insertions, 0 deletions
diff --git a/roms/u-boot/arch/avr32/cpu/Makefile b/roms/u-boot/arch/avr32/cpu/Makefile new file mode 100644 index 00000000..5e117212 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/Makefile @@ -0,0 +1,18 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2005-2006 Atmel Corporation. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +extra-y			+= start.o + +obj-y			+= cpu.o +obj-$(CONFIG_SYS_HSDRAMC) += hsdramc.o +obj-y			+= exception.o +obj-y			+= cache.o +obj-y			+= interrupts.o +obj-$(CONFIG_PORTMUX_PIO) += portmux-pio.o +obj-$(CONFIG_PORTMUX_GPIO) += portmux-gpio.o diff --git a/roms/u-boot/arch/avr32/cpu/at32ap700x/Makefile b/roms/u-boot/arch/avr32/cpu/at32ap700x/Makefile new file mode 100644 index 00000000..06f18963 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/at32ap700x/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2005-2006 Atmel Corporation +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	:= portmux.o clk.o mmu.o diff --git a/roms/u-boot/arch/avr32/cpu/at32ap700x/clk.c b/roms/u-boot/arch/avr32/cpu/at32ap700x/clk.c new file mode 100644 index 00000000..d5dbe3b9 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/at32ap700x/clk.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2005-2008 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> + +#include <asm/io.h> + +#include <asm/arch/clk.h> +#include <asm/arch/hardware.h> +#include <asm/arch/portmux.h> + +#include "sm.h" + +void clk_init(void) +{ +	uint32_t cksel; + +	/* in case of soft resets, disable watchdog */ +	sm_writel(WDT_CTRL, SM_BF(KEY, 0x55)); +	sm_writel(WDT_CTRL, SM_BF(KEY, 0xaa)); + +#ifdef CONFIG_PLL +	/* Initialize the PLL */ +	sm_writel(PM_PLL0, (SM_BF(PLLCOUNT, CONFIG_SYS_PLL0_SUPPRESS_CYCLES) +			    | SM_BF(PLLMUL, CONFIG_SYS_PLL0_MUL - 1) +			    | SM_BF(PLLDIV, CONFIG_SYS_PLL0_DIV - 1) +			    | SM_BF(PLLOPT, CONFIG_SYS_PLL0_OPT) +			    | SM_BF(PLLOSC, 0) +			    | SM_BIT(PLLEN))); + +	/* Wait for lock */ +	while (!(sm_readl(PM_ISR) & SM_BIT(LOCK0))) ; +#endif + +	/* Set up clocks for the CPU and all peripheral buses */ +	cksel = 0; +	if (CONFIG_SYS_CLKDIV_CPU) +		cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CONFIG_SYS_CLKDIV_CPU - 1); +	if (CONFIG_SYS_CLKDIV_HSB) +		cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CONFIG_SYS_CLKDIV_HSB - 1); +	if (CONFIG_SYS_CLKDIV_PBA) +		cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CONFIG_SYS_CLKDIV_PBA - 1); +	if (CONFIG_SYS_CLKDIV_PBB) +		cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CONFIG_SYS_CLKDIV_PBB - 1); +	sm_writel(PM_CKSEL, cksel); + +#ifdef CONFIG_PLL +	/* Use PLL0 as main clock */ +	sm_writel(PM_MCCTRL, SM_BIT(PLLSEL)); + +#ifdef CONFIG_LCD +	/* Set up pixel clock for the LCDC */ +	sm_writel(PM_GCCTRL(7), SM_BIT(PLLSEL) | SM_BIT(CEN)); +#endif +#endif +} + +unsigned long __gclk_set_rate(unsigned int id, enum gclk_parent parent, +		unsigned long rate, unsigned long parent_rate) +{ +	unsigned long divider; + +	if (rate == 0 || parent_rate == 0) { +		sm_writel(PM_GCCTRL(id), 0); +		return 0; +	} + +	divider = (parent_rate + rate / 2) / rate; +	if (divider <= 1) { +		sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN)); +		rate = parent_rate; +	} else { +		divider = min(255, divider / 2 - 1); +		sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN) | SM_BIT(DIVEN) +				| SM_BF(DIV, divider)); +		rate = parent_rate / (2 * (divider + 1)); +	} + +	return rate; +} diff --git a/roms/u-boot/arch/avr32/cpu/at32ap700x/mmu.c b/roms/u-boot/arch/avr32/cpu/at32ap700x/mmu.c new file mode 100644 index 00000000..0e28b21e --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/at32ap700x/mmu.c @@ -0,0 +1,78 @@ +#include <common.h> +#include <asm/arch/mmu.h> +#include <asm/sysreg.h> + +void mmu_init_r(unsigned long dest_addr) +{ +	uintptr_t	vmr_table_addr; + +	/* Round monitor address down to the nearest page boundary */ +	dest_addr &= PAGE_ADDR_MASK; + +	/* Initialize TLB entry 0 to cover the monitor, and lock it */ +	sysreg_write(TLBEHI, dest_addr | SYSREG_BIT(TLBEHI_V)); +	sysreg_write(TLBELO, dest_addr | MMU_VMR_CACHE_WRBACK); +	sysreg_write(MMUCR, SYSREG_BF(DRP, 0) | SYSREG_BF(DLA, 1) +			| SYSREG_BIT(MMUCR_S) | SYSREG_BIT(M)); +	__builtin_tlbw(); + +	/* +	 * Calculate the address of the VM range table in a PC-relative +	 * manner to make sure we hit the SDRAM and not the flash. +	 */ +	vmr_table_addr = (uintptr_t)&mmu_vmr_table; +	sysreg_write(PTBR, vmr_table_addr); +	printf("VMR table @ 0x%08lx\n", vmr_table_addr); + +	/* Enable paging */ +	sysreg_write(MMUCR, SYSREG_BF(DRP, 1) | SYSREG_BF(DLA, 1) +			| SYSREG_BIT(MMUCR_S) | SYSREG_BIT(M) | SYSREG_BIT(E)); +} + +int mmu_handle_tlb_miss(void) +{ +	const struct mmu_vm_range *vmr_table; +	const struct mmu_vm_range *vmr; +	unsigned int fault_pgno; +	int first, last; + +	fault_pgno = sysreg_read(TLBEAR) >> PAGE_SHIFT; +	vmr_table = (const struct mmu_vm_range *)sysreg_read(PTBR); + +	/* Do a binary search through the VM ranges */ +	first = 0; +	last = CONFIG_SYS_NR_VM_REGIONS; +	while (first < last) { +		unsigned int start; +		int middle; + +		/* Pick the entry in the middle of the remaining range */ +		middle = (first + last) >> 1; +		vmr = &vmr_table[middle]; +		start = vmr->virt_pgno; + +		/* Do the bisection thing */ +		if (fault_pgno < start) { +			last = middle; +		} else if (fault_pgno >= (start + vmr->nr_pages)) { +			first = middle + 1; +		} else { +			/* Got it; let's slam it into the TLB */ +			uint32_t tlbelo; + +			tlbelo = vmr->phys & ~PAGE_ADDR_MASK; +			tlbelo |= fault_pgno << PAGE_SHIFT; +			sysreg_write(TLBELO, tlbelo); +			__builtin_tlbw(); + +			/* Zero means success */ +			return 0; +		} +	} + +	/* +	 * Didn't find any matching entries. Return a nonzero value to +	 * indicate that this should be treated as a fatal exception. +	 */ +	return -1; +} diff --git a/roms/u-boot/arch/avr32/cpu/at32ap700x/portmux.c b/roms/u-boot/arch/avr32/cpu/at32ap700x/portmux.c new file mode 100644 index 00000000..58327bac --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/at32ap700x/portmux.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2006, 2008 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> + +#include <asm/io.h> + +#include <asm/arch/chip-features.h> +#include <asm/arch/hardware.h> +#include <asm/arch/portmux.h> + +/* + * Lots of small functions here. We depend on --gc-sections getting + * rid of the ones we don't need. + */ +void portmux_enable_ebi(unsigned int bus_width, unsigned int addr_width, +		unsigned long flags, unsigned long drive_strength) +{ +	unsigned long porte_mask = 0; + +	if (bus_width > 16) +		portmux_select_peripheral(PORTMUX_PORT_E, 0xffff, +				PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); +	if (addr_width > 23) +		porte_mask |= (((1 << (addr_width - 23)) - 1) & 7) << 16; +	if (flags & PORTMUX_EBI_CS(2)) +		porte_mask |= 1 << 25; +	if (flags & PORTMUX_EBI_CS(4)) +		porte_mask |= 1 << 21; +	if (flags & PORTMUX_EBI_CS(5)) +		porte_mask |= 1 << 22; +	if (flags & (PORTMUX_EBI_CF(0) | PORTMUX_EBI_CF(1))) +		porte_mask |= (1 << 19) | (1 << 20) | (1 << 23); + +	portmux_select_peripheral(PORTMUX_PORT_E, porte_mask, +			PORTMUX_FUNC_A, 0); + +	if (flags & PORTMUX_EBI_NWAIT) +		portmux_select_peripheral(PORTMUX_PORT_E, 1 << 24, +				PORTMUX_FUNC_A, PORTMUX_PULL_UP); +} + +#ifdef AT32AP700x_CHIP_HAS_MACB +void portmux_enable_macb0(unsigned long flags, unsigned long drive_strength) +{ +	unsigned long portc_mask; + +	portc_mask = (1 << 3)	/* TXD0	*/ +		| (1 << 4)	/* TXD1	*/ +		| (1 << 7)	/* TXEN	*/ +		| (1 << 8)	/* TXCK */ +		| (1 << 9)	/* RXD0	*/ +		| (1 << 10)	/* RXD1	*/ +		| (1 << 13)	/* RXER	*/ +		| (1 << 15)	/* RXDV	*/ +		| (1 << 16)	/* MDC	*/ +		| (1 << 17);	/* MDIO	*/ + +	if (flags & PORTMUX_MACB_MII) +		portc_mask |= (1 << 0)	/* COL	*/ +			| (1 << 1)	/* CRS	*/ +			| (1 << 2)	/* TXER	*/ +			| (1 << 5)	/* TXD2	*/ +			| (1 << 6)	/* TXD3 */ +			| (1 << 11)	/* RXD2	*/ +			| (1 << 12)	/* RXD3	*/ +			| (1 << 14);	/* RXCK	*/ + +	if (flags & PORTMUX_MACB_SPEED) +		portc_mask |= (1 << 18);/* SPD	*/ + +	/* REVISIT: Some pins are probably pure outputs */ +	portmux_select_peripheral(PORTMUX_PORT_C, portc_mask, +			PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); +} + +void portmux_enable_macb1(unsigned long flags, unsigned long drive_strength) +{ +	unsigned long portc_mask = 0; +	unsigned long portd_mask; + +	portd_mask = (1 << 13)	/* TXD0	*/ +		| (1 << 14)	/* TXD1	*/ +		| (1 << 11)	/* TXEN	*/ +		| (1 << 12)	/* TXCK */ +		| (1 << 10)	/* RXD0	*/ +		| (1 << 6)	/* RXD1	*/ +		| (1 << 5)	/* RXER	*/ +		| (1 << 4)	/* RXDV	*/ +		| (1 << 3)	/* MDC	*/ +		| (1 << 2);	/* MDIO	*/ + +	if (flags & PORTMUX_MACB_MII) +		portc_mask = (1 << 19)	/* COL	*/ +			| (1 << 23)	/* CRS	*/ +			| (1 << 26)	/* TXER	*/ +			| (1 << 27)	/* TXD2	*/ +			| (1 << 28)	/* TXD3 */ +			| (1 << 29)	/* RXD2	*/ +			| (1 << 30)	/* RXD3	*/ +			| (1 << 24);	/* RXCK	*/ + +	if (flags & PORTMUX_MACB_SPEED) +		portd_mask |= (1 << 15);/* SPD	*/ + +	/* REVISIT: Some pins are probably pure outputs */ +	portmux_select_peripheral(PORTMUX_PORT_D, portd_mask, +			PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); +	portmux_select_peripheral(PORTMUX_PORT_C, portc_mask, +			PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); +} +#endif + +#ifdef AT32AP700x_CHIP_HAS_MMCI +void portmux_enable_mmci(unsigned int slot, unsigned long flags, +		unsigned long drive_strength) +{ +	unsigned long mask; +	unsigned long portmux_flags = PORTMUX_PULL_UP; + +	/* First, the common CLK signal. It doesn't need a pull-up */ +	portmux_select_peripheral(PORTMUX_PORT_A, 1 << 10, +			PORTMUX_FUNC_A, 0); + +	if (flags & PORTMUX_MMCI_EXT_PULLUP) +		portmux_flags = 0; + +	/* Then, the per-slot signals */ +	switch (slot) { +	case 0: +		mask = (1 << 11) | (1 << 12);	/* CMD and DATA0 */ +		if (flags & PORTMUX_MMCI_4BIT) +			/* DATA1..DATA3 */ +			mask |= (1 << 13) | (1 << 14) | (1 << 15); +		portmux_select_peripheral(PORTMUX_PORT_A, mask, +				PORTMUX_FUNC_A, portmux_flags); +		break; +	case 1: +		mask = (1 << 6) | (1 << 7);	/* CMD and DATA0 */ +		if (flags & PORTMUX_MMCI_4BIT) +			/* DATA1..DATA3 */ +			mask |= (1 << 8) | (1 << 9) | (1 << 10); +		portmux_select_peripheral(PORTMUX_PORT_B, mask, +				PORTMUX_FUNC_B, portmux_flags); +		break; +	} +} +#endif + +#ifdef AT32AP700x_CHIP_HAS_SPI +void portmux_enable_spi0(unsigned long cs_mask, unsigned long drive_strength) +{ +	unsigned long pin_mask; + +	/* MOSI and SCK */ +	portmux_select_peripheral(PORTMUX_PORT_A, (1 << 1) | (1 << 2), +			PORTMUX_FUNC_A, 0); +	/* MISO may float */ +	portmux_select_peripheral(PORTMUX_PORT_A, 1 << 0, +			PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); + +	/* Set up NPCSx as GPIO outputs, initially high */ +	pin_mask = (cs_mask & 7) << 3; +	if (cs_mask & (1 << 3)) +		pin_mask |= 1 << 20; + +	portmux_select_gpio(PORTMUX_PORT_A, pin_mask, +			PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH); +} + +void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength) +{ +	/* MOSI and SCK */ +	portmux_select_peripheral(PORTMUX_PORT_B, (1 << 1) | (1 << 5), +			PORTMUX_FUNC_B, 0); +	/* MISO may float */ +	portmux_select_peripheral(PORTMUX_PORT_B, 1 << 0, +			PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); + +	/* Set up NPCSx as GPIO outputs, initially high */ +	portmux_select_gpio(PORTMUX_PORT_B, (cs_mask & 7) << 2, +			PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH); +	portmux_select_gpio(PORTMUX_PORT_A, (cs_mask & 8) << (27 - 3), +			PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH); +} +#endif + +#ifdef AT32AP700x_CHIP_HAS_LCDC +void portmux_enable_lcdc(int pin_config) +{ +	unsigned long portc_mask = 0; +	unsigned long portd_mask = 0; +	unsigned long porte_mask = 0; + +	switch (pin_config) { +	case 0: +		portc_mask = (1 << 19)	/* CC     */ +			| (1 << 20)	/* HSYNC  */ +			| (1 << 21)	/* PCLK   */ +			| (1 << 22)	/* VSYNC  */ +			| (1 << 23)	/* DVAL   */ +			| (1 << 24)	/* MODE   */ +			| (1 << 25)	/* PWR    */ +			| (1 << 26)	/* DATA0  */ +			| (1 << 27)	/* DATA1  */ +			| (1 << 28)	/* DATA2  */ +			| (1 << 29)	/* DATA3  */ +			| (1 << 30)	/* DATA4  */ +			| (1 << 31);	/* DATA5  */ + +		portd_mask = (1 << 0)	/* DATA6  */ +			| (1 << 1)	/* DATA7  */ +			| (1 << 2)	/* DATA8  */ +			| (1 << 3)	/* DATA9  */ +			| (1 << 4)	/* DATA10 */ +			| (1 << 5)	/* DATA11 */ +			| (1 << 6)	/* DATA12 */ +			| (1 << 7)	/* DATA13 */ +			| (1 << 8)	/* DATA14 */ +			| (1 << 9)	/* DATA15 */ +			| (1 << 10)	/* DATA16 */ +			| (1 << 11)	/* DATA17 */ +			| (1 << 12)	/* DATA18 */ +			| (1 << 13)	/* DATA19 */ +			| (1 << 14)	/* DATA20 */ +			| (1 << 15)	/* DATA21 */ +			| (1 << 16)	/* DATA22 */ +			| (1 << 17);	/* DATA23 */ +		break; + +	case 1: +		portc_mask = (1 << 20)	/* HSYNC  */ +			| (1 << 21)	/* PCLK   */ +			| (1 << 22)	/* VSYNC  */ +			| (1 << 25)	/* PWR    */ +			| (1 << 31);	/* DATA5  */ + +		portd_mask = (1 << 0)	/* DATA6  */ +			| (1 << 1)	/* DATA7  */ +			| (1 << 7)	/* DATA13 */ +			| (1 << 8)	/* DATA14 */ +			| (1 << 9)	/* DATA15 */ +			| (1 << 16)	/* DATA22 */ +			| (1 << 17);	/* DATA23 */ + +		porte_mask = (1 << 0)	/* CC     */ +			| (1 << 1)	/* DVAL   */ +			| (1 << 2)	/* MODE   */ +			| (1 << 3)	/* DATA0  */ +			| (1 << 4)	/* DATA1  */ +			| (1 << 5)	/* DATA2  */ +			| (1 << 6)	/* DATA3  */ +			| (1 << 7)	/* DATA4  */ +			| (1 << 8)	/* DATA8  */ +			| (1 << 9)	/* DATA9  */ +			| (1 << 10)	/* DATA10 */ +			| (1 << 11)	/* DATA11 */ +			| (1 << 12)	/* DATA12 */ +			| (1 << 13)	/* DATA16 */ +			| (1 << 14)	/* DATA17 */ +			| (1 << 15)	/* DATA18 */ +			| (1 << 16)	/* DATA19 */ +			| (1 << 17)	/* DATA20 */ +			| (1 << 18);	/* DATA21 */ +		break; +	} + +	/* REVISIT: Some pins are probably pure outputs */ +	portmux_select_peripheral(PORTMUX_PORT_C, portc_mask, +			PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); +	portmux_select_peripheral(PORTMUX_PORT_D, portd_mask, +			PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); +	portmux_select_peripheral(PORTMUX_PORT_E, porte_mask, +			PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); +} +#endif diff --git a/roms/u-boot/arch/avr32/cpu/at32ap700x/sm.h b/roms/u-boot/arch/avr32/cpu/at32ap700x/sm.h new file mode 100644 index 00000000..9a3804ef --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/at32ap700x/sm.h @@ -0,0 +1,204 @@ +/* + * Register definitions for System Manager + */ +#ifndef __CPU_AT32AP_SM_H__ +#define __CPU_AT32AP_SM_H__ + +/* SM register offsets */ +#define SM_PM_MCCTRL				0x0000 +#define SM_PM_CKSEL				0x0004 +#define SM_PM_CPU_MASK				0x0008 +#define SM_PM_HSB_MASK				0x000c +#define SM_PM_PBA_MASK				0x0010 +#define SM_PM_PBB_MASK				0x0014 +#define SM_PM_PLL0				0x0020 +#define SM_PM_PLL1				0x0024 +#define SM_PM_VCTRL				0x0030 +#define SM_PM_VMREF				0x0034 +#define SM_PM_VMV				0x0038 +#define SM_PM_IER				0x0040 +#define SM_PM_IDR				0x0044 +#define SM_PM_IMR				0x0048 +#define SM_PM_ISR				0x004c +#define SM_PM_ICR				0x0050 +#define SM_PM_GCCTRL(x)				(0x0060 + 4 * x) +#define SM_RTC_CTRL				0x0080 +#define SM_RTC_VAL				0x0084 +#define SM_RTC_TOP				0x0088 +#define SM_RTC_IER				0x0090 +#define SM_RTC_IDR				0x0094 +#define SM_RTC_IMR				0x0098 +#define SM_RTC_ISR				0x009c +#define SM_RTC_ICR				0x00a0 +#define SM_WDT_CTRL				0x00b0 +#define SM_WDT_CLR				0x00b4 +#define SM_WDT_EXT				0x00b8 +#define SM_RC_RCAUSE				0x00c0 +#define SM_EIM_IER				0x0100 +#define SM_EIM_IDR				0x0104 +#define SM_EIM_IMR				0x0108 +#define SM_EIM_ISR				0x010c +#define SM_EIM_ICR				0x0110 +#define SM_EIM_MODE				0x0114 +#define SM_EIM_EDGE				0x0118 +#define SM_EIM_LEVEL				0x011c +#define SM_EIM_TEST				0x0120 +#define SM_EIM_NMIC				0x0124 + +/* Bitfields in PM_CKSEL */ +#define SM_CPUSEL_OFFSET			0 +#define SM_CPUSEL_SIZE				3 +#define SM_CPUDIV_OFFSET			7 +#define SM_CPUDIV_SIZE				1 +#define SM_HSBSEL_OFFSET			8 +#define SM_HSBSEL_SIZE				3 +#define SM_HSBDIV_OFFSET			15 +#define SM_HSBDIV_SIZE				1 +#define SM_PBASEL_OFFSET			16 +#define SM_PBASEL_SIZE				3 +#define SM_PBADIV_OFFSET			23 +#define SM_PBADIV_SIZE				1 +#define SM_PBBSEL_OFFSET			24 +#define SM_PBBSEL_SIZE				3 +#define SM_PBBDIV_OFFSET			31 +#define SM_PBBDIV_SIZE				1 + +/* Bitfields in PM_PLL0 */ +#define SM_PLLEN_OFFSET				0 +#define SM_PLLEN_SIZE				1 +#define SM_PLLOSC_OFFSET			1 +#define SM_PLLOSC_SIZE				1 +#define SM_PLLOPT_OFFSET			2 +#define SM_PLLOPT_SIZE				3 +#define SM_PLLDIV_OFFSET			8 +#define SM_PLLDIV_SIZE				8 +#define SM_PLLMUL_OFFSET			16 +#define SM_PLLMUL_SIZE				8 +#define SM_PLLCOUNT_OFFSET			24 +#define SM_PLLCOUNT_SIZE			6 +#define SM_PLLTEST_OFFSET			31 +#define SM_PLLTEST_SIZE				1 + +/* Bitfields in PM_VCTRL */ +#define SM_VAUTO_OFFSET				0 +#define SM_VAUTO_SIZE				1 +#define SM_PM_VCTRL_VAL_OFFSET			8 +#define SM_PM_VCTRL_VAL_SIZE			7 + +/* Bitfields in PM_VMREF */ +#define SM_REFSEL_OFFSET			0 +#define SM_REFSEL_SIZE				4 + +/* Bitfields in PM_VMV */ +#define SM_PM_VMV_VAL_OFFSET			0 +#define SM_PM_VMV_VAL_SIZE			8 + +/* Bitfields in PM_ICR */ +#define SM_LOCK0_OFFSET				0 +#define SM_LOCK0_SIZE				1 +#define SM_LOCK1_OFFSET				1 +#define SM_LOCK1_SIZE				1 +#define SM_WAKE_OFFSET				2 +#define SM_WAKE_SIZE				1 +#define SM_VOK_OFFSET				3 +#define SM_VOK_SIZE				1 +#define SM_VMRDY_OFFSET				4 +#define SM_VMRDY_SIZE				1 +#define SM_CKRDY_OFFSET				5 +#define SM_CKRDY_SIZE				1 + +/* Bitfields in PM_GCCTRL */ +#define SM_OSCSEL_OFFSET			0 +#define SM_OSCSEL_SIZE				1 +#define SM_PLLSEL_OFFSET			1 +#define SM_PLLSEL_SIZE				1 +#define SM_CEN_OFFSET				2 +#define SM_CEN_SIZE				1 +#define SM_CPC_OFFSET				3 +#define SM_CPC_SIZE				1 +#define SM_DIVEN_OFFSET				4 +#define SM_DIVEN_SIZE				1 +#define SM_DIV_OFFSET				8 +#define SM_DIV_SIZE				8 + +/* Bitfields in RTC_CTRL */ +#define SM_PCLR_OFFSET				1 +#define SM_PCLR_SIZE				1 +#define SM_TOPEN_OFFSET				2 +#define SM_TOPEN_SIZE				1 +#define SM_CLKEN_OFFSET				3 +#define SM_CLKEN_SIZE				1 +#define SM_PSEL_OFFSET				8 +#define SM_PSEL_SIZE				16 + +/* Bitfields in RTC_VAL */ +#define SM_RTC_VAL_VAL_OFFSET			0 +#define SM_RTC_VAL_VAL_SIZE			31 + +/* Bitfields in RTC_TOP */ +#define SM_RTC_TOP_VAL_OFFSET			0 +#define SM_RTC_TOP_VAL_SIZE			32 + +/* Bitfields in RTC_ICR */ +#define SM_TOPI_OFFSET				0 +#define SM_TOPI_SIZE				1 + +/* Bitfields in WDT_CTRL */ +#define SM_KEY_OFFSET				24 +#define SM_KEY_SIZE				8 + +/* Bitfields in RC_RCAUSE */ +#define SM_POR_OFFSET				0 +#define SM_POR_SIZE				1 +#define SM_BOD_OFFSET				1 +#define SM_BOD_SIZE				1 +#define SM_EXT_OFFSET				2 +#define SM_EXT_SIZE				1 +#define SM_WDT_OFFSET				3 +#define SM_WDT_SIZE				1 +#define SM_NTAE_OFFSET				4 +#define SM_NTAE_SIZE				1 +#define SM_SERP_OFFSET				5 +#define SM_SERP_SIZE				1 + +/* Bitfields in EIM_EDGE */ +#define SM_INT0_OFFSET				0 +#define SM_INT0_SIZE				1 +#define SM_INT1_OFFSET				1 +#define SM_INT1_SIZE				1 +#define SM_INT2_OFFSET				2 +#define SM_INT2_SIZE				1 +#define SM_INT3_OFFSET				3 +#define SM_INT3_SIZE				1 + +/* Bitfields in EIM_LEVEL */ + +/* Bitfields in EIM_TEST */ +#define SM_TESTEN_OFFSET			31 +#define SM_TESTEN_SIZE				1 + +/* Bitfields in EIM_NMIC */ +#define SM_EN_OFFSET				0 +#define SM_EN_SIZE				1 + +/* Bit manipulation macros */ +#define SM_BIT(name)					\ +	(1 << SM_##name##_OFFSET) +#define SM_BF(name,value)				\ +	(((value) & ((1 << SM_##name##_SIZE) - 1))	\ +	 << SM_##name##_OFFSET) +#define SM_BFEXT(name,value)				\ +	(((value) >> SM_##name##_OFFSET)		\ +	 & ((1 << SM_##name##_SIZE) - 1)) +#define SM_BFINS(name,value,old)			\ +	(((old) & ~(((1 << SM_##name##_SIZE) - 1)	\ +		    << SM_##name##_OFFSET))		\ +	 | SM_BF(name,value)) + +/* Register access macros */ +#define sm_readl(reg)					\ +	readl((void *)ATMEL_BASE_SM + SM_##reg) +#define sm_writel(reg,value)				\ +	writel((value), (void *)ATMEL_BASE_SM + SM_##reg) + +#endif /* __CPU_AT32AP_SM_H__ */ diff --git a/roms/u-boot/arch/avr32/cpu/cache.c b/roms/u-boot/arch/avr32/cpu/cache.c new file mode 100644 index 00000000..ab0374e5 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/cache.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +#include <asm/arch/cacheflush.h> + +void dcache_clean_range(volatile void *start, size_t size) +{ +	unsigned long v, begin, end, linesz; + +	linesz = CONFIG_SYS_DCACHE_LINESZ; + +	/* You asked for it, you got it */ +	begin = (unsigned long)start & ~(linesz - 1); +	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); + +	for (v = begin; v < end; v += linesz) +		dcache_clean_line((void *)v); + +	sync_write_buffer(); +} + +void dcache_invalidate_range(volatile void *start, size_t size) +{ +	unsigned long v, begin, end, linesz; + +	linesz = CONFIG_SYS_DCACHE_LINESZ; + +	/* You asked for it, you got it */ +	begin = (unsigned long)start & ~(linesz - 1); +	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); + +	for (v = begin; v < end; v += linesz) +		dcache_invalidate_line((void *)v); +} + +void dcache_flush_range(volatile void *start, size_t size) +{ +	unsigned long v, begin, end, linesz; + +	linesz = CONFIG_SYS_DCACHE_LINESZ; + +	/* You asked for it, you got it */ +	begin = (unsigned long)start & ~(linesz - 1); +	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); + +	for (v = begin; v < end; v += linesz) +		dcache_flush_line((void *)v); + +	sync_write_buffer(); +} + +void icache_invalidate_range(volatile void *start, size_t size) +{ +	unsigned long v, begin, end, linesz; + +	linesz = CONFIG_SYS_ICACHE_LINESZ; + +	/* You asked for it, you got it */ +	begin = (unsigned long)start & ~(linesz - 1); +	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); + +	for (v = begin; v < end; v += linesz) +		icache_invalidate_line((void *)v); +} + +/* + * This is called after loading something into memory.  We need to + * make sure that everything that was loaded is actually written to + * RAM, and that the icache will look for it. Cleaning the dcache and + * invalidating the icache will do the trick. + */ +void  flush_cache (unsigned long start_addr, unsigned long size) +{ +	dcache_clean_range((void *)start_addr, size); +	icache_invalidate_range((void *)start_addr, size); +} diff --git a/roms/u-boot/arch/avr32/cpu/config.mk b/roms/u-boot/arch/avr32/cpu/config.mk new file mode 100644 index 00000000..3d2d817f --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/config.mk @@ -0,0 +1,6 @@ +# +# Copyright (C) 2005-2006 Atmel Corporation +# +# SPDX-License-Identifier:	GPL-2.0+ +# +PLATFORM_RELFLAGS       += -mcpu=ap7000 diff --git a/roms/u-boot/arch/avr32/cpu/cpu.c b/roms/u-boot/arch/avr32/cpu/cpu.c new file mode 100644 index 00000000..cef630ed --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/cpu.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> +#include <command.h> + +#include <asm/io.h> +#include <asm/sections.h> +#include <asm/sysreg.h> + +#include <asm/arch/clk.h> +#include <asm/arch/hardware.h> + +#include "hsmc3.h" + +/* Sanity checks */ +#if (CONFIG_SYS_CLKDIV_CPU > CONFIG_SYS_CLKDIV_HSB)		\ +	|| (CONFIG_SYS_CLKDIV_HSB > CONFIG_SYS_CLKDIV_PBA)	\ +	|| (CONFIG_SYS_CLKDIV_HSB > CONFIG_SYS_CLKDIV_PBB) +# error Constraint fCPU >= fHSB >= fPB{A,B} violated +#endif +#if defined(CONFIG_PLL) && ((CONFIG_SYS_PLL0_MUL < 1) || (CONFIG_SYS_PLL0_DIV < 1)) +# error Invalid PLL multiplier and/or divider +#endif + +DECLARE_GLOBAL_DATA_PTR; + +int cpu_init(void) +{ +	extern void _evba(void); + +	gd->arch.cpu_hz = CONFIG_SYS_OSC0_HZ; + +	/* TODO: Move somewhere else, but needs to be run before we +	 * increase the clock frequency. */ +	hsmc3_writel(MODE0, 0x00031103); +	hsmc3_writel(CYCLE0, 0x000c000d); +	hsmc3_writel(PULSE0, 0x0b0a0906); +	hsmc3_writel(SETUP0, 0x00010002); + +	clk_init(); + +	/* Update the CPU speed according to the PLL configuration */ +	gd->arch.cpu_hz = get_cpu_clk_rate(); + +	/* Set up the exception handler table and enable exceptions */ +	sysreg_write(EVBA, (unsigned long)&_evba); +	asm volatile("csrf	%0" : : "i"(SYSREG_EM_OFFSET)); + +	return 0; +} + +void prepare_to_boot(void) +{ +	/* Flush both caches and the write buffer */ +	asm volatile("cache  %0[4], 010\n\t" +		     "cache  %0[0], 000\n\t" +		     "sync   0" : : "r"(0) : "memory"); +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	/* This will reset the CPU core, caches, MMU and all internal busses */ +	__builtin_mtdr(8, 1 << 13);	/* set DC:DBE */ +	__builtin_mtdr(8, 1 << 30);	/* set DC:RES */ + +	/* Flush the pipeline before we declare it a failure */ +	asm volatile("sub   pc, pc, -4"); + +	return -1; +} diff --git a/roms/u-boot/arch/avr32/cpu/exception.c b/roms/u-boot/arch/avr32/cpu/exception.c new file mode 100644 index 00000000..5d1bc689 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/exception.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> + +#include <asm/sysreg.h> +#include <asm/ptrace.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const char * const cpu_modes[8] = { +	"Application", "Supervisor", "Interrupt level 0", "Interrupt level 1", +	"Interrupt level 2", "Interrupt level 3", "Exception", "NMI" +}; + +static void dump_mem(const char *str, unsigned long bottom, unsigned long top) +{ +	unsigned long p; +	int i; + +	printf("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); + +	for (p = bottom & ~31; p < top; ) { +		printf("%04lx: ", p & 0xffff); + +		for (i = 0; i < 8; i++, p += 4) { +			unsigned int val; + +			if (p < bottom || p >= top) +				printf("         "); +			else { +				val = *(unsigned long *)p; +				printf("%08x ", val); +			} +		} +		printf("\n"); +	} +} + +void do_unknown_exception(unsigned int ecr, struct pt_regs *regs) +{ +	unsigned int mode; + +	printf("\n *** Unhandled exception %u at PC=0x%08lx [%08lx]\n", +			ecr, regs->pc, regs->pc - gd->reloc_off); + +	switch (ecr) { +	case ECR_BUS_ERROR_WRITE: +	case ECR_BUS_ERROR_READ: +		printf("Bus error at address 0x%08lx\n", +		       sysreg_read(BEAR)); +		break; +	case ECR_TLB_MULTIPLE: +	case ECR_ADDR_ALIGN_X: +	case ECR_PROTECTION_X: +	case ECR_ADDR_ALIGN_R: +	case ECR_ADDR_ALIGN_W: +	case ECR_PROTECTION_R: +	case ECR_PROTECTION_W: +	case ECR_DTLB_MODIFIED: +	case ECR_TLB_MISS_X: +	case ECR_TLB_MISS_R: +	case ECR_TLB_MISS_W: +		printf("MMU exception at address 0x%08lx\n", +		       sysreg_read(TLBEAR)); +		break; +	} + +	printf("   pc: %08lx    lr: %08lx    sp: %08lx   r12: %08lx\n", +	       regs->pc, regs->lr, regs->sp, regs->r12); +	printf("  r11: %08lx   r10: %08lx    r9: %08lx    r8: %08lx\n", +	       regs->r11, regs->r10, regs->r9, regs->r8); +	printf("   r7: %08lx    r6: %08lx    r5: %08lx    r4: %08lx\n", +	       regs->r7, regs->r6, regs->r5, regs->r4); +	printf("   r3: %08lx    r2: %08lx    r1: %08lx    r0: %08lx\n", +	       regs->r3, regs->r2, regs->r1, regs->r0); +	printf("Flags: %c%c%c%c%c\n", +	       regs->sr & SR_Q ? 'Q' : 'q', +	       regs->sr & SR_V ? 'V' : 'v', +	       regs->sr & SR_N ? 'N' : 'n', +	       regs->sr & SR_Z ? 'Z' : 'z', +	       regs->sr & SR_C ? 'C' : 'c'); +	printf("Mode bits: %c%c%c%c%c%c%c%c%c\n", +	       regs->sr & SR_H ? 'H' : 'h', +	       regs->sr & SR_R ? 'R' : 'r', +	       regs->sr & SR_J ? 'J' : 'j', +	       regs->sr & SR_EM ? 'E' : 'e', +	       regs->sr & SR_I3M ? '3' : '.', +	       regs->sr & SR_I2M ? '2' : '.', +	       regs->sr & SR_I1M ? '1' : '.', +	       regs->sr & SR_I0M ? '0' : '.', +	       regs->sr & SR_GM ? 'G' : 'g'); +	mode = (regs->sr >> SYSREG_M0_OFFSET) & 7; +	printf("CPU Mode: %s\n", cpu_modes[mode]); + +	/* Avoid exception loops */ +	if (regs->sp < (gd->arch.stack_end - CONFIG_STACKSIZE) +			|| regs->sp >= gd->arch.stack_end) +		printf("\nStack pointer seems bogus, won't do stack dump\n"); +	else +		dump_mem("\nStack: ", regs->sp, gd->arch.stack_end); + +	panic("Unhandled exception\n"); +} diff --git a/roms/u-boot/arch/avr32/cpu/hsdramc.c b/roms/u-boot/arch/avr32/cpu/hsdramc.c new file mode 100644 index 00000000..7e481720 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/hsdramc.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> + +#include <asm/io.h> +#include <asm/sdram.h> + +#include <asm/arch/clk.h> +#include <asm/arch/hardware.h> + +#include "hsdramc1.h" + +unsigned long sdram_init(void *sdram_base, const struct sdram_config *config) +{ +	unsigned long sdram_size; +	uint32_t cfgreg; +	unsigned int i; + +	cfgreg = (HSDRAMC1_BF(NC, config->col_bits - 8) +		       | HSDRAMC1_BF(NR, config->row_bits - 11) +		       | HSDRAMC1_BF(NB, config->bank_bits - 1) +		       | HSDRAMC1_BF(CAS, config->cas) +		       | HSDRAMC1_BF(TWR, config->twr) +		       | HSDRAMC1_BF(TRC, config->trc) +		       | HSDRAMC1_BF(TRP, config->trp) +		       | HSDRAMC1_BF(TRCD, config->trcd) +		       | HSDRAMC1_BF(TRAS, config->tras) +		       | HSDRAMC1_BF(TXSR, config->txsr)); + +	if (config->data_bits == SDRAM_DATA_16BIT) +		cfgreg |= HSDRAMC1_BIT(DBW); + +	hsdramc1_writel(CR, cfgreg); + +	/* Send a NOP to turn on the clock (necessary on some chips) */ +	hsdramc1_writel(MR, HSDRAMC1_MODE_NOP); +	hsdramc1_readl(MR); +	writel(0, sdram_base); + +	/* +	 * Initialization sequence for SDRAM, from the data sheet: +	 * +	 * 1. A minimum pause of 200 us is provided to precede any +	 *    signal toggle. +	 */ +	udelay(200); + +	/* +	 * 2. A Precharge All command is issued to the SDRAM +	 */ +	hsdramc1_writel(MR, HSDRAMC1_MODE_BANKS_PRECHARGE); +	hsdramc1_readl(MR); +	writel(0, sdram_base); + +	/* +	 * 3. Eight auto-refresh (CBR) cycles are provided +	 */ +	hsdramc1_writel(MR, HSDRAMC1_MODE_AUTO_REFRESH); +	hsdramc1_readl(MR); +	for (i = 0; i < 8; i++) +		writel(0, sdram_base); + +	/* +	 * 4. A mode register set (MRS) cycle is issued to program +	 *    SDRAM parameters, in particular CAS latency and burst +	 *    length. +	 * +	 * The address will be chosen by the SDRAMC automatically; we +	 * just have to make sure BA[1:0] are set to 0. +	 */ +	hsdramc1_writel(MR, HSDRAMC1_MODE_LOAD_MODE); +	hsdramc1_readl(MR); +	writel(0, sdram_base); + +	/* +	 * 5. The application must go into Normal Mode, setting Mode +	 *    to 0 in the Mode Register and performing a write access +	 *    at any location in the SDRAM. +	 */ +	hsdramc1_writel(MR, HSDRAMC1_MODE_NORMAL); +	hsdramc1_readl(MR); +	writel(0, sdram_base); + +	/* +	 * 6. Write refresh rate into SDRAMC refresh timer count +	 *    register (refresh rate = timing between refresh cycles). +	 */ +	hsdramc1_writel(TR, config->refresh_period); + +	if (config->data_bits == SDRAM_DATA_16BIT) +		sdram_size = 1 << (config->row_bits + config->col_bits +				   + config->bank_bits + 1); +	else +		sdram_size = 1 << (config->row_bits + config->col_bits +				   + config->bank_bits + 2); + +	return sdram_size; +} diff --git a/roms/u-boot/arch/avr32/cpu/hsdramc1.h b/roms/u-boot/arch/avr32/cpu/hsdramc1.h new file mode 100644 index 00000000..e18e074a --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/hsdramc1.h @@ -0,0 +1,143 @@ +/* + * Register definitions for SDRAM Controller + */ +#ifndef __ASM_AVR32_HSDRAMC1_H__ +#define __ASM_AVR32_HSDRAMC1_H__ + +/* HSDRAMC1 register offsets */ +#define HSDRAMC1_MR				0x0000 +#define HSDRAMC1_TR				0x0004 +#define HSDRAMC1_CR				0x0008 +#define HSDRAMC1_HSR				0x000c +#define HSDRAMC1_LPR				0x0010 +#define HSDRAMC1_IER				0x0014 +#define HSDRAMC1_IDR				0x0018 +#define HSDRAMC1_IMR				0x001c +#define HSDRAMC1_ISR				0x0020 +#define HSDRAMC1_MDR				0x0024 +#define HSDRAMC1_VERSION			0x00fc + +/* Bitfields in MR */ +#define HSDRAMC1_MODE_OFFSET			0 +#define HSDRAMC1_MODE_SIZE			3 + +/* Bitfields in TR */ +#define HSDRAMC1_COUNT_OFFSET			0 +#define HSDRAMC1_COUNT_SIZE			12 + +/* Bitfields in CR */ +#define HSDRAMC1_NC_OFFSET			0 +#define HSDRAMC1_NC_SIZE			2 +#define HSDRAMC1_NR_OFFSET			2 +#define HSDRAMC1_NR_SIZE			2 +#define HSDRAMC1_NB_OFFSET			4 +#define HSDRAMC1_NB_SIZE			1 +#define HSDRAMC1_CAS_OFFSET			5 +#define HSDRAMC1_CAS_SIZE			2 +#define HSDRAMC1_DBW_OFFSET			7 +#define HSDRAMC1_DBW_SIZE			1 +#define HSDRAMC1_TWR_OFFSET			8 +#define HSDRAMC1_TWR_SIZE			4 +#define HSDRAMC1_TRC_OFFSET			12 +#define HSDRAMC1_TRC_SIZE			4 +#define HSDRAMC1_TRP_OFFSET			16 +#define HSDRAMC1_TRP_SIZE			4 +#define HSDRAMC1_TRCD_OFFSET			20 +#define HSDRAMC1_TRCD_SIZE			4 +#define HSDRAMC1_TRAS_OFFSET			24 +#define HSDRAMC1_TRAS_SIZE			4 +#define HSDRAMC1_TXSR_OFFSET			28 +#define HSDRAMC1_TXSR_SIZE			4 + +/* Bitfields in HSR */ +#define HSDRAMC1_DA_OFFSET			0 +#define HSDRAMC1_DA_SIZE			1 + +/* Bitfields in LPR */ +#define HSDRAMC1_LPCB_OFFSET			0 +#define HSDRAMC1_LPCB_SIZE			2 +#define HSDRAMC1_PASR_OFFSET			4 +#define HSDRAMC1_PASR_SIZE			3 +#define HSDRAMC1_TCSR_OFFSET			8 +#define HSDRAMC1_TCSR_SIZE			2 +#define HSDRAMC1_DS_OFFSET			10 +#define HSDRAMC1_DS_SIZE			2 +#define HSDRAMC1_TIMEOUT_OFFSET			12 +#define HSDRAMC1_TIMEOUT_SIZE			2 + +/* Bitfields in IDR */ +#define HSDRAMC1_RES_OFFSET			0 +#define HSDRAMC1_RES_SIZE			1 + +/* Bitfields in MDR */ +#define HSDRAMC1_MD_OFFSET			0 +#define HSDRAMC1_MD_SIZE			2 + +/* Bitfields in VERSION */ +#define HSDRAMC1_VERSION_OFFSET			0 +#define HSDRAMC1_VERSION_SIZE			12 +#define HSDRAMC1_MFN_OFFSET			16 +#define HSDRAMC1_MFN_SIZE			3 + +/* Constants for MODE */ +#define HSDRAMC1_MODE_NORMAL			0 +#define HSDRAMC1_MODE_NOP			1 +#define HSDRAMC1_MODE_BANKS_PRECHARGE		2 +#define HSDRAMC1_MODE_LOAD_MODE			3 +#define HSDRAMC1_MODE_AUTO_REFRESH		4 +#define HSDRAMC1_MODE_EXT_LOAD_MODE		5 +#define HSDRAMC1_MODE_POWER_DOWN		6 + +/* Constants for NC */ +#define HSDRAMC1_NC_8_COLUMN_BITS		0 +#define HSDRAMC1_NC_9_COLUMN_BITS		1 +#define HSDRAMC1_NC_10_COLUMN_BITS		2 +#define HSDRAMC1_NC_11_COLUMN_BITS		3 + +/* Constants for NR */ +#define HSDRAMC1_NR_11_ROW_BITS			0 +#define HSDRAMC1_NR_12_ROW_BITS			1 +#define HSDRAMC1_NR_13_ROW_BITS			2 + +/* Constants for NB */ +#define HSDRAMC1_NB_TWO_BANKS			0 +#define HSDRAMC1_NB_FOUR_BANKS			1 + +/* Constants for CAS */ +#define HSDRAMC1_CAS_ONE_CYCLE			1 +#define HSDRAMC1_CAS_TWO_CYCLES			2 + +/* Constants for DBW */ +#define HSDRAMC1_DBW_32_BITS			0 +#define HSDRAMC1_DBW_16_BITS			1 + +/* Constants for TIMEOUT */ +#define HSDRAMC1_TIMEOUT_AFTER_END		0 +#define HSDRAMC1_TIMEOUT_64_CYC_AFTER_END	1 +#define HSDRAMC1_TIMEOUT_128_CYC_AFTER_END	2 + +/* Constants for MD */ +#define HSDRAMC1_MD_SDRAM			0 +#define HSDRAMC1_MD_LOW_POWER_SDRAM		1 + +/* Bit manipulation macros */ +#define HSDRAMC1_BIT(name)					\ +	(1 << HSDRAMC1_##name##_OFFSET) +#define HSDRAMC1_BF(name,value)					\ +	(((value) & ((1 << HSDRAMC1_##name##_SIZE) - 1))	\ +	 << HSDRAMC1_##name##_OFFSET) +#define HSDRAMC1_BFEXT(name,value)				\ +	(((value) >> HSDRAMC1_##name##_OFFSET)			\ +	 & ((1 << HSDRAMC1_##name##_SIZE) - 1)) +#define HSDRAMC1_BFINS(name,value,old)				\ +	(((old) & ~(((1 << HSDRAMC1_##name##_SIZE) - 1)		\ +		    << HSDRAMC1_##name##_OFFSET))		\ +	 | HSDRAMC1_BF(name,value)) + +/* Register access macros */ +#define hsdramc1_readl(reg)					\ +	readl((void *)ATMEL_BASE_HSDRAMC + HSDRAMC1_##reg) +#define hsdramc1_writel(reg,value)				\ +	writel((value), (void *)ATMEL_BASE_HSDRAMC + HSDRAMC1_##reg) + +#endif /* __ASM_AVR32_HSDRAMC1_H__ */ diff --git a/roms/u-boot/arch/avr32/cpu/hsmc3.h b/roms/u-boot/arch/avr32/cpu/hsmc3.h new file mode 100644 index 00000000..ac472952 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/hsmc3.h @@ -0,0 +1,126 @@ +/* + * Register definitions for Static Memory Controller + */ +#ifndef __CPU_AT32AP_HSMC3_H__ +#define __CPU_AT32AP_HSMC3_H__ + +/* HSMC3 register offsets */ +#define HSMC3_SETUP0				0x0000 +#define HSMC3_PULSE0				0x0004 +#define HSMC3_CYCLE0				0x0008 +#define HSMC3_MODE0				0x000c +#define HSMC3_SETUP1				0x0010 +#define HSMC3_PULSE1				0x0014 +#define HSMC3_CYCLE1				0x0018 +#define HSMC3_MODE1				0x001c +#define HSMC3_SETUP2				0x0020 +#define HSMC3_PULSE2				0x0024 +#define HSMC3_CYCLE2				0x0028 +#define HSMC3_MODE2				0x002c +#define HSMC3_SETUP3				0x0030 +#define HSMC3_PULSE3				0x0034 +#define HSMC3_CYCLE3				0x0038 +#define HSMC3_MODE3				0x003c +#define HSMC3_SETUP4				0x0040 +#define HSMC3_PULSE4				0x0044 +#define HSMC3_CYCLE4				0x0048 +#define HSMC3_MODE4				0x004c +#define HSMC3_SETUP5				0x0050 +#define HSMC3_PULSE5				0x0054 +#define HSMC3_CYCLE5				0x0058 +#define HSMC3_MODE5				0x005c + +/* Bitfields in SETUP0 */ +#define HSMC3_NWE_SETUP_OFFSET			0 +#define HSMC3_NWE_SETUP_SIZE			6 +#define HSMC3_NCS_WR_SETUP_OFFSET		8 +#define HSMC3_NCS_WR_SETUP_SIZE			6 +#define HSMC3_NRD_SETUP_OFFSET			16 +#define HSMC3_NRD_SETUP_SIZE			6 +#define HSMC3_NCS_RD_SETUP_OFFSET		24 +#define HSMC3_NCS_RD_SETUP_SIZE			6 + +/* Bitfields in PULSE0 */ +#define HSMC3_NWE_PULSE_OFFSET			0 +#define HSMC3_NWE_PULSE_SIZE			7 +#define HSMC3_NCS_WR_PULSE_OFFSET		8 +#define HSMC3_NCS_WR_PULSE_SIZE			7 +#define HSMC3_NRD_PULSE_OFFSET			16 +#define HSMC3_NRD_PULSE_SIZE			7 +#define HSMC3_NCS_RD_PULSE_OFFSET		24 +#define HSMC3_NCS_RD_PULSE_SIZE			7 + +/* Bitfields in CYCLE0 */ +#define HSMC3_NWE_CYCLE_OFFSET			0 +#define HSMC3_NWE_CYCLE_SIZE			9 +#define HSMC3_NRD_CYCLE_OFFSET			16 +#define HSMC3_NRD_CYCLE_SIZE			9 + +/* Bitfields in MODE0 */ +#define HSMC3_READ_MODE_OFFSET			0 +#define HSMC3_READ_MODE_SIZE			1 +#define HSMC3_WRITE_MODE_OFFSET			1 +#define HSMC3_WRITE_MODE_SIZE			1 +#define HSMC3_EXNW_MODE_OFFSET			4 +#define HSMC3_EXNW_MODE_SIZE			2 +#define HSMC3_BAT_OFFSET			8 +#define HSMC3_BAT_SIZE				1 +#define HSMC3_DBW_OFFSET			12 +#define HSMC3_DBW_SIZE				2 +#define HSMC3_TDF_CYCLES_OFFSET			16 +#define HSMC3_TDF_CYCLES_SIZE			4 +#define HSMC3_TDF_MODE_OFFSET			20 +#define HSMC3_TDF_MODE_SIZE			1 +#define HSMC3_PMEN_OFFSET			24 +#define HSMC3_PMEN_SIZE				1 +#define HSMC3_PS_OFFSET				28 +#define HSMC3_PS_SIZE				2 + +/* Bitfields in MODE1 */ +#define HSMC3_PD_OFFSET				28 +#define HSMC3_PD_SIZE				2 + +/* Constants for READ_MODE */ +#define HSMC3_READ_MODE_NCS_CONTROLLED		0 +#define HSMC3_READ_MODE_NRD_CONTROLLED		1 + +/* Constants for WRITE_MODE */ +#define HSMC3_WRITE_MODE_NCS_CONTROLLED		0 +#define HSMC3_WRITE_MODE_NWE_CONTROLLED		1 + +/* Constants for EXNW_MODE */ +#define HSMC3_EXNW_MODE_DISABLED		0 +#define HSMC3_EXNW_MODE_RESERVED		1 +#define HSMC3_EXNW_MODE_FROZEN			2 +#define HSMC3_EXNW_MODE_READY			3 + +/* Constants for BAT */ +#define HSMC3_BAT_BYTE_SELECT			0 +#define HSMC3_BAT_BYTE_WRITE			1 + +/* Constants for DBW */ +#define HSMC3_DBW_8_BITS			0 +#define HSMC3_DBW_16_BITS			1 +#define HSMC3_DBW_32_BITS			2 + +/* Bit manipulation macros */ +#define HSMC3_BIT(name)						\ +	(1 << HSMC3_##name##_OFFSET) +#define HSMC3_BF(name,value)					\ +	(((value) & ((1 << HSMC3_##name##_SIZE) - 1))		\ +	 << HSMC3_##name##_OFFSET) +#define HSMC3_BFEXT(name,value)					\ +	(((value) >> HSMC3_##name##_OFFSET)			\ +	 & ((1 << HSMC3_##name##_SIZE) - 1)) +#define HSMC3_BFINS(name,value,old)\ +	(((old) & ~(((1 << HSMC3_##name##_SIZE) - 1)		\ +		    << HSMC3_##name##_OFFSET))			\ +	 | HSMC3_BF(name,value)) + +/* Register access macros */ +#define hsmc3_readl(reg)					\ +	readl((void *)ATMEL_BASE_HSMC + HSMC3_##reg) +#define hsmc3_writel(reg,value)					\ +	writel((value), (void *)ATMEL_BASE_HSMC + HSMC3_##reg) + +#endif /* __CPU_AT32AP_HSMC3_H__ */ diff --git a/roms/u-boot/arch/avr32/cpu/interrupts.c b/roms/u-boot/arch/avr32/cpu/interrupts.c new file mode 100644 index 00000000..4a03e19e --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/interrupts.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> +#include <div64.h> + +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/sysreg.h> + +#include <asm/arch/hardware.h> + +#define HANDLER_MASK	0x00ffffff +#define INTLEV_SHIFT	30 +#define INTLEV_MASK	0x00000003 + +DECLARE_GLOBAL_DATA_PTR; + +/* Incremented whenever COUNT reaches 0xffffffff by timer_interrupt_handler */ +volatile unsigned long timer_overflow; + +/* + * Instead of dividing by get_tbclk(), multiply by this constant and + * right-shift the result by 32 bits. + */ +static unsigned long tb_factor; + +unsigned long get_tbclk(void) +{ +	return gd->arch.cpu_hz; +} + +unsigned long long get_ticks(void) +{ +	unsigned long lo, hi_now, hi_prev; + +	do { +		hi_prev = timer_overflow; +		lo = sysreg_read(COUNT); +		hi_now = timer_overflow; +	} while (hi_prev != hi_now); + +	return ((unsigned long long)hi_now << 32) | lo; +} + +unsigned long get_timer(unsigned long base) +{ +	u64 now = get_ticks(); + +	now *= tb_factor; +	return (unsigned long)(now >> 32) - base; +} + +/* + * For short delays only. It will overflow after a few seconds. + */ +void __udelay(unsigned long usec) +{ +	unsigned long cycles; +	unsigned long base; +	unsigned long now; + +	base = sysreg_read(COUNT); +	cycles = ((usec * (get_tbclk() / 10000)) + 50) / 100; + +	do { +		now = sysreg_read(COUNT); +	} while ((now - base) < cycles); +} + +static int set_interrupt_handler(unsigned int nr, void (*handler)(void), +				 unsigned int priority) +{ +	extern void _evba(void); +	unsigned long intpr; +	unsigned long handler_addr = (unsigned long)handler; + +	handler_addr -= (unsigned long)&_evba; + +	if ((handler_addr & HANDLER_MASK) != handler_addr +	    || (priority & INTLEV_MASK) != priority) +		return -EINVAL; + +	intpr = (handler_addr & HANDLER_MASK); +	intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT; +	writel(intpr, (void *)ATMEL_BASE_INTC + 4 * nr); + +	return 0; +} + +int timer_init(void) +{ +	extern void timer_interrupt_handler(void); +	u64 tmp; + +	sysreg_write(COUNT, 0); + +	tmp = (u64)CONFIG_SYS_HZ << 32; +	tmp += gd->arch.cpu_hz / 2; +	do_div(tmp, gd->arch.cpu_hz); +	tb_factor = (u32)tmp; + +	if (set_interrupt_handler(0, &timer_interrupt_handler, 3)) +		return -EINVAL; + +	/* For all practical purposes, this gives us an overflow interrupt */ +	sysreg_write(COMPARE, 0xffffffff); +	return 0; +} diff --git a/roms/u-boot/arch/avr32/cpu/portmux-gpio.c b/roms/u-boot/arch/avr32/cpu/portmux-gpio.c new file mode 100644 index 00000000..640852c2 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/portmux-gpio.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2008 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> + +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/gpio.h> + +void portmux_select_peripheral(void *port, unsigned long pin_mask, +		enum portmux_function func, unsigned long flags) +{ +	/* Both pull-up and pull-down set means buskeeper */ +	if (flags & PORTMUX_PULL_DOWN) +		gpio_writel(port, PDERS, pin_mask); +	else +		gpio_writel(port, PDERC, pin_mask); +	if (flags & PORTMUX_PULL_UP) +		gpio_writel(port, PUERS, pin_mask); +	else +		gpio_writel(port, PUERC, pin_mask); + +	/* Select drive strength */ +	if (flags & PORTMUX_DRIVE_LOW) +		gpio_writel(port, ODCR0S, pin_mask); +	else +		gpio_writel(port, ODCR0C, pin_mask); +	if (flags & PORTMUX_DRIVE_HIGH) +		gpio_writel(port, ODCR1S, pin_mask); +	else +		gpio_writel(port, ODCR1C, pin_mask); + +	/* Select function */ +	if (func & PORTMUX_FUNC_B) +		gpio_writel(port, PMR0S, pin_mask); +	else +		gpio_writel(port, PMR0C, pin_mask); +	if (func & PORTMUX_FUNC_C) +		gpio_writel(port, PMR1S, pin_mask); +	else +		gpio_writel(port, PMR1C, pin_mask); + +	/* Disable GPIO (i.e. enable peripheral) */ +	gpio_writel(port, GPERC, pin_mask); +} + +void portmux_select_gpio(void *port, unsigned long pin_mask, +		unsigned long flags) +{ +	/* Both pull-up and pull-down set means buskeeper */ +	if (flags & PORTMUX_PULL_DOWN) +		gpio_writel(port, PDERS, pin_mask); +	else +		gpio_writel(port, PDERC, pin_mask); +	if (flags & PORTMUX_PULL_UP) +		gpio_writel(port, PUERS, pin_mask); +	else +		gpio_writel(port, PUERC, pin_mask); + +	/* Enable open-drain mode if requested */ +	if (flags & PORTMUX_OPEN_DRAIN) +		gpio_writel(port, ODMERS, pin_mask); +	else +		gpio_writel(port, ODMERC, pin_mask); + +	/* Select drive strength */ +	if (flags & PORTMUX_DRIVE_LOW) +		gpio_writel(port, ODCR0S, pin_mask); +	else +		gpio_writel(port, ODCR0C, pin_mask); +	if (flags & PORTMUX_DRIVE_HIGH) +		gpio_writel(port, ODCR1S, pin_mask); +	else +		gpio_writel(port, ODCR1C, pin_mask); + +	/* Select direction and initial pin state */ +	if (flags & PORTMUX_DIR_OUTPUT) { +		if (flags & PORTMUX_INIT_HIGH) +			gpio_writel(port, OVRS, pin_mask); +		else +			gpio_writel(port, OVRC, pin_mask); +		gpio_writel(port, ODERS, pin_mask); +	} else { +		gpio_writel(port, ODERC, pin_mask); +	} + +	/* Enable GPIO */ +	gpio_writel(port, GPERS, pin_mask); +} diff --git a/roms/u-boot/arch/avr32/cpu/portmux-pio.c b/roms/u-boot/arch/avr32/cpu/portmux-pio.c new file mode 100644 index 00000000..8ce51e64 --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/portmux-pio.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2006, 2008 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <common.h> + +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/gpio.h> + +void portmux_select_peripheral(void *port, unsigned long pin_mask, +		enum portmux_function func, unsigned long flags) +{ +	if (flags & PORTMUX_PULL_UP) +		pio_writel(port, PUER, pin_mask); +	else +		pio_writel(port, PUDR, pin_mask); + +	switch (func) { +	case PORTMUX_FUNC_A: +		pio_writel(port, ASR, pin_mask); +		break; +	case PORTMUX_FUNC_B: +		pio_writel(port, BSR, pin_mask); +		break; +	} + +	pio_writel(port, PDR, pin_mask); +} + +void portmux_select_gpio(void *port, unsigned long pin_mask, +		unsigned long flags) +{ +	if (flags & PORTMUX_PULL_UP) +		pio_writel(port, PUER, pin_mask); +	else +		pio_writel(port, PUDR, pin_mask); + +	if (flags & PORTMUX_OPEN_DRAIN) +		pio_writel(port, MDER, pin_mask); +	else +		pio_writel(port, MDDR, pin_mask); + +	if (flags & PORTMUX_DIR_OUTPUT) { +		if (flags & PORTMUX_INIT_HIGH) +			pio_writel(port, SODR, pin_mask); +		else +			pio_writel(port, CODR, pin_mask); +		pio_writel(port, OER, pin_mask); +	} else { +		pio_writel(port, ODR, pin_mask); +	} + +	pio_writel(port, PER, pin_mask); +} + +void pio_set_output_value(unsigned int pin, int value) +{ +	void *port = pio_pin_to_port(pin); + +	if (!port) +		panic("Invalid GPIO pin %u\n", pin); + +	__pio_set_output_value(port, pin & 0x1f, value); +} + +int pio_get_input_value(unsigned int pin) +{ +	void *port = pio_pin_to_port(pin); + +	if (!port) +		panic("Invalid GPIO pin %u\n", pin); + +	return __pio_get_input_value(port, pin & 0x1f); +} diff --git a/roms/u-boot/arch/avr32/cpu/start.S b/roms/u-boot/arch/avr32/cpu/start.S new file mode 100644 index 00000000..14a0269a --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/start.S @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2005-2008 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +#include <asm-offsets.h> +#include <config.h> +#include <asm/ptrace.h> +#include <asm/sysreg.h> + +#define SYSREG_MMUCR_I_OFFSET	2 +#define SYSREG_MMUCR_S_OFFSET	4 + +#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0)) +/* due to errata (unreliable branch folding) clear FE bit explicitly */ +#define CPUCR_INIT ((SYSREG_BIT(BI) | SYSREG_BIT(BE)	\ +		    | SYSREG_BIT(RE)   |  SYSREG_BIT(IBE)		\ +		    | SYSREG_BIT(IEE)) & ~SYSREG_BIT(FE)) + +	/* +	 * To save some space, we use the same entry point for +	 * exceptions and reset. This avoids lots of alignment padding +	 * since the reset vector is always suitably aligned. +	 */ +	.section .exception.text, "ax", @progbits +	.global	_start +	.global	_evba +	.type	_start, @function +	.type	_evba, @function +_start: +	.size	_start, 0 +_evba: +	.org	0x00 +	rjmp	unknown_exception	/* Unrecoverable exception */ +	.org	0x04 +	rjmp	unknown_exception	/* TLB multiple hit */ +	.org	0x08 +	rjmp	unknown_exception	/* Bus error data fetch */ +	.org	0x0c +	rjmp	unknown_exception	/* Bus error instruction fetch */ +	.org	0x10 +	rjmp	unknown_exception	/* NMI */ +	.org	0x14 +	rjmp	unknown_exception	/* Instruction address */ +	.org	0x18 +	rjmp	unknown_exception	/* ITLB protection */ +	.org	0x1c +	rjmp	unknown_exception	/* Breakpoint */ +	.org	0x20 +	rjmp	unknown_exception	/* Illegal opcode */ +	.org	0x24 +	rjmp	unknown_exception	/* Unimplemented instruction */ +	.org	0x28 +	rjmp	unknown_exception	/* Privilege violation */ +	.org	0x2c +	rjmp	unknown_exception	/* Floating-point */ +	.org	0x30 +	rjmp	unknown_exception	/* Coprocessor absent */ +	.org	0x34 +	rjmp	unknown_exception	/* Data Address (read) */ +	.org	0x38 +	rjmp	unknown_exception	/* Data Address (write) */ +	.org	0x3c +	rjmp	unknown_exception	/* DTLB Protection (read) */ +	.org	0x40 +	rjmp	unknown_exception	/* DTLB Protection (write) */ +	.org	0x44 +	rjmp	unknown_exception	/* DTLB Modified */ + +	.org	0x50			/* ITLB Miss */ +	pushm   r8-r12,lr +	rjmp	1f +	.org	0x60			/* DTLB Miss (read) */ +	pushm   r8-r12,lr +	rjmp	1f +	.org	0x70			/* DTLB Miss (write) */ +	pushm   r8-r12,lr +1:	mov	r12, sp +	rcall	mmu_handle_tlb_miss +	popm	r8-r12,lr +	brne	unknown_exception +	rete + +	.size	_evba, . - _evba + +	.align	2 +	.type	unknown_exception, @function +unknown_exception: +	/* Figure out whether we're handling an exception (Exception +	 * mode) or just booting (Supervisor mode). */ +	csrfcz	SYSREG_M1_OFFSET +	brcc	at32ap_cpu_bootstrap + +	/* This is an exception. Complain. */ +	pushm	r0-r12 +	sub	r8, sp, REG_R12 - REG_R0 - 4 +	mov	r9, lr +	mfsr	r10, SYSREG_RAR_EX +	mfsr	r11, SYSREG_RSR_EX +	pushm	r8-r11 +	mfsr	r12, SYSREG_ECR +	mov	r11, sp +	rcall	do_unknown_exception +1:	rjmp	1b + +	/* The COUNT/COMPARE timer interrupt handler */ +	.global	timer_interrupt_handler +	.type	timer_interrupt_handler,@function +	.align	2 +timer_interrupt_handler: +	/* +	 * Increment timer_overflow and re-write COMPARE with 0xffffffff. +	 * +	 * We're running at interrupt level 3, so we don't need to save +	 * r8-r12 or lr to the stack. +	 */ +	lda.w	r8, timer_overflow +	ld.w	r9, r8[0] +	mov	r10, -1 +	mtsr	SYSREG_COMPARE, r10 +	sub	r9, -1 +	st.w	r8[0], r9 +	rete + +	/* +	 * CPU bootstrap after reset is handled here. SoC code may +	 * override this in case they need to initialize oscillators, +	 * etc. +	 */ +	.section .text.at32ap_cpu_bootstrap, "ax", @progbits +	.global	at32ap_cpu_bootstrap +	.weak	at32ap_cpu_bootstrap +	.type	at32ap_cpu_bootstrap, @function +	.align	2 +at32ap_cpu_bootstrap: +	/* Reset the Status Register */ +	mov	r0, lo(SR_INIT) +	orh	r0, hi(SR_INIT) +	mtsr	SYSREG_SR, r0 + +	/* Reset CPUCR and invalidate the BTB */ +	mov	r2, CPUCR_INIT +	mtsr	SYSREG_CPUCR, r2 + +	/* Flush the caches */ +	mov	r1, 0 +	cache	r1[4], 8 +	cache	r1[0], 0 +	sync	0 + +	/* Reset the MMU to default settings */ +	mov	r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I) +	mtsr	SYSREG_MMUCR, r0 + +	/* Internal RAM should not need any initialization.  We might +	   have to initialize external RAM here if the part doesn't +	   have internal RAM (or we may use the data cache) */ + +	/* Jump to cacheable segment */ +	lddpc	pc, 1f + +	.align	2 +1:	.long	at32ap_low_level_init +	.size	_start, . - _start + +	/* Common CPU bootstrap code after oscillator/cache/etc. init */ +	.section .text.avr32ap_low_level_init, "ax", @progbits +	.global	at32ap_low_level_init +	.type	at32ap_low_level_init, @function +	.align	2 +at32ap_low_level_init: +	lddpc	sp, sp_init + +	/* Initialize the GOT pointer */ +	lddpc	r6, got_init +3:	rsub	r6, pc + +	/* Let's go */ +	rjmp	board_init_f + +	.align	2 +	.type	sp_init,@object +sp_init: +	.long	CONFIG_SYS_INIT_SP_ADDR +got_init: +	.long	3b - _GLOBAL_OFFSET_TABLE_ + +	/* +	 * void	relocate_code(new_sp, new_gd, monitor_addr) +	 * +	 * Relocate the u-boot image into RAM and continue from there. +	 * Does not return. +	 */ +	.section .text.relocate_code,"ax",@progbits +	.global	relocate_code +	.type	relocate_code,@function +relocate_code: +	mov	sp, r12		/* use new stack */ +	mov	r12, r11	/* save new_gd */ +	mov	r11, r10	/* save destination address */ + +	/* copy .text section and flush the cache along the way */ +	lda.w	r8, _text +	lda.w	r9, _etext +	sub	lr, r10, r8	/* relocation offset */ + +1:	ldm	r8++, r0-r3 +	stm	r10, r0-r3 +	sub	r10, -16 +	ldm	r8++, r0-r3 +	stm	r10, r0-r3 +	sub	r10, -16 +	cp.w	r8, r9 +	cache	r10[-4], 0x0d	/* dcache clean/invalidate */ +	cache	r10[-4], 0x01	/* icache invalidate */ +	brlt	1b + +	/* flush write buffer */ +	sync	0 + +	/* copy data sections */ +	lda.w	r9, _edata +1:	ld.d	r0, r8++ +	st.d	r10++, r0 +	cp.w	r8, r9 +	brlt	1b + +	/* zero out .bss */ +	mov	r0, 0 +	mov	r1, 0 +	lda.w	r9, __bss_end +	sub	r9, r8 +1:	st.d	r10++, r0 +	sub	r9, 8 +	brgt	1b + +	/* jump to RAM */ +	sub	r0, pc, . - in_ram +	add	pc, r0, lr + +	.align	2 +in_ram: +	/* find the new GOT and relocate it */ +	lddpc	r6, got_init_reloc +3:	rsub	r6, pc +	mov	r8, r6 +	lda.w	r9, _egot +	lda.w	r10, _got +	sub	r9, r10 +1:	ld.w	r0, r8[0] +	add	r0, lr +	st.w	r8++, r0 +	sub	r9, 4 +	brgt	1b + +	/* Move the exception handlers */ +	mfsr	r2, SYSREG_EVBA +	add	r2, lr +	mtsr	SYSREG_EVBA, r2 + +	/* Do the rest of the initialization sequence */ +	call	board_init_r + +	.align	2 +got_init_reloc: +	.long	3b - _GLOBAL_OFFSET_TABLE_ + +	.size	relocate_code, . - relocate_code diff --git a/roms/u-boot/arch/avr32/cpu/u-boot.lds b/roms/u-boot/arch/avr32/cpu/u-boot.lds new file mode 100644 index 00000000..cb29a22b --- /dev/null +++ b/roms/u-boot/arch/avr32/cpu/u-boot.lds @@ -0,0 +1,56 @@ +/* -*- Fundamental -*- + * + * Copyright (C) 2005-2006 Atmel Corporation + * + * SPDX-License-Identifier:	GPL-2.0+ + */ +OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32") +OUTPUT_ARCH(avr32) +ENTRY(_start) + +SECTIONS +{ +	. = 0; +	_text = .; +	.text : { +		*(.exception.text) +		*(.text) +		*(.text.*) +	} +	_etext = .; + +	.rodata : { +		*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) +	} + +	. = ALIGN(8); +	_data = .; +	.data : { +		*(.data) +		*(.data.*) +	} + +	. = ALIGN(4); + +	. = ALIGN(4); +	.u_boot_list : { +		KEEP(*(SORT(.u_boot_list*))); +	} + +	. = ALIGN(4); +	_got = .; +	.got : { +		*(.got) +	} +	_egot = .; + +	. = ALIGN(8); +	_edata = .; + +	.bss (NOLOAD) : { +		*(.bss) +		*(.bss.*) +	} +	. = ALIGN(8); +	__bss_end = .; +}  | 
