avionic design with actual uboot and tooling

submodule of avionic design uboot bootloader and with included tools to
get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
2026-03-03 21:46:32 +02:00
parent fe3ba02c96
commit 68d74d3181
11967 changed files with 2221897 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
#
# (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
obj-y += mmc.o
obj-$(if $(filter at32ap700x,$(SOC)),y) += at32ap700x/

View File

@@ -0,0 +1,7 @@
#
# Copyright (C) 2005-2006 Atmel Corporation
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := portmux.o clk.o mmu.o

View File

@@ -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(255UL, 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;
}

View File

@@ -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 &= MMU_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) >> MMU_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 & ~MMU_PAGE_ADDR_MASK;
tlbelo |= fault_pgno << MMU_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;
}

View File

@@ -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

View File

@@ -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__ */

View File

@@ -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 invalidate_dcache_range(unsigned long start, unsigned long stop)
{
unsigned long v, linesz;
linesz = CONFIG_SYS_DCACHE_LINESZ;
/* You asked for it, you got it */
start = start & ~(linesz - 1);
stop = (stop + linesz - 1) & ~(linesz - 1);
for (v = start; v < stop; v += linesz)
dcache_invalidate_line((void *)v);
}
void flush_dcache_range(unsigned long start, unsigned long stop)
{
unsigned long v, linesz;
linesz = CONFIG_SYS_DCACHE_LINESZ;
/* You asked for it, you got it */
start = start & ~(linesz - 1);
stop = (stop + linesz - 1) & ~(linesz - 1);
for (v = start; v < stop; 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);
}

View File

@@ -0,0 +1,6 @@
#
# Copyright (C) 2005-2006 Atmel Corporation
#
# SPDX-License-Identifier: GPL-2.0+
#
PLATFORM_RELFLAGS += -mcpu=ap7000

View File

@@ -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 arch_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;
}

View File

@@ -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->start_addr_sp - CONFIG_STACKSIZE) ||
regs->sp >= gd->start_addr_sp)
printf("\nStack pointer seems bogus, won't do stack dump\n");
else
dump_mem("\nStack: ", regs->sp, gd->start_addr_sp);
panic("Unhandled exception\n");
}

View File

@@ -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;
}

View File

@@ -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__ */

View File

@@ -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__ */

View File

@@ -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;
}

View File

@@ -0,0 +1,16 @@
/*
* Copyright (C) 2004-2006 Atmel Corporation
* Copyright (C) 2015 Andreas Bießmann <andreas@biessmann.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <atmel_mci.h>
#include <asm/arch/hardware.h>
/* provide cpu_mmc_init, to overwrite provide board_mmc_init */
int cpu_mmc_init(bd_t *bd)
{
/* This calls the atmel_mci_init in gen_atmel_mci.c */
return atmel_mci_init((void *)ATMEL_BASE_MMCI);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -0,0 +1,58 @@
/* -*- 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_start = .;
*(.bss)
*(.bss.*)
}
. = ALIGN(8);
__bss_end = .;
__init_end = .;
}