diff options
Diffstat (limited to 'roms/u-boot/arch/arm/mach-at91/armv7')
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/Makefile | 20 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/clock.c | 298 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/cpu.c | 84 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/reset.c | 31 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/sama5d2_devices.c | 83 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/sama5d3_devices.c | 214 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/sama5d4_devices.c | 43 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/sama7g5_devices.c | 11 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/timer.c | 64 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-at91/armv7/u-boot-spl.lds | 59 |
10 files changed, 907 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/Makefile b/roms/u-boot/arch/arm/mach-at91/armv7/Makefile new file mode 100644 index 000000000..f5b266595 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/Makefile @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2013 +# Bo Shen <voice.shen@atmel.com> + +obj-$(CONFIG_SAMA5D2) += sama5d2_devices.o clock.o +obj-$(CONFIG_SAMA5D3) += sama5d3_devices.o clock.o +obj-$(CONFIG_SAMA5D4) += sama5d4_devices.o clock.o +obj-$(CONFIG_SAMA7G5) += sama7g5_devices.o +obj-y += cpu.o +obj-y += reset.o +ifneq ($(CONFIG_ATMEL_PIT_TIMER),y) +ifneq ($(CONFIG_MCHP_PIT64B_TIMER),y) +# old non-DM timer driver +obj-y += timer.o +endif +endif diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/clock.c b/roms/u-boot/arch/arm/mach-at91/armv7/clock.c new file mode 100644 index 000000000..aa6bb6bf3 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/clock.c @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] + * + * Copyright (C) 2005 David Brownell + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com> + * Copyright (C) 2015 Wenyou Yang <wenyou.yang@atmel.com> + */ + +#include <common.h> +#include <asm/global_data.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_pmc.h> +#include <asm/arch/clk.h> + +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static unsigned long at91_css_to_rate(unsigned long css) +{ + switch (css) { + case AT91_PMC_MCKR_CSS_SLOW: + return CONFIG_SYS_AT91_SLOW_CLOCK; + case AT91_PMC_MCKR_CSS_MAIN: + return gd->arch.main_clk_rate_hz; + case AT91_PMC_MCKR_CSS_PLLA: + return gd->arch.plla_rate_hz; + } + + return 0; +} + +static u32 at91_pll_rate(u32 freq, u32 reg) +{ + unsigned mul, div; + + div = reg & 0xff; + mul = (reg >> 18) & 0x7f; + if (div && mul) { + freq /= div; + freq *= mul + 1; + } else { + freq = 0; + } + + return freq; +} + +int at91_clock_init(unsigned long main_clock) +{ + unsigned freq, mckr; + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK + unsigned tmp; + /* + * When the bootloader initialized the main oscillator correctly, + * there's no problem using the cycle counter. But if it didn't, + * or when using oscillator bypass mode, we must be told the speed + * of the main clock. + */ + if (!main_clock) { + do { + tmp = readl(&pmc->mcfr); + } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); + tmp &= AT91_PMC_MCFR_MAINF_MASK; + main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); + } +#endif + gd->arch.main_clk_rate_hz = main_clock; + + /* report if PLLA is more than mildly overclocked */ + gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + + /* + * MCK and CPU derive from one of those primary clocks. + * For now, assume this parentage won't change. + */ + mckr = readl(&pmc->mckr); + + /* plla divisor by 2 */ + if (mckr & (1 << 12)) + gd->arch.plla_rate_hz >>= 1; + + gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = gd->arch.mck_rate_hz; + + /* prescale */ + freq >>= mckr & AT91_PMC_MCKR_PRES_MASK; + + switch (mckr & AT91_PMC_MCKR_MDIV_MASK) { + case AT91_PMC_MCKR_MDIV_2: + gd->arch.mck_rate_hz = freq / 2; + break; + case AT91_PMC_MCKR_MDIV_3: + gd->arch.mck_rate_hz = freq / 3; + break; + case AT91_PMC_MCKR_MDIV_4: + gd->arch.mck_rate_hz = freq / 4; + break; + default: + break; + } + + gd->arch.cpu_clk_rate_hz = freq; + + return 0; +} + +void at91_plla_init(u32 pllar) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + writel(pllar, &pmc->pllar); + while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) + ; +} + +void at91_mck_init(u32 mckr) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + tmp = readl(&pmc->mckr); + tmp &= ~(AT91_PMC_MCKR_CSS_MASK | + AT91_PMC_MCKR_PRES_MASK | + AT91_PMC_MCKR_MDIV_MASK | + AT91_PMC_MCKR_PLLADIV_2); +#ifdef CPU_HAS_H32MXDIV + tmp &= ~AT91_PMC_MCKR_H32MXDIV; +#endif + + tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK | + AT91_PMC_MCKR_PRES_MASK | + AT91_PMC_MCKR_MDIV_MASK | + AT91_PMC_MCKR_PLLADIV_2); +#ifdef CPU_HAS_H32MXDIV + tmp |= mckr & AT91_PMC_MCKR_H32MXDIV; +#endif + + writel(tmp, &pmc->mckr); + + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) + ; +} + +/* + * For the Master Clock Controller Register(MCKR), while switching + * to a lower clock source, we must switch the clock source first + * instead of last. Otherwise, we could end up with too high frequency + * on the internal bus and peripherals. + */ +void at91_mck_init_down(u32 mckr) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + tmp = readl(&pmc->mckr); + tmp &= (~AT91_PMC_MCKR_CSS_MASK); + tmp |= (mckr & AT91_PMC_MCKR_CSS_MASK); + writel(tmp, &pmc->mckr); + + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) + ; + +#ifdef CPU_HAS_H32MXDIV + tmp = readl(&pmc->mckr); + tmp &= (~AT91_PMC_MCKR_H32MXDIV); + tmp |= (mckr & AT91_PMC_MCKR_H32MXDIV); + writel(tmp, &pmc->mckr); +#endif + + tmp = readl(&pmc->mckr); + tmp &= (~AT91_PMC_MCKR_PLLADIV_MASK); + tmp |= (mckr & AT91_PMC_MCKR_PLLADIV_MASK); + writel(tmp, &pmc->mckr); + + tmp = readl(&pmc->mckr); + tmp &= (~AT91_PMC_MCKR_MDIV_MASK); + tmp |= (mckr & AT91_PMC_MCKR_MDIV_MASK); + writel(tmp, &pmc->mckr); + + tmp = readl(&pmc->mckr); + tmp &= (~AT91_PMC_MCKR_PRES_MASK); + tmp |= (mckr & AT91_PMC_MCKR_PRES_MASK); + writel(tmp, &pmc->mckr); +} + +int at91_enable_periph_generated_clk(u32 id, u32 clk_source, u32 div) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 regval, status; + u32 timeout = 1000; + + if (id > AT91_PMC_PCR_PID_MASK) + return -EINVAL; + + if (div > 0xff) + return -EINVAL; + + if (clk_source == GCK_CSS_UPLL_CLK) { + if (at91_upll_clk_enable()) + return -ENODEV; + } + + writel(id, &pmc->pcr); + regval = readl(&pmc->pcr); + regval &= ~AT91_PMC_PCR_GCKCSS; + regval &= ~AT91_PMC_PCR_GCKDIV; + + switch (clk_source) { + case GCK_CSS_SLOW_CLK: + regval |= AT91_PMC_PCR_GCKCSS_SLOW_CLK; + break; + case GCK_CSS_MAIN_CLK: + regval |= AT91_PMC_PCR_GCKCSS_MAIN_CLK; + break; + case GCK_CSS_PLLA_CLK: + regval |= AT91_PMC_PCR_GCKCSS_PLLA_CLK; + break; + case GCK_CSS_UPLL_CLK: + regval |= AT91_PMC_PCR_GCKCSS_UPLL_CLK; + break; + case GCK_CSS_MCK_CLK: + regval |= AT91_PMC_PCR_GCKCSS_MCK_CLK; + break; + case GCK_CSS_AUDIO_CLK: + regval |= AT91_PMC_PCR_GCKCSS_AUDIO_CLK; + break; + default: + printf("Error GCK clock source selection!\n"); + return -EINVAL; + } + + regval |= AT91_PMC_PCR_CMD_WRITE | + AT91_PMC_PCR_GCKDIV_(div) | + AT91_PMC_PCR_GCKEN; + + writel(regval, &pmc->pcr); + + do { + udelay(1); + status = readl(&pmc->sr); + } while ((!!(--timeout)) && (!(status & AT91_PMC_GCKRDY))); + + if (!timeout) + printf("Timeout waiting for GCK ready!\n"); + + return 0; +} + +u32 at91_get_periph_generated_clk(u32 id) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 regval, clk_source, div; + u32 freq; + + if (id > AT91_PMC_PCR_PID_MASK) + return 0; + + writel(id, &pmc->pcr); + regval = readl(&pmc->pcr); + + clk_source = regval & AT91_PMC_PCR_GCKCSS; + switch (clk_source) { + case AT91_PMC_PCR_GCKCSS_SLOW_CLK: + freq = CONFIG_SYS_AT91_SLOW_CLOCK; + break; + case AT91_PMC_PCR_GCKCSS_MAIN_CLK: + freq = gd->arch.main_clk_rate_hz; + break; + case AT91_PMC_PCR_GCKCSS_PLLA_CLK: + freq = gd->arch.plla_rate_hz; + break; + case AT91_PMC_PCR_GCKCSS_UPLL_CLK: + freq = AT91_UTMI_PLL_CLK_FREQ; + break; + case AT91_PMC_PCR_GCKCSS_MCK_CLK: + freq = gd->arch.mck_rate_hz; + break; + default: + printf("Improper GCK clock source selection!\n"); + freq = 0; + break; + } + + div = ((regval & AT91_PMC_PCR_GCKDIV) >> AT91_PMC_PCR_GCKDIV_OFFSET); + div += 1; + + return freq / div; +} diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/cpu.c b/roms/u-boot/arch/arm/mach-at91/armv7/cpu.c new file mode 100644 index 000000000..9b3753491 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/cpu.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * (C) Copyright 2009 + * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * (C) Copyright 2013 + * Bo Shen <voice.shen@atmel.com> + */ + +#include <common.h> +#include <cpu_func.h> +#include <init.h> +#include <vsprintf.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_pit.h> +#include <asm/arch/at91_gpbr.h> +#include <asm/arch/clk.h> + +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK +#define CONFIG_SYS_AT91_MAIN_CLOCK 0 +#endif + +int arch_cpu_init(void) +{ +#if defined(CONFIG_CLK_CCF) + return 0; +#else + return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); +#endif +} + +void arch_preboot_os(void) +{ +#if (IS_ENABLED(CONFIG_ATMEL_PIT_TIMER)) + ulong cpiv; + at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT; + + cpiv = AT91_PIT_MR_PIV_MASK(readl(&pit->piir)); + + /* + * Disable PITC + * Add 0x1000 to current counter to stop it faster + * without waiting for wrapping back to 0 + */ + writel(cpiv + 0x1000, &pit->mr); +#endif +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU: %s\n", get_cpu_name()); + printf("Crystal frequency: %8s MHz\n", + strmhz(buf, get_main_clk_rate())); + printf("CPU clock : %8s MHz\n", + strmhz(buf, get_cpu_clk_rate())); + printf("Master clock : %8s MHz\n", + strmhz(buf, get_mck_clk_rate())); + + return 0; +} +#endif + +void enable_caches(void) +{ + icache_enable(); + dcache_enable(); +} + +#define ATMEL_CHIPID_CIDR_VERSION 0x1f + +unsigned int get_chip_id(void) +{ + return readl(ATMEL_CHIPID_CIDR) & ~ATMEL_CHIPID_CIDR_VERSION; +} + +unsigned int get_extension_chip_id(void) +{ + return readl(ATMEL_CHIPID_EXID); +} diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/reset.c b/roms/u-boot/arch/arm/mach-at91/armv7/reset.c new file mode 100644 index 000000000..1ea415ea9 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/reset.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2007-2008 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + * + * (C) Copyright 2013 + * Bo Shen <voice.shen@atmel.com> + */ + +#include <common.h> +#include <cpu_func.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_rstc.h> + +/* Reset the cpu by telling the reset controller to do so */ +void reset_cpu(void) +{ + at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC; + + writel(AT91_RSTC_KEY + | AT91_RSTC_CR_PROCRST /* Processor Reset */ + | AT91_RSTC_CR_PERRST /* Peripheral Reset */ +#ifdef CONFIG_AT91RESET_EXTRST + | AT91_RSTC_CR_EXTRST /* External Reset (assert nRST pin) */ +#endif + , &rstc->cr); + /* never reached */ + do { } while (1); +} diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/sama5d2_devices.c b/roms/u-boot/arch/arm/mach-at91/armv7/sama5d2_devices.c new file mode 100644 index 000000000..9e9d026c3 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/sama5d2_devices.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015 Atmel Corporation + * Wenyou Yang <wenyou.yang@atmel.com> + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/sama5d2.h> + +int _cpu_is_sama5d2(void) +{ + unsigned int chip_id = get_chip_id(); + + return ((chip_id == ARCH_ID_SAMA5D2) || + (chip_id == ARCH_ID_SAMA5D2_SIP)) ? 1 : 0; +} + +char *get_cpu_name(void) +{ + unsigned int chip_id = get_chip_id(); + unsigned int extension_id = get_extension_chip_id(); + + if (chip_id == ARCH_ID_SAMA5D2) { + switch (extension_id) { + case ARCH_EXID_SAMA5D21CU: + return "SAMA5D21"; + case ARCH_EXID_SAMA5D22CU: + return "SAMA5D22-CU"; + case ARCH_EXID_SAMA5D22CN: + return "SAMA5D22-CN"; + case ARCH_EXID_SAMA5D23CU: + return "SAMA5D23-CU"; + case ARCH_EXID_SAMA5D24CX: + return "SAMA5D24-CX"; + case ARCH_EXID_SAMA5D24CU: + return "SAMA5D24-CU"; + case ARCH_EXID_SAMA5D26CU: + return "SAMA5D26-CU"; + case ARCH_EXID_SAMA5D27CU: + return "SAMA5D27-CU"; + case ARCH_EXID_SAMA5D27CN: + return "SAMA5D27-CN"; + case ARCH_EXID_SAMA5D28CU: + return "SAMA5D28-CU"; + case ARCH_EXID_SAMA5D28CN: + return "SAMA5D28-CN"; + } + } + + if ((chip_id == ARCH_ID_SAMA5D2) || (chip_id == ARCH_ID_SAMA5D2_SIP)) { + switch (extension_id) { + case ARCH_EXID_SAMA5D225C_D1M: + return "SAMA5D225 128M bits DDR2 SDRAM"; + case ARCH_EXID_SAMA5D27C_D5M: + return "SAMA5D27 512M bits DDR2 SDRAM"; + case ARCH_EXID_SAMA5D27C_D1G: + return "SAMA5D27 1G bits DDR2 SDRAM"; + case ARCH_EXID_SAMA5D27C_LD1G: + return "SAMA5D27 1G bits LPDDR2 SDRAM"; + case ARCH_EXID_SAMA5D27C_LD2G: + return "SAMA5D27 2G bits LPDDR2 SDRAM"; + case ARCH_EXID_SAMA5D28C_D1G: + return "SAMA5D28 1G bits DDR2 SDRAM"; + case ARCH_EXID_SAMA5D28C_LD1G: + return "SAMA5D28 1G bits LPDDR2 SDRAM"; + case ARCH_EXID_SAMA5D28C_LD2G: + return "SAMA5D28 2G bits LPDDR2 SDRAM"; + } + } + + return "Unknown CPU type"; +} + +#ifdef CONFIG_USB_GADGET_ATMEL_USBA +void at91_udp_hw_init(void) +{ + at91_upll_clk_enable(); + + at91_periph_clk_enable(ATMEL_ID_UDPHS); +} +#endif diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/sama5d3_devices.c b/roms/u-boot/arch/arm/mach-at91/armv7/sama5d3_devices.c new file mode 100644 index 000000000..091059ea5 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/sama5d3_devices.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2012-2013 Atmel Corporation + * Bo Shen <voice.shen@atmel.com> + */ + +#include <common.h> +#include <asm/arch/sama5d3.h> +#include <asm/arch/at91_common.h> +#include <asm/arch/clk.h> +#include <asm/arch/gpio.h> +#include <asm/io.h> + +unsigned int has_emac() +{ + return cpu_is_sama5d31() || cpu_is_sama5d35() || cpu_is_sama5d36(); +} + +unsigned int has_gmac() +{ + return !cpu_is_sama5d31(); +} + +unsigned int has_lcdc() +{ + return !cpu_is_sama5d35(); +} + +char *get_cpu_name() +{ + unsigned int extension_id = get_extension_chip_id(); + + if (cpu_is_sama5d3()) + switch (extension_id) { + case ARCH_EXID_SAMA5D31: + return "SAMA5D31"; + case ARCH_EXID_SAMA5D33: + return "SAMA5D33"; + case ARCH_EXID_SAMA5D34: + return "SAMA5D34"; + case ARCH_EXID_SAMA5D35: + return "SAMA5D35"; + case ARCH_EXID_SAMA5D36: + return "SAMA5D36"; + default: + return "Unknown CPU type"; + } + else + return "Unknown CPU type"; +} + +void at91_serial0_hw_init(void) +{ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 18, 1); /* TXD0 */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 17, 0); /* RXD0 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART0); +} + +void at91_serial1_hw_init(void) +{ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 29, 1); /* TXD1 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 28, 0); /* RXD1 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART1); +} + +void at91_serial2_hw_init(void) +{ + at91_pio3_set_b_periph(AT91_PIO_PORTE, 26, 1); /* TXD2 */ + at91_pio3_set_b_periph(AT91_PIO_PORTE, 25, 0); /* RXD2 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART2); +} + +void at91_seriald_hw_init(void) +{ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 31, 1); /* DTXD */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 30, 0); /* DRXD */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_DBGU); +} + +#if defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 10, 0); /* SPI0_MISO */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 11, 0); /* SPI0_MOSI */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 12, 0); /* SPI0_SPCK */ + + if (cs_mask & (1 << 0)) + at91_set_pio_output(AT91_PIO_PORTD, 13, 1); + if (cs_mask & (1 << 1)) + at91_set_pio_output(AT91_PIO_PORTD, 14, 1); + if (cs_mask & (1 << 2)) + at91_set_pio_output(AT91_PIO_PORTD, 15, 1); + if (cs_mask & (1 << 3)) + at91_set_pio_output(AT91_PIO_PORTD, 16, 1); + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_SPI0); +} +#endif + +#ifdef CONFIG_GENERIC_ATMEL_MCI +void at91_mci_hw_init(void) +{ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 0, 0); /* MCI0 CMD */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 1, 0); /* MCI0 DA0 */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 2, 0); /* MCI0 DA1 */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 3, 0); /* MCI0 DA2 */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 4, 0); /* MCI0 DA3 */ +#ifdef CONFIG_ATMEL_MCI_8BIT + at91_pio3_set_a_periph(AT91_PIO_PORTD, 5, 0); /* MCI0 DA4 */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 6, 0); /* MCI0 DA5 */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 7, 0); /* MCI0 DA6 */ + at91_pio3_set_a_periph(AT91_PIO_PORTD, 8, 0); /* MCI0 DA7 */ +#endif + at91_pio3_set_a_periph(AT91_PIO_PORTD, 9, 0); /* MCI0 CLK */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_MCI0); +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 7, 0); /* ETXCK_EREFCK */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 5, 0); /* ERXDV */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 2, 0); /* ERX0 */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 3, 0); /* ERX1 */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 6, 0); /* ERXER */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 4, 0); /* ETXEN */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 0, 0); /* ETX0 */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 1, 0); /* ETX1 */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 9, 0); /* EMDIO */ + at91_pio3_set_a_periph(AT91_PIO_PORTC, 8, 0); /* EMDC */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_EMAC); +} + +void at91_gmac_hw_init(void) +{ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 0, 0); /* GTX0 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 1, 0); /* GTX1 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 2, 0); /* GTX2 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 3, 0); /* GTX3 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 4, 0); /* GRX0 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 5, 0); /* GRX1 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 6, 0); /* GRX2 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 7, 0); /* GRX3 */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 8, 0); /* GTXCK */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 9, 0); /* GTXEN */ + + at91_pio3_set_a_periph(AT91_PIO_PORTB, 11, 0); /* GRXCK */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 13, 0); /* GRXER */ + + at91_pio3_set_a_periph(AT91_PIO_PORTB, 16, 0); /* GMDC */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 17, 0); /* GMDIO */ + at91_pio3_set_a_periph(AT91_PIO_PORTB, 18, 0); /* G125CK */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_GMAC); +} +#endif + +#ifdef CONFIG_LCD +void at91_lcd_hw_init(void) +{ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 24, 0); /* LCDPWM */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 25, 0); /* LCDDISP */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 26, 0); /* LCDVSYNC */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 27, 0); /* LCDHSYNC */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 28, 0); /* LCDDOTCK */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 29, 0); /* LCDDEN */ + + /* The lower 16-bit of LCD only available on Port A */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 0, 0); /* LCDD0 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 1, 0); /* LCDD1 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 2, 0); /* LCDD2 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 3, 0); /* LCDD3 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 4, 0); /* LCDD4 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 5, 0); /* LCDD5 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 6, 0); /* LCDD6 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 7, 0); /* LCDD7 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 8, 0); /* LCDD8 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 9, 0); /* LCDD9 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 10, 0); /* LCDD10 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 11, 0); /* LCDD11 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 12, 0); /* LCDD12 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 13, 0); /* LCDD13 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 14, 0); /* LCDD14 */ + at91_pio3_set_a_periph(AT91_PIO_PORTA, 15, 0); /* LCDD15 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_LCDC); +} +#endif + +#ifdef CONFIG_USB_GADGET_ATMEL_USBA +void at91_udp_hw_init(void) +{ + /* Enable UPLL clock */ + at91_upll_clk_enable(); + /* Enable UDPHS clock */ + at91_periph_clk_enable(ATMEL_ID_UDPHS); +} +#endif diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/sama5d4_devices.c b/roms/u-boot/arch/arm/mach-at91/armv7/sama5d4_devices.c new file mode 100644 index 000000000..e68ae9940 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/sama5d4_devices.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014 Atmel + * Bo Shen <voice.shen@atmel.com> + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/at91_common.h> +#include <asm/arch/clk.h> +#include <asm/arch/at91_sfr.h> +#include <asm/arch/sama5d4.h> + +char *get_cpu_name() +{ + unsigned int extension_id = get_extension_chip_id(); + + if (cpu_is_sama5d4()) + switch (extension_id) { + case ARCH_EXID_SAMA5D41: + return "SAMA5D41"; + case ARCH_EXID_SAMA5D42: + return "SAMA5D42"; + case ARCH_EXID_SAMA5D43: + return "SAMA5D43"; + case ARCH_EXID_SAMA5D44: + return "SAMA5D44"; + default: + return "Unknown CPU type"; + } + else + return "Unknown CPU type"; +} + +#ifdef CONFIG_USB_GADGET_ATMEL_USBA +void at91_udp_hw_init(void) +{ + /* Enable UPLL clock */ + at91_upll_clk_enable(); + /* Enable UDPHS clock */ + at91_periph_clk_enable(ATMEL_ID_UDPHS); +} +#endif diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/sama7g5_devices.c b/roms/u-boot/arch/arm/mach-at91/armv7/sama7g5_devices.c new file mode 100644 index 000000000..a58f671f7 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/sama7g5_devices.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Microchip Technology, Inc. + * Eugen Hristev <eugen.hristev@microchip.com> + */ + +char *get_cpu_name(void) +{ + return "SAMA7G5"; +} + diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/timer.c b/roms/u-boot/arch/arm/mach-at91/armv7/timer.c new file mode 100644 index 000000000..1f54c5dca --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/timer.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2007-2008 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + * + * (C) Copyright 2013 + * Bo Shen <voice.shen@atmel.com> + */ + +#include <common.h> +#include <init.h> +#include <time.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_pit.h> +#include <asm/arch/clk.h> +#include <div64.h> + +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* + * We're using the SAMA5D3x PITC in 32 bit mode, by + * setting the 20 bit counter period to its maximum (0xfffff). + * (See the relevant data sheets to understand that this really works) + * + * We do also mimic the typical powerpc way of incrementing + * two 32 bit registers called tbl and tbu. + * + * Those registers increment at 1/16 the main clock rate. + */ + +#define TIMER_LOAD_VAL 0xfffff + +/* + * Use the PITC in full 32 bit incrementing mode + */ +int timer_init(void) +{ + at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT; + + /* Enable PITC Clock */ + at91_periph_clk_enable(ATMEL_ID_PIT); + + /* Enable PITC */ + writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); + + gd->arch.timer_rate_hz = get_pit_clk_rate() / 16; + + return 0; +} + +/* + * Return the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return gd->arch.timer_rate_hz; +} diff --git a/roms/u-boot/arch/arm/mach-at91/armv7/u-boot-spl.lds b/roms/u-boot/arch/arm/mach-at91/armv7/u-boot-spl.lds new file mode 100644 index 000000000..950ea55d7 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-at91/armv7/u-boot-spl.lds @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V <aneesh@ti.com> + * + * (C) 2013 Atmel Corporation + * Bo Shen <voice.shen@atmel.com> + */ + +MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE, \ + LENGTH = IMAGE_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + *(.vectors) + arch/arm/cpu/armv7/start.o (.text*) + *(.text*) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + + . = ALIGN(4); + .u_boot_list : { KEEP(*(SORT(.u_boot_list*))) } > .sram + + . = ALIGN(4); + __image_copy_end = .; + + .end : + { + *(.__end) + } >.sram + + _image_binary_end = .; + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +} |