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:
21
u-boot/arch/avr32/cpu/Makefile
Normal file
21
u-boot/arch/avr32/cpu/Makefile
Normal 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/
|
||||
7
u-boot/arch/avr32/cpu/at32ap700x/Makefile
Normal file
7
u-boot/arch/avr32/cpu/at32ap700x/Makefile
Normal 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
|
||||
82
u-boot/arch/avr32/cpu/at32ap700x/clk.c
Normal file
82
u-boot/arch/avr32/cpu/at32ap700x/clk.c
Normal 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;
|
||||
}
|
||||
78
u-boot/arch/avr32/cpu/at32ap700x/mmu.c
Normal file
78
u-boot/arch/avr32/cpu/at32ap700x/mmu.c
Normal 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;
|
||||
}
|
||||
278
u-boot/arch/avr32/cpu/at32ap700x/portmux.c
Normal file
278
u-boot/arch/avr32/cpu/at32ap700x/portmux.c
Normal 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
|
||||
204
u-boot/arch/avr32/cpu/at32ap700x/sm.h
Normal file
204
u-boot/arch/avr32/cpu/at32ap700x/sm.h
Normal 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__ */
|
||||
81
u-boot/arch/avr32/cpu/cache.c
Normal file
81
u-boot/arch/avr32/cpu/cache.c
Normal 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);
|
||||
}
|
||||
6
u-boot/arch/avr32/cpu/config.mk
Normal file
6
u-boot/arch/avr32/cpu/config.mk
Normal file
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# Copyright (C) 2005-2006 Atmel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
PLATFORM_RELFLAGS += -mcpu=ap7000
|
||||
73
u-boot/arch/avr32/cpu/cpu.c
Normal file
73
u-boot/arch/avr32/cpu/cpu.c
Normal 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;
|
||||
}
|
||||
106
u-boot/arch/avr32/cpu/exception.c
Normal file
106
u-boot/arch/avr32/cpu/exception.c
Normal 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");
|
||||
}
|
||||
101
u-boot/arch/avr32/cpu/hsdramc.c
Normal file
101
u-boot/arch/avr32/cpu/hsdramc.c
Normal 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;
|
||||
}
|
||||
143
u-boot/arch/avr32/cpu/hsdramc1.h
Normal file
143
u-boot/arch/avr32/cpu/hsdramc1.h
Normal 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__ */
|
||||
126
u-boot/arch/avr32/cpu/hsmc3.h
Normal file
126
u-boot/arch/avr32/cpu/hsmc3.h
Normal 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__ */
|
||||
112
u-boot/arch/avr32/cpu/interrupts.c
Normal file
112
u-boot/arch/avr32/cpu/interrupts.c
Normal 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;
|
||||
}
|
||||
16
u-boot/arch/avr32/cpu/mmc.c
Normal file
16
u-boot/arch/avr32/cpu/mmc.c
Normal 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);
|
||||
}
|
||||
91
u-boot/arch/avr32/cpu/portmux-gpio.c
Normal file
91
u-boot/arch/avr32/cpu/portmux-gpio.c
Normal 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);
|
||||
}
|
||||
76
u-boot/arch/avr32/cpu/portmux-pio.c
Normal file
76
u-boot/arch/avr32/cpu/portmux-pio.c
Normal 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);
|
||||
}
|
||||
268
u-boot/arch/avr32/cpu/start.S
Normal file
268
u-boot/arch/avr32/cpu/start.S
Normal 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
|
||||
58
u-boot/arch/avr32/cpu/u-boot.lds
Normal file
58
u-boot/arch/avr32/cpu/u-boot.lds
Normal 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 = .;
|
||||
}
|
||||
Reference in New Issue
Block a user