diff options
author | Josh Wu <josh.wu@atmel.com> | 2012-10-22 15:49:04 +0800 |
---|---|---|
committer | Josh Wu <josh.wu@atmel.com> | 2012-10-22 15:49:04 +0800 |
commit | d09dc68d74844b44b89a1311f60055351952fb0e (patch) | |
tree | 6d4bf5d6962bfa3c5d4597d8fbcdb7e2fd840266 | |
parent | 6528ff0109d81c1f21d20f9f1370782bccf87bcb (diff) | |
parent | 3cda03c7fa4413eef2ee250b5936a88c25dbc1be (diff) |
Merge branch 'josh/sama5ek/v2012.10-rc1' into josh/sama5ek/v2012.10
Conflicts:
drivers/mtd/spi/atmel.c
31 files changed, 3655 insertions, 20 deletions
diff --git a/arch/arm/cpu/armv7/at91/Makefile b/arch/arm/cpu/armv7/at91/Makefile new file mode 100644 index 0000000000..5ad88b395e --- /dev/null +++ b/arch/arm/cpu/armv7/at91/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +COBJS-$(CONFIG_AT91SAMA5) += at91sama5_devices.o +COBJS-y += clock.o +COBJS-y += cpu.o +COBJS-y += reset.o +COBJS-y += timer.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +SOBJS-y := lowlevel_init.o +endif + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/at91/at91sama5_devices.c b/arch/arm/cpu/armv7/at91/at91sama5_devices.c new file mode 100644 index 0000000000..167b9f5bb3 --- /dev/null +++ b/arch/arm/cpu/armv7/at91/at91sama5_devices.c @@ -0,0 +1,278 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/arch/at91sama5.h> +#include <asm/arch/at91_common.h> +#include <asm/arch/at91_pmc.h> +#include <asm/arch/clk.h> +#include <asm/arch/gpio.h> +#include <asm/io.h> + +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif + +#define CIDR 0x40 +#define EXID 0x44 + +unsigned int get_chip_id(void) +{ + return readl(ATMEL_BASE_DBGU + CIDR); +} + +unsigned int get_extension_chip_id(void) +{ + return readl(ATMEL_BASE_DBGU + EXID); +} + +unsigned int has_emac() +{ + return cpu_is_at91sama5d31() || cpu_is_at91sama5d35(); +} + +unsigned int has_gmac() +{ + return !cpu_is_at91sama5d31(); +} + +unsigned int has_lcdc() +{ + return !cpu_is_at91sama5d35(); +} + +char *get_cpu_name() +{ + unsigned int extension_id = get_extension_chip_id(); + + if (cpu_is_at91sama5()) + switch (extension_id) { + case ARCH_EXID_AT91SAMA5D31: + return CONFIG_SYS_AT91_D31_CPU_NAME; + case ARCH_EXID_AT91SAMA5D33: + return CONFIG_SYS_AT91_D33_CPU_NAME; + case ARCH_EXID_AT91SAMA5D34: + return CONFIG_SYS_AT91_D34_CPU_NAME; + case ARCH_EXID_AT91SAMA5D35: + return CONFIG_SYS_AT91_D35_CPU_NAME; + default: + return CONFIG_SYS_AT91_UNKNOWN_CPU; + } + else + return CONFIG_SYS_AT91_UNKNOWN_CPU; +} + +void at91_serial0_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTD, 18, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTD, 17, PUP); /* RXD0 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART0); +} + +void at91_serial1_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTB, 28, 0); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTB, 29, PUP); /* RXD1 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART1); +} + +void at91_serial2_hw_init(void) +{ + at91_set_b_periph(AT91_PIO_PORTE, 26, 1); /* TXD2 */ + at91_set_b_periph(AT91_PIO_PORTE, 25, PUP); /* RXD2 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART2); +} + +void at91_seriald_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTB, 31, 1); /* DTXD */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_SYS); +} + +#if defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_set_a_periph(AT91_PIO_PORTD, 10, 0); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTD, 11, 0); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTD, 12, 0); /* SPI0_SPCK */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_SPI0); + + if (cs_mask & (1 << 0)) + at91_set_a_periph(AT91_PIO_PORTD, 13, 0); + if (cs_mask & (1 << 1)) + at91_set_b_periph(AT91_PIO_PORTD, 14, 0); + if (cs_mask & (1 << 2)) + at91_set_b_periph(AT91_PIO_PORTD, 15, 0); + if (cs_mask & (1 << 3)) + at91_set_b_periph(AT91_PIO_PORTD, 16, 0); + if (cs_mask & (1 << 4)) + at91_set_pio_output(AT91_PIO_PORTD, 13, 0); + if (cs_mask & (1 << 5)) + at91_set_pio_output(AT91_PIO_PORTD, 14, 0); + if (cs_mask & (1 << 6)) + at91_set_pio_output(AT91_PIO_PORTD, 15, 0); + if (cs_mask & (1 << 7)) + at91_set_pio_output(AT91_PIO_PORTD, 16, 0); +} +#endif + +#ifdef CONFIG_GENERIC_ATMEL_MCI +void at91_mci_hw_init(void) +{ + at91_set_pio_output(AT91_PIO_PORTB, 10, 0); /* MCI0 Power */ + + at91_set_a_periph(AT91_PIO_PORTD, 0, 0); /* MCI0 CMD */ + at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* MCI0 DA0 */ + at91_set_a_periph(AT91_PIO_PORTD, 2, 0); /* MCI0 DA1 */ + at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* MCI0 DA2 */ + at91_set_a_periph(AT91_PIO_PORTD, 4, 0); /* MCI0 DA3 */ +#ifdef CONFIG_ATMEL_MCI_8BIT + at91_set_a_periph(AT91_PIO_PORTD, 5, 0); /* MCI0 DA4 */ + at91_set_a_periph(AT91_PIO_PORTD, 6, 0); /* MCI0 DA5 */ + at91_set_a_periph(AT91_PIO_PORTD, 7, 0); /* MCI0 DA6 */ + at91_set_a_periph(AT91_PIO_PORTD, 8, 0); /* MCI0 DA7 */ +#endif + at91_set_a_periph(AT91_PIO_PORTD, 9, 0); /* MCI0 CLK */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_MCI0); + + /* Pin muxing for MCI1 */ + at91_set_pio_output(AT91_PIO_PORTB, 12, 0); /* MCI1 Power */ + + at91_set_a_periph(AT91_PIO_PORTB, 19, 0); /* MCI1 CMD */ + at91_set_a_periph(AT91_PIO_PORTB, 20, 0); /* MCI1 DA0 */ + at91_set_a_periph(AT91_PIO_PORTB, 21, 0); /* MCI1 DA1 */ + at91_set_a_periph(AT91_PIO_PORTB, 22, 0); /* MCI1 DA2 */ + at91_set_a_periph(AT91_PIO_PORTB, 23, 0); /* MCI1 DA3 */ + at91_set_a_periph(AT91_PIO_PORTB, 24, 0); /* MCI1 CLK */ +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTC, 7, 0); /* ETXCK_EREFCK */ + at91_set_a_periph(AT91_PIO_PORTC, 5, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTC, 2, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTC, 3, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTC, 6, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTC, 4, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTC, 0, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTC, 1, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTC, 8, 0); /* EMDC */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_EMAC); +} +#endif + +#ifdef CONFIG_GMACB +void at91_gmacb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* GTX0 */ + at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* GTX1 */ + at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* GTX2 */ + at91_set_a_periph(AT91_PIO_PORTB, 3, 0); /* GTX3 */ + at91_set_a_periph(AT91_PIO_PORTB, 4, 0); /* GRX0 */ + at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* GRX1 */ + at91_set_a_periph(AT91_PIO_PORTB, 6, 0); /* GRX2 */ + at91_set_a_periph(AT91_PIO_PORTB, 7, 0); /* GRX3 */ + at91_set_a_periph(AT91_PIO_PORTB, 8, 0); /* GTXCK */ + at91_set_a_periph(AT91_PIO_PORTB, 9, 0); /* GTXEN */ + + at91_set_a_periph(AT91_PIO_PORTB, 11, 0); /* GRXCK */ + at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* GRXER */ + + at91_set_a_periph(AT91_PIO_PORTB, 16, 0); /* GMDC */ + at91_set_a_periph(AT91_PIO_PORTB, 17, 0); /* GMDIO */ + at91_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_set_a_periph(AT91_PIO_PORTA, 24, 0); /* LCDPWM */ + at91_set_a_periph(AT91_PIO_PORTA, 25, 0); /* LCDDISP */ + at91_set_a_periph(AT91_PIO_PORTA, 26, 0); /* LCDVSYNC */ + at91_set_a_periph(AT91_PIO_PORTA, 27, 0); /* LCDHSYNC */ + at91_set_a_periph(AT91_PIO_PORTA, 28, 0); /* LCDDOTCK */ + at91_set_a_periph(AT91_PIO_PORTA, 29, 0); /* LCDDEN */ + + at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* LCDD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* LCDD1 */ + at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* LCDD2 */ + at91_set_a_periph(AT91_PIO_PORTA, 3, 0); /* LCDD3 */ + at91_set_a_periph(AT91_PIO_PORTA, 4, 0); /* LCDD4 */ + at91_set_a_periph(AT91_PIO_PORTA, 5, 0); /* LCDD5 */ + at91_set_a_periph(AT91_PIO_PORTA, 6, 0); /* LCDD6 */ + at91_set_a_periph(AT91_PIO_PORTA, 7, 0); /* LCDD7 */ + at91_set_a_periph(AT91_PIO_PORTA, 8, 0); /* LCDD8 */ + at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* LCDD9 */ + at91_set_a_periph(AT91_PIO_PORTA, 10, 0); /* LCDD10 */ + at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* LCDD11 */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* LCDD12 */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* LCDD13 */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* LCDD14 */ + at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* LCDD15 */ + at91_set_c_periph(AT91_PIO_PORTC, 14, 0); /* LCDD16 */ + at91_set_c_periph(AT91_PIO_PORTC, 13, 0); /* LCDD17 */ + at91_set_c_periph(AT91_PIO_PORTC, 12, 0); /* LCDD18 */ + at91_set_c_periph(AT91_PIO_PORTC, 11, 0); /* LCDD19 */ + at91_set_c_periph(AT91_PIO_PORTC, 10, 0); /* LCDD20 */ + at91_set_c_periph(AT91_PIO_PORTC, 15, 0); /* LCDD21 */ + at91_set_c_periph(AT91_PIO_PORTE, 27, 0); /* LCDD22 */ + at91_set_c_periph(AT91_PIO_PORTE, 28, 0); /* LCDD23 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_LCDC); +} +#endif diff --git a/arch/arm/cpu/armv7/at91/clock.c b/arch/arm/cpu/armv7/at91/clock.c new file mode 100644 index 0000000000..dad7357f4e --- /dev/null +++ b/arch/arm/cpu/armv7/at91/clock.c @@ -0,0 +1,116 @@ +/* + * [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> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <common.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->main_clk_rate_hz; + case AT91_PMC_MCKR_CSS_PLLA: + return gd->plla_rate_hz; + case AT91_PMC_MCKR_CSS_PLLB: + return gd->pllb_rate_hz; + } + + return 0; +} + +static u32 at91_pll_rate(u32 freq, u32 reg) +{ + unsigned mul, div; + + div = reg & 0xff; + mul = (reg >> 18) & 0x7ff; + if (div && mul) { + freq /= div; + freq *= mul + 1; + } else + freq = 0; + + return freq; +} + +int at91_clock_init(unsigned long main_clock) +{ + unsigned freq, mckr; + at91_pmc_t *pmc = (at91_pmc_t *) 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->main_clk_rate_hz = main_clock; + + /* report if PLLA is more than mildly overclocked */ + gd->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 */ + gd->plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); + + gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = gd->mck_rate_hz; + + freq /= (1 << ((mckr & (AT91_PMC_MCKR_PRES_MASK << 2)) >> 4)); /* prescale */ + + gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == + (AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4) + ? freq / 3 + : freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); + + gd->cpu_clk_rate_hz = freq; + + return 0; +} + +void at91_periph_clk_enable(int id) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + /* do we need sanity check for id ? */ + + if (id > 31) + writel(1 << (id - 32), &pmc->pcer1); + else + writel(1 << id, &pmc->pcer); +} diff --git a/arch/arm/cpu/armv7/at91/cpu.c b/arch/arm/cpu/armv7/at91/cpu.c new file mode 100644 index 0000000000..98102576f2 --- /dev/null +++ b/arch/arm/cpu/armv7/at91/cpu.c @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * (C) Copyright 2009 + * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_pmc.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) +{ + return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); +} + +void arch_preboot_os(void) +{ + 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); +} + +#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 + +#ifdef CONFIG_BOOTCOUNT_LIMIT +/* + * We combine the BOOTCOUNT_MAGIC and bootcount in one 32-bit register. + * This is done so we need to use only one of the four GPBR registers. + */ +void bootcount_store (ulong a) +{ + at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR; + + writel((BOOTCOUNT_MAGIC & 0xffff0000) | (a & 0x0000ffff), + &gpbr->reg[AT91_GPBR_INDEX_BOOTCOUNT]); +} + +ulong bootcount_load (void) +{ + at91_gpbr_t *gpbr = (at91_gpbr_t *) ATMEL_BASE_GPBR; + + ulong val = readl(&gpbr->reg[AT91_GPBR_INDEX_BOOTCOUNT]); + if ((val & 0xffff0000) != (BOOTCOUNT_MAGIC & 0xffff0000)) + return 0; + else + return val & 0x0000ffff; +} + +#endif /* CONFIG_BOOTCOUNT_LIMIT */ diff --git a/arch/arm/cpu/armv7/at91/lowlevel_init.S b/arch/arm/cpu/armv7/at91/lowlevel_init.S new file mode 100644 index 0000000000..d102195273 --- /dev/null +++ b/arch/arm/cpu/armv7/at91/lowlevel_init.S @@ -0,0 +1,274 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Copyright (C) 2008 Ronetix Ilko Iliev (www.ronetix.at) + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_pmc.h> +#include <asm/arch/at91_wdt.h> +#include <asm/arch/at91_pio.h> +#include <asm/arch/at91_matrix.h> +#include <asm/arch/at91sam9_sdramc.h> +#include <asm/arch/at91sam9_smc.h> +#include <asm/arch/at91_rstc.h> +#ifdef CONFIG_ATMEL_LEGACY +#include <asm/arch/at91sam9_matrix.h> +#endif +#ifndef CONFIG_SYS_MATRIX_EBICSA_VAL +#define CONFIG_SYS_MATRIX_EBICSA_VAL CONFIG_SYS_MATRIX_EBI0CSA_VAL +#endif + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE + +.globl lowlevel_init +.type lowlevel_init,function +lowlevel_init: + + mov r5, pc /* r5 = POS1 + 4 current */ +POS1: + ldr r0, =POS1 /* r0 = POS1 compile */ + ldr r2, _TEXT_BASE + sub r0, r0, r2 /* r0 = POS1-_TEXT_BASE (POS1 relative) */ + sub r5, r5, r0 /* r0 = CONFIG_SYS_TEXT_BASE-1 */ + sub r5, r5, #4 /* r1 = text base - current */ + + /* memory control configuration 1 */ + ldr r0, =SMRDATA + ldr r2, =SMRDATA1 + ldr r1, _TEXT_BASE + sub r0, r0, r1 + sub r2, r2, r1 + add r0, r0, r5 + add r2, r2, r5 +0: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne 0b + +/* ---------------------------------------------------------------------------- + * PMC Init Step 1. + * ---------------------------------------------------------------------------- + * - Check if the PLL is already initialized + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MCKR) + ldr r0, [r1] + and r0, r0, #3 + cmp r0, #0 + bne PLL_setup_end + +/* --------------------------------------------------------------------------- + * - Enable the Main Oscillator + * --------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MOR) + ldr r2, =(AT91_ASM_PMC_SR) + /* Main oscillator Enable register PMC_MOR: */ + ldr r0, =CONFIG_SYS_MOR_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Main Oscillator is enabled */ + mov r4, #AT91_PMC_IXR_MOSCS +MOSCS_Loop: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MOSCS + bne MOSCS_Loop + +/* ---------------------------------------------------------------------------- + * PMC Init Step 2. + * ---------------------------------------------------------------------------- + * Setup PLLA + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_PLLAR) + ldr r0, =CONFIG_SYS_PLLAR_VAL + str r0, [r1] + + /* Reading the PMC Status register to detect when the PLLA is locked */ + mov r4, #AT91_PMC_IXR_LOCKA +MOSCS_Loop1: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_LOCKA + bne MOSCS_Loop1 + +/* ---------------------------------------------------------------------------- + * PMC Init Step 3. + * ---------------------------------------------------------------------------- + * - Switch on the Main Oscillator + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MCKR) + + /* -Master Clock Controller register PMC_MCKR */ + ldr r0, =CONFIG_SYS_MCKR1_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Master clock is ready */ + mov r4, #AT91_PMC_IXR_MCKRDY +MCKRDY_Loop: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MCKRDY + bne MCKRDY_Loop + + ldr r0, =CONFIG_SYS_MCKR2_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Master clock is ready */ + mov r4, #AT91_PMC_IXR_MCKRDY +MCKRDY_Loop1: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MCKRDY + bne MCKRDY_Loop1 +PLL_setup_end: + +/* ---------------------------------------------------------------------------- + * - memory control configuration 2 + * ---------------------------------------------------------------------------- + */ + ldr r0, =(AT91_ASM_SDRAMC_TR) + ldr r1, [r0] + cmp r1, #0 + bne SDRAM_setup_end + + ldr r0, =SMRDATA1 + ldr r2, =SMRDATA2 + ldr r1, _TEXT_BASE + sub r0, r0, r1 + sub r2, r2, r1 + add r0, r0, r5 + add r2, r2, r5 +2: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne 2b + +SDRAM_setup_end: + /* everything is fine now */ + mov pc, lr + + .ltorg + +SMRDATA: + .word AT91_ASM_WDT_MR + .word CONFIG_SYS_WDTC_WDMR_VAL + /* configure PIOx as EBI0 D[16-31] */ +#if defined(CONFIG_AT91SAM9263) + .word AT91_ASM_PIOD_PDR + .word CONFIG_SYS_PIOD_PDR_VAL1 + .word AT91_ASM_PIOD_PUDR + .word CONFIG_SYS_PIOD_PPUDR_VAL + .word AT91_ASM_PIOD_ASR + .word CONFIG_SYS_PIOD_PPUDR_VAL +#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) \ + || defined(CONFIG_AT91SAM9G20) + .word AT91_ASM_PIOC_PDR + .word CONFIG_SYS_PIOC_PDR_VAL1 + .word AT91_ASM_PIOC_PUDR + .word CONFIG_SYS_PIOC_PPUDR_VAL +#endif + .word AT91_ASM_MATRIX_CSA0 + .word CONFIG_SYS_MATRIX_EBICSA_VAL + + /* flash */ + .word AT91_ASM_SMC_MODE0 + .word CONFIG_SYS_SMC0_MODE0_VAL + + .word AT91_ASM_SMC_CYCLE0 + .word CONFIG_SYS_SMC0_CYCLE0_VAL + + .word AT91_ASM_SMC_PULSE0 + .word CONFIG_SYS_SMC0_PULSE0_VAL + + .word AT91_ASM_SMC_SETUP0 + .word CONFIG_SYS_SMC0_SETUP0_VAL + +SMRDATA1: + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL1 + .word AT91_ASM_SDRAMC_TR + .word CONFIG_SYS_SDRC_TR_VAL1 + .word AT91_ASM_SDRAMC_CR + .word CONFIG_SYS_SDRC_CR_VAL + .word AT91_ASM_SDRAMC_MDR + .word CONFIG_SYS_SDRC_MDR_VAL + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL2 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL1 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL3 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL2 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL3 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL4 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL5 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL6 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL7 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL8 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL9 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL4 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL10 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL5 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL11 + .word AT91_ASM_SDRAMC_TR + .word CONFIG_SYS_SDRC_TR_VAL2 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL12 + /* User reset enable*/ + .word AT91_ASM_RSTC_MR + .word CONFIG_SYS_RSTC_RMR_VAL +#ifdef CONFIG_SYS_MATRIX_MCFG_REMAP + /* MATRIX_MCFG - REMAP all masters */ + .word AT91_ASM_MATRIX_MCFG + .word 0x1FF +#endif +SMRDATA2: + .word 0 diff --git a/arch/arm/cpu/armv7/at91/reset.c b/arch/arm/cpu/armv7/at91/reset.c new file mode 100644 index 0000000000..f6a7cb7a86 --- /dev/null +++ b/arch/arm/cpu/armv7/at91/reset.c @@ -0,0 +1,45 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.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(ulong ignored) +{ + 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 */ + while (1) + ; +} diff --git a/arch/arm/cpu/armv7/at91/timer.c b/arch/arm/cpu/armv7/at91/timer.c new file mode 100644 index 0000000000..f70ce83f08 --- /dev/null +++ b/arch/arm/cpu/armv7/at91/timer.c @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/at91_pit.h> +#include <asm/arch/at91_pmc.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 AT91CAP9/SAM9 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 + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, gd->timer_rate_hz); + + return tick; +} + +static inline unsigned long long usec_to_tick(unsigned long long usec) +{ + usec *= gd->timer_rate_hz; + do_div(usec, 1000000); + + return usec; +} + +/* + * Use the PITC in full 32 bit incrementing mode + */ +int timer_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + at91_pit_t *pit = (at91_pit_t *) ATMEL_BASE_PIT; + + /* Enable PITC Clock */ + writel(1 << ATMEL_ID_SYS, &pmc->pcer); + + /* Enable PITC */ + writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); + + gd->timer_rate_hz = gd->mck_rate_hz / 16; + gd->tbu = gd->tbl = 0; + + return 0; +} + +/* + * Get the current 64 bit timer tick count + */ +unsigned long long get_ticks(void) +{ + at91_pit_t *pit = (at91_pit_t *) ATMEL_BASE_PIT; + + ulong now = readl(&pit->piir); + + /* increment tbu if tbl has rolled over */ + if (now < gd->tbl) + gd->tbu++; + gd->tbl = now; + return (((unsigned long long)gd->tbu) << 32) | gd->tbl; +} + +void __udelay(unsigned long usec) +{ + unsigned long long start; + ulong tmo; + + start = get_ticks(); /* get current timestamp */ + tmo = usec_to_tick(usec); /* convert usecs to ticks */ + while ((get_ticks() - start) < tmo) + ; /* loop till time has passed */ +} + +/* + * get_timer(base) can be used to check for timeouts or + * to measure elasped time relative to an event: + * + * ulong start_time = get_timer(0) sets start_time to the current + * time value. + * get_timer(start_time) returns the time elapsed since then. + * + * The time is used in CONFIG_SYS_HZ units! + */ +ulong get_timer(ulong base) +{ + return tick_to_time(get_ticks()) - base; +} + +/* + * Return the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return gd->timer_rate_hz; +} diff --git a/arch/arm/include/asm/arch-at91/at91_pio.h b/arch/arm/include/asm/arch-at91/at91_pio.h index 0483c9820e..3252516200 100644 --- a/arch/arm/include/asm/arch-at91/at91_pio.h +++ b/arch/arm/include/asm/arch-at91/at91_pio.h @@ -180,11 +180,36 @@ int at91_get_pio_value(unsigned port, unsigned pin); #define PIO_PUER 0x64 /* Pull-up Enable Register */ #define PIO_PUSR 0x68 /* Pull-up Status Register */ #define PIO_ASR 0x70 /* Peripheral A Select Register */ +#define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 */ #define PIO_BSR 0x74 /* Peripheral B Select Register */ +#define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 */ #define PIO_ABSR 0x78 /* AB Status Register */ +#define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */ +#define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */ +#define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */ +#define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */ +#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */ +#define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */ +#define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */ +#define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */ #define PIO_OWER 0xa0 /* Output Write Enable Register */ #define PIO_OWDR 0xa4 /* Output Write Disable Register */ #define PIO_OWSR 0xa8 /* Output Write Status Register */ +#define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */ +#define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */ +#define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */ +#define PIO_ESR 0xc0 /* Edge Select Register */ +#define PIO_LSR 0xc4 /* Level Select Register */ +#define PIO_ELSR 0xc8 /* Edge/Level Status Register */ +#define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */ +#define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */ +#define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */ +#define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */ + +#define ABCDSR_PERIPH_A 0x0 +#define ABCDSR_PERIPH_B 0x1 +#define ABCDSR_PERIPH_C 0x2 +#define ABCDSR_PERIPH_D 0x3 #endif #endif diff --git a/arch/arm/include/asm/arch-at91/at91_pmc.h b/arch/arm/include/asm/arch-at91/at91_pmc.h index 086cb9b34e..ca529778b7 100644 --- a/arch/arm/include/asm/arch-at91/at91_pmc.h +++ b/arch/arm/include/asm/arch-at91/at91_pmc.h @@ -43,19 +43,29 @@ typedef struct at91_pmc { u32 mckr; /* 0x30 Master Clock Register */ u32 reserved1; u32 usb; /* 0x38 USB Clock Register */ - u32 reserved2; + u32 smd; /* 0x3C Soft Modem Clock Register */ u32 pck[4]; /* 0x40 Programmable Clock Register 0 - 3 */ u32 reserved3[4]; u32 ier; /* 0x60 Interrupt Enable Register */ u32 idr; /* 0x64 Interrupt Disable Register */ u32 sr; /* 0x68 Status Register */ u32 imr; /* 0x6C Interrupt Mask Register */ - u32 reserved4[4]; + u32 fsmr; /* 0x70 Fast Startup Mode Register */ + u32 fspr; /* 0x74 Fast Startup Polarity Register */ + u32 focr; /* 0x78 Fault Output Clear Register */ + u32 reserved4; u32 pllicpr; /* 0x80 Change Pump Current Register (SAM9) */ u32 reserved5[21]; u32 wpmr; /* 0xE4 Write Protect Mode Register (CAP0) */ u32 wpsr; /* 0xE8 Write Protect Status Register (CAP0) */ - u32 reserved8[5]; + u32 reserved6[4]; + u32 ver; /* 0xFC Version register */ + u32 reserved[3]; + u32 pcer1; /* 0x100 Periperial Clock Enable Register 1 */ + u32 pcdr1; /* 0x104 Periperial Clock Disable Register 1 */ + u32 pcsr1; /* 0x108 Periperial Clcok Status Register 1 */ + u32 pcr; /* 0x10C Periperial Control Register */ + u32 ocr; /* 0x110 Oscillator Calibration Register */ } at91_pmc_t; #endif /* end not assembly */ diff --git a/arch/arm/include/asm/arch-at91/at91sama5.h b/arch/arm/include/asm/arch-at91/at91sama5.h new file mode 100644 index 0000000000..38b9e9c7d9 --- /dev/null +++ b/arch/arm/include/asm/arch-at91/at91sama5.h @@ -0,0 +1,219 @@ +/* + * Chip-specific header file for the AT91SAMA5 family + * + * (C) 2012 Atmel Corporation. + * + * Definitions for the SoC: + * AT91SAMA5 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91SAMA5_H +#define AT91SAMA5_H + +/* + * defines to be used in other places + */ +#define CONFIG_ARMV7 /* ARM A5 Core */ +#define CONFIG_AT91FAMILY /* it's a member of AT91 */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define ATMEL_ID_SYS 1 /* System Controller Interrupt */ +#define ATMEL_ID_DBGU 2 /* Debug Unit Interrupt */ +#define ATMEL_ID_PIT 3 /* Periodic Interval Timer Interrupt */ +#define ATMEL_ID_WDT 4 /* Watchdog timer Interrupt */ +#define ATMEL_ID_SMC 5 /* Multi-bit ECC Interrupt */ +#define ATMEL_ID_PIOA 6 /* Parallel I/O Controller A */ +#define ATMEL_ID_PIOB 7 /* Parallel I/O Controller B */ +#define ATMEL_ID_PIOC 8 /* Parallel I/O Controller C */ +#define ATMEL_ID_PIOD 9 /* Parallel I/O Controller D */ +#define ATMEL_ID_PIOE 10 /* Parallel I/O Controller E */ +#define ATMEL_ID_SMD 11 /* SMD Soft Modem */ +#define ATMEL_ID_USART0 12 /* USART 0 */ +#define ATMEL_ID_USART1 13 /* USART 1 */ +#define ATMEL_ID_USART2 14 /* USART 2 */ +#define ATMEL_ID_USART3 15 /* USART 3 */ +#define ATMEL_ID_UART0 16 +#define ATMEL_ID_UART1 17 +#define ATMEL_ID_TWI0 18 /* Two-Wire Interface 0 */ +#define ATMEL_ID_TWI1 19 /* Two-Wire Interface 1 */ +#define ATMEL_ID_TWI2 20 /* Two-Wire Interface 2 */ +#define ATMEL_ID_MCI0 21 /* High Speed Multimedia Card Interface 0 */ +#define ATMEL_ID_MCI1 22 /* */ +#define ATMEL_ID_MCI2 23 /* */ +#define ATMEL_ID_SPI0 24 /* Serial Peripheral Interface 0 */ +#define ATMEL_ID_SPI1 25 /* Serial Peripheral Interface 1 */ +#define ATMEL_ID_TC0 26 /* */ +#define ATMEL_ID_TC1 27 /* */ +#define ATMEL_ID_PWMC 28 /* Pulse Width Modulation Controller */ +#define ATMEL_ID_TSC 29 /* Touch Screen ADC Controller */ +#define ATMEL_ID_DMA0 30 /* DMA Controller */ +#define ATMEL_ID_DMA1 31 /* DMA Controller */ +#define ATMEL_ID_UHPHS 32 /* USB Host High Speed */ +#define ATMEL_ID_UDPHS 33 /* USB Device High Speed */ +#define ATMEL_ID_GMAC 34 +#define ATMEL_ID_EMAC 35 /* Ethernet MAC */ +#define ATMEL_ID_LCDC 36 /* LCD Controller */ +#define ATMEL_ID_ISI 37 /* Image Sensor Interface */ +#define ATMEL_ID_SSC0 38 /* Synchronous Serial Controller 0 */ +#define ATMEL_ID_SSC1 39 /* Synchronous Serial Controller 1 */ +#define ATMEL_ID_CAN0 40 +#define ATMEL_ID_CAN1 41 +#define ATMEL_ID_SHA 42 +#define ATMEL_ID_AES 43 +#define ATMEL_ID_TDES 44 +#define ATMEL_ID_TRNG 45 +#define ATMEL_ID_ARM 46 +#define ATMEL_ID_IRQ0 47 /* Advanced Interrupt Controller */ +#define ATMEL_ID_FUSE 48 +#define ATMEL_ID_MPDDRC 49 + +/* sama5 series chip id definitions */ +#define ARCH_ID_AT91SAMA5 0x8a5c07c1 +#define ARCH_EXID_AT91SAMA5D31 0x00444300 +#define ARCH_EXID_AT91SAMA5D33 0x00414300 +#define ARCH_EXID_AT91SAMA5D34 0x00414301 +#define ARCH_EXID_AT91SAMA5D35 0x00584300 + +#define cpu_is_at91sama5() (get_chip_id() == ARCH_ID_AT91SAMA5) +#define cpu_is_at91sama5d31() (cpu_is_at91sama5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAMA5D31)) +#define cpu_is_at91sama5d33() (cpu_is_at91sama5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAMA5D33)) +#define cpu_is_at91sama5d34() (cpu_is_at91sama5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAMA5D34)) +#define cpu_is_at91sama5d35() (cpu_is_at91sama5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAMA5D35)) + +/* + * User Peripherals physical base addresses. + */ +#define ATMEL_BASE_MCI0 0xf0000000 +#define ATMEL_BASE_SPI0 0xf0004000 +#define ATMEL_BASE_SSC0 0xf000C000 +#define ATMEL_BASE_TC2 0xf0010000 +#define ATMEL_BASE_TWI0 0xf0014000 +#define ATMEL_BASE_TWI1 0xf0018000 +#define ATMEL_BASE_USART0 0xf001c000 +#define ATMEL_BASE_USART1 0xf0020000 +#define ATMEL_BASE_UART0 0xf0024000 +#define ATMEL_BASE_GMAC 0xf0028000 +#define ATMEL_BASE_PWMC 0xf002c000 +#define ATMEL_BASE_LCDC 0xf0030000 +#define ATMEL_BASE_ISI 0xf0034000 +#define ATMEL_BASE_SFR 0xf0038000 +/* Reserved: 0xf003c000 - 0xf8000000 */ +#define ATMEL_BASE_MCI1 0xf8000000 +#define ATMEL_BASE_MCI2 0xf8004000 +#define ATMEL_BASE_SPI1 0xf8008000 +#define ATMEL_BASE_SSC1 0xf800c000 +#define ATMEL_BASE_CAN1 0xf8010000 +#define ATMEL_BASE_TC3 0xf8014000 +#define ATMEL_BASE_TSADC 0xf8018000 +#define ATMEL_BASE_TWI2 0xf801c000 +#define ATMEL_BASE_USART2 0xf8020000 +#define ATMEL_BASE_USART3 0xf8024000 +#define ATMEL_BASE_UART1 0xf8028000 +#define ATMEL_BASE_EMAC 0xf802c000 +#define ATMEL_BASE_UDHPS 0xf8030000 +#define ATMEL_BASE_SHA 0xf8034000 +#define ATMEL_BASE_AES 0xf8038000 +#define ATMEL_BASE_TDES 0xf803c000 +#define ATMEL_BASE_TRNG 0xf8040000 +/* Reserved: 0xf804400 - 0xffffc00 */ + +/* + * System Peripherals physical base addresses. + */ +#define ATMEL_BASE_SYS 0xffffc000 +#define ATMEL_BASE_SMC 0xffffc000 +#define ATMEL_BASE_PMECC (ATMEL_BASE_SMC + 0x070) +#define ATMEL_BASE_PMERRLOC (ATMEL_BASE_SMC + 0x500) +#define ATMEL_BASE_FUSE 0xffffe400 +#define ATMEL_BASE_DMAC0 0xffffe600 +#define ATMEL_BASE_DMAC1 0xffffe800 +#define ATMEL_BASE_MPDDRC 0xffffea00 +#define ATMEL_BASE_MATRIX 0xffffec00 +#define ATMEL_BASE_DBGU 0xffffee00 +#define ATMEL_BASE_AIC 0xfffff000 +#define ATMEL_BASE_PIOA 0xfffff200 +#define ATMEL_BASE_PIOB 0xfffff400 +#define ATMEL_BASE_PIOC 0xfffff600 +#define ATMEL_BASE_PIOD 0xfffff800 +#define ATMEL_BASE_PIOE 0xfffffa00 +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffe00 +#define ATMEL_BASE_SHDWN 0xfffffe10 +#define ATMEL_BASE_PIT 0xfffffe30 +#define ATMEL_BASE_WDT 0xfffffe40 +#define ATMEL_BASE_SCKCR 0xfffffe50 +#define ATMEL_BASE_GPBR 0xfffffe60 +#define ATMEL_BASE_RTC 0xfffffeb0 +/* Reserved: 0xfffffee0 - 0xffffffff */ + +/* + * Internal Memory. + */ +#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */ +#define ATMEL_BASE_SRAM 0x00200000 /* Internal ROM base address */ +#define ATMEL_BASE_SRAM0 0x00300000 /* Internal SRAM base address */ +#define ATMEL_BASE_SRAM1 0x00310000 /* Internal SRAM base address */ +#define ATMEL_BASE_SMD 0x00400000 /* Internal ROM base address */ +#define ATMEL_BASE_UDPHS_FIFO 0x00500000 /* USB Device HS controller */ +#define ATMEL_BASE_OHCI 0x00600000 /* USB Host controller (OHCI) */ +#define ATMEL_BASE_EHCI 0x00700000 /* USB Host controller (EHCI) */ +#define ATMEL_BASE_AXI 0x00800000 /* Video Decoder Controller */ +#define ATMEL_BASE_DAP 0x00900000 /* Video Decoder Controller */ + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 +#define ATMEL_BASE_DDRCS 0x20000000 +#define ATMEL_BASE_CS1 0x40000000 +#define ATMEL_BASE_CS2 0x50000000 +#define ATMEL_BASE_CS3 0x60000000 + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 5 +#define CPU_HAS_PIO3 + +/* + * PMECC table in ROM + */ +#define ATMEL_PMECC_INDEX_OFFSET_512 0x10000 +#define ATMEL_PMECC_INDEX_OFFSET_1024 0x18000 +#define ATMEL_PMECC_ALPHA_OFFSET_512 0x10000 +#define ATMEL_PMECC_ALPHA_OFFSET_1024 0x18000 + +/* + * Cpu Name + */ +#define CONFIG_SYS_AT91_D31_CPU_NAME "AT91SAMA5D31" +#define CONFIG_SYS_AT91_D33_CPU_NAME "AT91SAMA5D33" +#define CONFIG_SYS_AT91_D34_CPU_NAME "AT91SAMA5D34" +#define CONFIG_SYS_AT91_D35_CPU_NAME "AT91SAMA5D35" +#define CONFIG_SYS_AT91_UNKNOWN_CPU "Unknown CPU type" + +/* + * AT91SAMA5 specific prototypes + */ +#ifndef __ASSEMBLY__ +unsigned int get_chip_id(void); +unsigned int get_extension_chip_id(void); +unsigned int has_emac(void); +unsigned int has_gmac(void); +unsigned int has_lcdc(void); +char *get_cpu_name(void); +#endif + +#endif diff --git a/arch/arm/include/asm/arch-at91/at91sama5_smc.h b/arch/arm/include/asm/arch-at91/at91sama5_smc.h new file mode 100644 index 0000000000..22370e0b8f --- /dev/null +++ b/arch/arm/include/asm/arch-at91/at91sama5_smc.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2012 Atmel Corporation. + * + * Static Memory Controllers (SMC) - System peripherals registers. + * Based on AT91SAMA5 datasheet. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91SAMA5_SMC_H +#define AT91SAMA5_SMC_H + +#ifdef __ASSEMBLY__ + +#define AT91_ASM_SMC_SETUP0 (ATMEL_BASE_SMC + 0x600) +#define AT91_ASM_SMC_PULSE0 (ATMEL_BASE_SMC + 0x604) +#define AT91_ASM_SMC_CYCLE0 (ATMEL_BASE_SMC + 0x608) +#define AT91_ASM_SMC_MODE0 (ATMEL_BASE_SMC + 0x60C) + +#else + +typedef struct at91_cs { + u32 reserved[96]; + u32 setup; /* 0x600 SMC Setup Register */ + u32 pulse; /* 0x604 SMC Pulse Register */ + u32 cycle; /* 0x608 SMC Cycle Register */ + u32 timings; /* 0x60C SMC Cycle Register */ + u32 mode; /* 0x610 SMC Mode Register */ +} at91_cs_t; + +typedef struct at91_smc { + at91_cs_t cs[4]; +} at91_smc_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_SMC_SETUP_NWE(x) (x & 0x3f) +#define AT91_SMC_SETUP_NCS_WR(x) ((x & 0x3f) << 8) +#define AT91_SMC_SETUP_NRD(x) ((x & 0x3f) << 16) +#define AT91_SMC_SETUP_NCS_RD(x) ((x & 0x3f) << 24) + +#define AT91_SMC_PULSE_NWE(x) (x & 0x3f) +#define AT91_SMC_PULSE_NCS_WR(x) ((x & 0x3f) << 8) +#define AT91_SMC_PULSE_NRD(x) ((x & 0x3f) << 16) +#define AT91_SMC_PULSE_NCS_RD(x) ((x & 0x3f) << 24) + +#define AT91_SMC_CYCLE_NWE(x) (x & 0x1ff) +#define AT91_SMC_CYCLE_NRD(x) ((x & 0x1ff) << 16) + +#define AT91_SMC_TIMINGS_TCLR(x) (x & 0xf) +#define AT91_SMC_TIMINGS_TADL(x) ((x & 0xf) << 4) +#define AT91_SMC_TIMINGS_TAR(x) ((x & 0xf) << 8) +#define AT91_SMC_TIMINGS_OCMS(x) ((x & 0x1) << 12) +#define AT91_SMC_TIMINGS_TRR(x) ((x & 0xf) << 16) +#define AT91_SMC_TIMINGS_TWB(x) ((x & 0xf) << 24) +#define AT91_SMC_TIMINGS_RBNSEL(x) ((x & 0xf) << 28) +#define AT91_SMC_TIMINGS_NFSEL(x) ((x & 0x1) << 31) + +#define AT91_SMC_MODE_RM_NCS 0x00000000 +#define AT91_SMC_MODE_RM_NRD 0x00000001 +#define AT91_SMC_MODE_WM_NCS 0x00000000 +#define AT91_SMC_MODE_WM_NWE 0x00000002 + +#define AT91_SMC_MODE_EXNW_DISABLE 0x00000000 +#define AT91_SMC_MODE_EXNW_FROZEN 0x00000020 +#define AT91_SMC_MODE_EXNW_READY 0x00000030 + +#define AT91_SMC_MODE_BAT 0x00000100 +#define AT91_SMC_MODE_DBW_8 0x00000000 +#define AT91_SMC_MODE_DBW_16 0x00001000 +#define AT91_SMC_MODE_DBW_32 0x00002000 +#define AT91_SMC_MODE_TDF_CYCLE(x) ((x & 0xf) << 16) +#define AT91_SMC_MODE_TDF 0x00100000 +#define AT91_SMC_MODE_PMEN 0x01000000 +#define AT91_SMC_MODE_PS_4 0x00000000 +#define AT91_SMC_MODE_PS_8 0x10000000 +#define AT91_SMC_MODE_PS_16 0x20000000 +#define AT91_SMC_MODE_PS_32 0x30000000 + +#ifdef CONFIG_AT91_LEGACY + +#define AT91_SMC_SETUP(n) (AT91_SMC + 0x00 + ((n)*0x10)) /* Setup Register for CS n */ +#define AT91_SMC_NWESETUP (0x3f << 0) /* NWE Setup Length */ +#define AT91_SMC_NWESETUP_(x) ((x) << 0) +#define AT91_SMC_NCS_WRSETUP (0x3f << 8) /* NCS Setup Length in Write Access */ +#define AT91_SMC_NCS_WRSETUP_(x) ((x) << 8) +#define AT91_SMC_NRDSETUP (0x3f << 16) /* NRD Setup Length */ +#define AT91_SMC_NRDSETUP_(x) ((x) << 16) +#define AT91_SMC_NCS_RDSETUP (0x3f << 24) /* NCS Setup Length in Read Access */ +#define AT91_SMC_NCS_RDSETUP_(x) ((x) << 24) + +#define AT91_SMC_PULSE(n) (AT91_SMC + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */ +#define AT91_SMC_NWEPULSE (0x7f << 0) /* NWE Pulse Length */ +#define AT91_SMC_NWEPULSE_(x) ((x) << 0) +#define AT91_SMC_NCS_WRPULSE (0x7f << 8) /* NCS Pulse Length in Write Access */ +#define AT91_SMC_NCS_WRPULSE_(x)((x) << 8) +#define AT91_SMC_NRDPULSE (0x7f << 16) /* NRD Pulse Length */ +#define AT91_SMC_NRDPULSE_(x) ((x) << 16) +#define AT91_SMC_NCS_RDPULSE (0x7f << 24) /* NCS Pulse Length in Read Access */ +#define AT91_SMC_NCS_RDPULSE_(x)((x) << 24) + +#define AT91_SMC_CYCLE(n) (AT91_SMC + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */ +#define AT91_SMC_NWECYCLE (0x1ff << 0 ) /* Total Write Cycle Length */ +#define AT91_SMC_NWECYCLE_(x) ((x) << 0) +#define AT91_SMC_NRDCYCLE (0x1ff << 16) /* Total Read Cycle Length */ +#define AT91_SMC_NRDCYCLE_(x) ((x) << 16) + +#define AT91_SMC_MODE(n) (AT91_SMC + 0x0c + ((n)*0x10)) /* Mode Register for CS n */ +#define AT91_SMC_READMODE (1 << 0) /* Read Mode */ +#define AT91_SMC_WRITEMODE (1 << 1) /* Write Mode */ +#define AT91_SMC_EXNWMODE (3 << 4) /* NWAIT Mode */ +#define AT91_SMC_EXNWMODE_DISABLE (0 << 4) +#define AT91_SMC_EXNWMODE_FROZEN (2 << 4) +#define AT91_SMC_EXNWMODE_READY (3 << 4) +#define AT91_SMC_BAT (1 << 8) /* Byte Access Type */ +#define AT91_SMC_BAT_SELECT (0 << 8) +#define AT91_SMC_BAT_WRITE (1 << 8) +#define AT91_SMC_DBW (3 << 12) /* Data Bus Width */ +#define AT91_SMC_DBW_8 (0 << 12) +#define AT91_SMC_DBW_16 (1 << 12) +#define AT91_SMC_DBW_32 (2 << 12) +#define AT91_SMC_TDF (0xf << 16) /* Data Float Time. */ +#define AT91_SMC_TDF_(x) ((x) << 16) +#define AT91_SMC_TDFMODE (1 << 20) /* TDF Optimization - Enabled */ +#define AT91_SMC_PMEN (1 << 24) /* Page Mode Enabled */ +#define AT91_SMC_PS (3 << 28) /* Page Size */ +#define AT91_SMC_PS_4 (0 << 28) +#define AT91_SMC_PS_8 (1 << 28) +#define AT91_SMC_PS_16 (2 << 28) +#define AT91_SMC_PS_32 (3 << 28) +#endif +#endif diff --git a/arch/arm/include/asm/arch-at91/clk.h b/arch/arm/include/asm/arch-at91/clk.h index 1e8522b839..bc43c0ca53 100644 --- a/arch/arm/include/asm/arch-at91/clk.h +++ b/arch/arm/include/asm/arch-at91/clk.h @@ -95,4 +95,5 @@ static inline unsigned long get_mci_clk_rate(void) } int at91_clock_init(unsigned long main_clock); +void at91_periph_clk_enable(int id); #endif /* __ASM_ARM_ARCH_CLK_H__ */ diff --git a/arch/arm/include/asm/arch-at91/hardware.h b/arch/arm/include/asm/arch-at91/hardware.h index 4c4ee703a6..dac322da1e 100644 --- a/arch/arm/include/asm/arch-at91/hardware.h +++ b/arch/arm/include/asm/arch-at91/hardware.h @@ -39,6 +39,8 @@ # include <asm/arch/at91sam9g45.h> #elif defined(CONFIG_AT91SAM9X5) # include <asm/arch/at91sam9x5.h> +#elif defined(CONFIG_AT91SAMA5) +# include <asm/arch/at91sama5.h> #elif defined(CONFIG_AT91CAP9) # include <asm/arch/at91cap9.h> #elif defined(CONFIG_AT91X40) diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h index a676b6d905..ddbf238da1 100644 --- a/arch/arm/include/asm/mach-types.h +++ b/arch/arm/include/asm/mach-types.h @@ -987,6 +987,7 @@ extern unsigned int __machine_arch_type; #define MACH_TYPE_VIT_IBOX 3371 #define MACH_TYPE_DM6441_ESP 3372 #define MACH_TYPE_AT91SAM9X5EK 3373 +#define MACH_TYPE_AT91SAMA5EK 3373 #define MACH_TYPE_LIBRA 3374 #define MACH_TYPE_EASYCRRH 3375 #define MACH_TYPE_TRIPEL 3376 diff --git a/board/atmel/at91sama5ek/Makefile b/board/atmel/at91sama5ek/Makefile new file mode 100644 index 0000000000..bfb26b149d --- /dev/null +++ b/board/atmel/at91sama5ek/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2003-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Stelian Pop <stelian@popies.net> +# Lead Tech Design <www.leadtechdesign.com> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +COBJS-y += at91sama5ek.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(call cmd_link_o_target, $(OBJS) $(SOBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/atmel/at91sama5ek/at91sama5ek.c b/board/atmel/at91sama5ek/at91sama5ek.c new file mode 100644 index 0000000000..4dc5a5b3da --- /dev/null +++ b/board/atmel/at91sama5ek/at91sama5ek.c @@ -0,0 +1,298 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mmc.h> +#include <asm/io.h> +#include <asm/arch/at91sama5_smc.h> +#include <asm/arch/at91_common.h> +#include <asm/arch/at91_pmc.h> +#include <asm/arch/at91_rstc.h> +#include <asm/arch/gpio.h> +#include <asm/arch/clk.h> +#include <lcd.h> +#include <atmel_lcdc.h> +#if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_MACB) +#include <net.h> +#endif +#include <netdev.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* ------------------------------------------------------------------------- */ +/* + * Miscelaneous platform dependent initialisations + */ + +#ifdef CONFIG_CMD_NAND +void at91sama5ek_nand_hw_init(void) +{ + struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC; + + at91_periph_clk_enable(ATMEL_ID_SMC); + + /* Configure SMC CS3 for NAND/SmartMedia */ + writel(AT91_SMC_SETUP_NWE(2) | AT91_SMC_SETUP_NCS_WR(1) | + AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(1), + &smc->cs[3].setup); + writel(AT91_SMC_PULSE_NWE(3) | AT91_SMC_PULSE_NCS_WR(5) | + AT91_SMC_PULSE_NRD(3) | AT91_SMC_PULSE_NCS_RD(5), + &smc->cs[3].pulse); + writel(AT91_SMC_CYCLE_NWE(8) | AT91_SMC_CYCLE_NRD(8), + &smc->cs[3].cycle); + writel(AT91_SMC_TIMINGS_TCLR(3) | AT91_SMC_TIMINGS_TADL(10) | + AT91_SMC_TIMINGS_TAR(3) | AT91_SMC_TIMINGS_TRR(4) | + AT91_SMC_TIMINGS_TWB(5) | AT91_SMC_TIMINGS_RBNSEL(3)| + AT91_SMC_TIMINGS_NFSEL(1), &smc->cs[3].timings); + writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE | + AT91_SMC_MODE_EXNW_DISABLE | +#ifdef CONFIG_SYS_NAND_DBW_16 + AT91_SMC_MODE_DBW_16 | +#else /* CONFIG_SYS_NAND_DBW_8 */ + AT91_SMC_MODE_DBW_8 | +#endif + AT91_SMC_MODE_TDF_CYCLE(3), + &smc->cs[3].mode); +} +#endif + +#ifdef CONFIG_CMD_USB +static void at91sama5ek_usb_hw_init(void) +{ + at91_set_pio_output(AT91_PIO_PORTD, 25, 0); + at91_set_pio_output(AT91_PIO_PORTD, 26, 0); + at91_set_pio_output(AT91_PIO_PORTD, 27, 0); +} +#endif + +#ifdef CONFIG_GENERIC_ATMEL_MCI +static void at91sama5ek_mci_hw_init(void) +{ + at91_mci_hw_init(); +} +#endif + +#ifdef CONFIG_MACB +static void at91sama5ek_macb_hw_init(void) +{ + at91_macb_hw_init(); +} +#endif + +#ifdef CONFIG_GMACB +static void at91sama5ek_gmacb_hw_init(void) +{ + at91_gmacb_hw_init(); +} +#endif + +#ifdef CONFIG_LCD + +vidinfo_t panel_info = { + vl_col: 800, + vl_row: 480, + vl_clk: 24000000, + vl_sync: ATMEL_LCDC_INVLINE_NORMAL | + ATMEL_LCDC_INVFRAME_NORMAL, + vl_bpix: LCD_BPP, + vl_tft: 1, + vl_hsync_len: 128, + vl_left_margin: 64, + vl_right_margin:64, + vl_vsync_len: 2, + vl_upper_margin:22, + vl_lower_margin:21, + mmio : ATMEL_BASE_LCDC, +}; + + +void lcd_enable(void) +{ + at91_set_a_periph(AT91_PIO_PORTA, 29, 1); /* power up */ +} + +void lcd_disable(void) +{ + at91_set_a_periph(AT91_PIO_PORTA, 29, 0); /* power down */ +} + +static void at91sama5ek_lcd_hw_init(void) +{ + gd->fb_base = CONFIG_AT91SAMA5_LCD_BASE; + + at91_lcd_hw_init(); +} + +#ifdef CONFIG_LCD_INFO +#include <nand.h> +#include <version.h> + +void lcd_show_board_info(void) +{ + ulong dram_size, nand_size; + int i; + char temp[32]; + + lcd_printf ("%s\n", U_BOOT_VERSION); + lcd_printf ("(C) 2012 ATMEL Corp\n"); + lcd_printf ("at91support@atmel.com\n"); + lcd_printf ("%s CPU at %s MHz\n", + get_cpu_name(), + strmhz(temp, get_cpu_clk_rate())); + + dram_size = 0; + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) + dram_size += gd->bd->bi_dram[i].size; + nand_size = 0; +#ifdef CONFIG_CMD_NAND + for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) + nand_size += nand_info[i].size; +#endif + lcd_printf (" %ld MB SDRAM, %ld MB NAND\n", + dram_size >> 20, + nand_size >> 20 ); +} +#endif /* CONFIG_LCD_INFO */ +#endif + +int board_early_init_f(void) +{ +#ifdef CONFIG_USART1 + at91_serial1_hw_init(); +#else + at91_seriald_hw_init(); +#endif + return 0; +} + +int board_init(void) +{ + /* Enable Ctrlc */ + console_init_f(); + + /* arch number of AT91SAMA5EK-Board */ +#if defined CONFIG_AT91SAMA5EK + gd->bd->bi_arch_number = MACH_TYPE_AT91SAMA5EK; +#endif + + /* adress of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + +#ifdef CONFIG_CMD_NAND + at91sama5ek_nand_hw_init(); +#endif +#ifdef CONFIG_CMD_USB + at91sama5ek_usb_hw_init(); +#endif +#ifdef CONFIG_GENERIC_ATMEL_MCI + at91sama5ek_mci_hw_init(); +#endif +#ifdef CONFIG_SYS_USE_DATAFLASH + at91_spi0_hw_init(1 << 0); +#endif +#ifdef CONFIG_ATMEL_SPI + at91_spi0_hw_init(1 << 4); +#endif +#ifdef CONFIG_MACB + if(has_emac()) + at91sama5ek_macb_hw_init(); +#endif +#ifdef CONFIG_GMACB + if (has_gmac()) + at91sama5ek_gmacb_hw_init(); +#endif +#ifdef CONFIG_LCD + if (has_lcdc()) + at91sama5ek_lcd_hw_init(); +#endif + return 0; +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *) CONFIG_SYS_SDRAM_BASE, + CONFIG_SYS_SDRAM_SIZE); + return 0; +} + +#ifdef CONFIG_RESET_PHY_R +void reset_phy(void) +{ +} +#endif + +int board_eth_init(bd_t *bis) +{ + int rc = 0; +#ifdef CONFIG_MACB + if (has_emac()) + rc = macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0x00); +#endif +#ifdef CONFIG_GMACB + if (has_gmac()) + rc = gmacb_eth_initialize(0, (void *)ATMEL_BASE_GMAC, 0x00); +#endif + return rc; +} + +#ifdef CONFIG_GENERIC_ATMEL_MCI +int board_mmc_init(bd_t *bis) +{ + int rc = 0; + + rc = atmel_mci_init((void *)ATMEL_BASE_MCI0); + + return rc; +} +#endif + +/* SPI chip select control */ +#ifdef CONFIG_ATMEL_SPI +#include <spi.h> + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs < 4; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + switch(slave->cs) { + case 0: + default: + at91_set_pio_output(AT91_PIO_PORTD, 13, 0); + break; + } +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + switch(slave->cs) { + case 0: + default: + at91_set_pio_output(AT91_PIO_PORTD, 13, 1); + break; + } +} +#endif /* CONFIG_ATMEL_SPI */ diff --git a/board/atmel/at91sama5ek/config.mk b/board/atmel/at91sama5ek/config.mk new file mode 100644 index 0000000000..6589a12a93 --- /dev/null +++ b/board/atmel/at91sama5ek/config.mk @@ -0,0 +1 @@ +CONFIG_SYS_TEXT_BASE = 0x26f00000 diff --git a/boards.cfg b/boards.cfg index 7c1fc7427a..7472da7f19 100644 --- a/boards.cfg +++ b/boards.cfg @@ -94,6 +94,9 @@ at91sam9g20ek_dataflash_cs0 arm arm926ejs at91sam9260ek atmel at91sam9g20ek_dataflash_cs1 arm arm926ejs at91sam9260ek atmel at91 at91sam9260ek:AT91SAM9G20,SYS_USE_DATAFLASH_CS1 at91sam9g20ek_nandflash arm arm926ejs at91sam9260ek atmel at91 at91sam9260ek:AT91SAM9G20,SYS_USE_NANDFLASH at91sam9m10g45ek_nandflash arm arm926ejs at91sam9m10g45ek atmel at91 at91sam9m10g45ek:AT91SAM9M10G45,SYS_USE_NANDFLASH +at91sama5ek_nandflash arm armv7 at91sama5ek atmel at91 at91sama5ek:AT91SAMA5,SYS_USE_NANDFLASH +at91sama5ek_serialflash arm armv7 at91sama5ek atmel at91 at91sama5ek:AT91SAMA5,SYS_USE_SERIALFLASH +at91sama5ek_sdcard arm armv7 at91sama5ek atmel at91 at91sama5ek:AT91SAMA5,SYS_USE_MMC at91sam9rlek_dataflash arm arm926ejs at91sam9rlek atmel at91 at91sam9rlek:AT91SAM9RL,SYS_USE_DATAFLASH at91sam9rlek_nandflash arm arm926ejs at91sam9rlek atmel at91 at91sam9rlek:AT91SAM9RL,SYS_USE_NANDFLASH at91sam9x5ek_nandflash arm arm926ejs at91sam9x5ek atmel at91 at91sam9x5ek:AT91SAM9X5,SYS_USE_NANDFLASH diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 4968c5e491..1e104f6fe1 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -83,10 +83,17 @@ static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen) blklen &= 0xfffc; /* On some platforms RDPROOF and WRPROOF are ignored */ +#ifdef CONFIG_AT91SAMA5 + writel((MMCI_BF(CLKDIV, clkdiv) + | MMCI_BIT(RDPROOF) + | MMCI_BIT(WRPROOF)), &mci->mr); + writel((blklen << 16), &mci->blkr); +#else writel((MMCI_BF(CLKDIV, clkdiv) | MMCI_BF(BLKLEN, blklen) | MMCI_BIT(RDPROOF) | MMCI_BIT(WRPROOF)), &mci->mr); +#endif initialized = 1; } @@ -183,6 +190,10 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) /* Figure out the transfer arguments */ cmdr = mci_encode_cmd(cmd, data, &error_flags); + if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) + || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) + writel(data->blocks | mmc->read_bl_len << 16, &mci->blkr); + /* Send the command */ writel(cmd->cmdarg, &mci->argr); writel(cmdr, &mci->cmdr); diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index 39535497f8..0e69ac8ba0 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -107,6 +107,7 @@ const struct nand_flash_dev nand_flash_ids[] = { /* 8 Gigabit */ {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, LP_OPTIONS}, {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, LP_OPTIONS}, + {"NAND 1GiB 3,3V 8-bit", 0x38, 0, 1024, 0, LP_OPTIONS}, {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, LP_OPTIONS16}, {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, LP_OPTIONS16}, diff --git a/drivers/mtd/spi/atmel.c b/drivers/mtd/spi/atmel.c index 006f6d5d04..2f5e83f040 100644 --- a/drivers/mtd/spi/atmel.c +++ b/drivers/mtd/spi/atmel.c @@ -25,6 +25,33 @@ #define AT45_STATUS_P2_PAGE_SIZE (1 << 0) #define AT45_STATUS_READY (1 << 7) +/* AT25-specific commands */ +#define CMD_AT25_READ_STATUS 0x05 +#define CMD_AT25_WRITE_STATUS 0x01 + +#define CMD_AT25_BYTE_PAGE_PROGRAM 0x02 +#define CMD_AT25_ERASE_BLOCK_4K 0x20 +#define CMD_AT25_ERASE_BLOCK_32K 0x52 +#define CMD_AT25_ERASE_BLOCK_64K 0xD8 + +#define CMD_AT25_WRITE_ENABLE 0x06 +#define CMD_AT25_WRITE_DISABLE 0x04 + +/* AT25 status register bits */ +#define AT25_STATUS_READYBUSY (1 << 0) +#define AT25_STATUS_READYBUSY_READY (0 << 0) +#define AT25_STATUS_READYBUSY_BUSY (1 << 0) +#define AT25_ERASE_PROGRAM_ERROR (1 << 5) +#define AT25_STATUS_SWP (3 << 2) +#define AT25_STATUS_SWP_PROTECTALL (3 << 2) +#define AT25_STATUS_SWP_PROTECTSOME (1 << 2) +#define AT25_STATUS_SWP_PROTECTNONE (0 << 2) +#define AT25_STATUS_SPRL (1 << 7) +#define AT25_STATUS_SPRL_UNLOCKED (0 << 7) +#define AT25_STATUS_SPRL_LOCKED (1 << 7) + +#define BLOCK_SIZE_4K (4 * 1024) + /* DataFlash family IDs, as obtained from the second idcode byte */ #define DF_FAMILY_AT26F 0 #define DF_FAMILY_AT45 1 @@ -111,10 +138,10 @@ static const struct atmel_spi_flash_params atmel_spi_flash_table[] = { }, { .idcode1 = 0x47, - .l2_page_size = 8, - .pages_per_block = 16, - .blocks_per_sector = 16, - .nr_sectors = 64, + .l2_page_size = 8, /* 256 bytes per page */ + .pages_per_block = 16, /* 4k bytes per block */ + .blocks_per_sector = 16, /* 64k bytes per sector*/ + .nr_sectors = 64, /* 64 sectors */ .name = "AT25DF321", }, }; @@ -178,6 +205,20 @@ static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset) cmd[2] = byte_addr; } +static int dataflash_read_fast_p2(struct spi_flash *flash, + u32 offset, size_t len, void *buf) +{ + u8 cmd[5]; + + cmd[0] = CMD_READ_ARRAY_FAST; + cmd[1] = offset >> 16; + cmd[2] = offset >> 8; + cmd[3] = offset; + cmd[4] = 0x00; + + return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len); +} + static int dataflash_read_fast_at45(struct spi_flash *flash, u32 offset, size_t len, void *buf) { @@ -336,7 +377,7 @@ out: /* * TODO: the two erase funcs (_p2/_at45) should get unified ... */ -static int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len) +int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len) { struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); unsigned long page_size; @@ -395,7 +436,7 @@ out: return ret; } -static int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len) +int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len) { struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); unsigned long page_addr; @@ -458,10 +499,259 @@ out: return ret; } +static int at25_read_status(struct spi_flash *flash) +{ + struct spi_slave *spi = flash->spi; + int ret; + u8 cmd = CMD_AT25_READ_STATUS; + u8 status; + + ret = spi_flash_cmd_read(spi, &cmd, 1, &status, 1); + + if (ret < 0) { + debug("SF: Error occured when read AT25 status\n"); + return ret; + } else + return status; +} + +static int at25_wait_ready(struct spi_flash *flash, unsigned long timeout) +{ + unsigned long timebase; + int ret; + u8 status; + + timebase = get_timer(0); + + do { + ret = at25_read_status(flash); + if (ret < 0) + return -1; + else + status = ret; + + if ((status & AT25_STATUS_READYBUSY) + == AT25_STATUS_READYBUSY_READY) + break; + } while (get_timer(timebase) < timeout); + + if ((status & AT25_STATUS_READYBUSY) == AT25_STATUS_READYBUSY_READY) + return 0; + + /* Timed out */ + return -1; +} + +static int at25_write_status(struct spi_flash *flash, u8 data) +{ + struct spi_slave *spi = flash->spi; + u8 cmd = CMD_AT25_WRITE_STATUS; + + return spi_flash_cmd_write(spi, &cmd, 1, &data, 1); +} + +static int at25_write_enable(struct spi_flash *flash, int is_enable) +{ + struct spi_slave *spi = flash->spi; + int ret; + u8 cmd; + + if (is_enable) + cmd = CMD_AT25_WRITE_ENABLE; + else + cmd = CMD_AT25_WRITE_DISABLE; + + ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN); + if (ret) + return -1; + + /* Deactivate CS */ + spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END); + + return 0; +} + +static int at25_unprotect(struct spi_flash *flash) +{ + int ret; + u8 status; + + ret = at25_read_status(flash); + if (ret < 0) + debug("SF: Read AT25 status failed\n"); + else + status = ret; + + if ((status & AT25_STATUS_SWP) == AT25_STATUS_SWP_PROTECTNONE) { + /* Protection already disabled */ + return 0; + } + + /* Check if sector protection registers are locked */ + if ((status & AT25_STATUS_SPRL) == AT25_STATUS_SPRL_LOCKED) { + /* Unprotect sector protection registers. */ + at25_write_enable(flash, 1); + at25_write_status(flash, 0); + } + + /* Perform a global unprotect command */ + at25_write_enable(flash, 1); + at25_write_status(flash, 0); + + /* Check the new status */ + status = at25_read_status(flash); + if (ret < 0) + return -1; + + if ((status & (AT25_STATUS_SPRL | AT25_STATUS_SWP)) != 0) { + debug("SF: Unprotect AT25 failed\n"); + return -1; + } else + return 0; +} + +int dataflash_erase_block_at25(struct spi_flash *flash, u32 offset) +{ + /* Using 4k block erase. */ + u32 addr = offset; + int ret; + u8 cmd[4]; + + if (offset % BLOCK_SIZE_4K != 0) + return -1; + + ret = at25_write_enable(flash, 1); + if (ret < 0) { + debug("SF: Enable write AT25 failed\n"); + return ret; + } + + cmd[0] = CMD_AT25_ERASE_BLOCK_4K; + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr; + ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0); + if (ret < 0) { + debug("SF: AT25 4k block erase failed\n"); + return ret; + } + + ret = at25_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT); + if (ret < 0) { + debug("SF: AT25 4k block erase timed out\n"); + return ret; + } + + return ret; +} + +int dataflash_erase_at25(struct spi_flash *flash, u32 offset, size_t len) +{ + int ret; + u32 addr; + + /* + * TODO: This function currently uses 4k block erase only. We can + * probably speed things up by using 32k/64k block erase or chip + * erase when possible. + */ + + if (offset % BLOCK_SIZE_4K || len % BLOCK_SIZE_4K) { + debug("SF: Erase offset/length not multiple of block size\n"); + return -1; + } + + ret = spi_claim_bus(flash->spi); + if (ret) { + debug("SF: Unable to claim SPI bus\n"); + return ret; + } + + ret = at25_unprotect(flash); + if (ret < 0) + goto out; + + /* Use 4k block erase. */ + for (addr = offset; addr < offset + len; addr += BLOCK_SIZE_4K) { + if (offset % BLOCK_SIZE_4K != 0) + addr = (addr >> 12) << 12; /* 4k size align. */ + + ret = dataflash_erase_block_at25(flash, addr); + if (ret < 0) + goto out; + } + + debug("SF: AT25: Successfully erased %zu bytes @ 0x%x\n", + len, offset); + ret = 0; +out: + spi_release_bus(flash->spi); + return ret; +} + +int dataflash_write_at25(struct spi_flash *flash, + u32 offset, size_t len, const void *buf) +{ + struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); + unsigned long page_size; + size_t chunk_len; + size_t actual; + int ret; + u8 status; + u32 addr; + u8 cmd[4]; + u8 *data = (u8 *)buf; + + page_size = 1 << (asf->params->l2_page_size); + + ret = spi_claim_bus(flash->spi); + if (ret) { + debug("SF: Unable to claim SPI bus\n"); + return ret; + } + + ret = at25_read_status(flash); + if (ret < 0) + goto out; + else + status = ret; + + /* Using page programming. */ + for (actual = 0; actual < len; actual += chunk_len, data += chunk_len) { + chunk_len = min(page_size, len - actual); + /* using page programming. */ + ret = at25_write_enable(flash, 1); + if (ret < 0) + goto out; + + addr = offset + actual; + cmd[0] = CMD_AT25_BYTE_PAGE_PROGRAM; + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr; + + ret = spi_flash_cmd_write(flash->spi, cmd, 4, data, chunk_len); + if (ret < 0) { + debug("SF: Page programming AT25 failed\n"); + goto out; + } + + ret = at25_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT); + if (ret < 0) { + debug("SF: AT25 page programming timed out\n"); + goto out; + } + } + +out: + spi_release_bus(flash->spi); + return 0; +} + struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) { const struct atmel_spi_flash_params *params; - unsigned page_size; + unsigned long page_size; unsigned int family; struct atmel_spi_flash *asf; unsigned int i; @@ -513,7 +803,7 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) asf->flash.erase = dataflash_erase_at45; page_size += 1 << (params->l2_page_size - 5); } else { - asf->flash.read = spi_flash_cmd_read_fast; + asf->flash.read = dataflash_read_fast_p2; asf->flash.write = dataflash_write_p2; asf->flash.erase = dataflash_erase_p2; } @@ -542,6 +832,9 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) * params->blocks_per_sector * params->nr_sectors; + debug("SF: Detected %s with page size %lu, total %u bytes\n", + params->name, page_size, asf->flash.size); + return &asf->flash; err: diff --git a/drivers/net/Makefile b/drivers/net/Makefile index e4abac7c8f..b1da93f8f2 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -52,6 +52,7 @@ COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o COBJS-$(CONFIG_LAN91C96) += lan91c96.o COBJS-$(CONFIG_MACB) += macb.o +COBJS-$(CONFIG_GMACB) += gmacb.o COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o COBJS-$(CONFIG_MPC512x_FEC) += mpc512x_fec.o diff --git a/drivers/net/gmacb.c b/drivers/net/gmacb.c new file mode 100644 index 0000000000..af1f552ab0 --- /dev/null +++ b/drivers/net/gmacb.c @@ -0,0 +1,622 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <common.h> + +/* + * The u-boot networking stack is a little weird. It seems like the + * networking core allocates receive buffers up front without any + * regard to the hardware that's supposed to actually receive those + * packets. + * + * The MACB receives packets into 128-byte receive buffers, so the + * buffers allocated by the core isn't very practical to use. We'll + * allocate our own, but we need one such buffer in case a packet + * wraps around the DMA ring so that we have to copy it. + * + * Therefore, define CONFIG_SYS_RX_ETH_BUFFER to 1 in the board-specific + * configuration header. This way, the core allocates one RX buffer + * and one TX buffer, each of which can hold a ethernet packet of + * maximum size. + * + * For some reason, the networking core unconditionally specifies a + * 32-byte packet "alignment" (which really should be called + * "padding"). MACB shouldn't need that, but we'll refrain from any + * core modifications here... + */ + +#include <net.h> +#include <netdev.h> +#include <malloc.h> +#include <miiphy.h> + +#include <linux/mii.h> +#include <asm/io.h> +#include <asm/dma-mapping.h> +#include <asm/arch/clk.h> + +#include "gmacb.h" + +#define barrier() asm volatile("" ::: "memory") + +#define CONFIG_SYS_MACB_RX_BUFFER_SIZE 4096 +#define CONFIG_SYS_MACB_RX_RING_SIZE (CONFIG_SYS_MACB_RX_BUFFER_SIZE / 128) +#define CONFIG_SYS_MACB_TX_RING_SIZE 16 +#define CONFIG_SYS_MACB_TX_TIMEOUT 1000 +#define CONFIG_SYS_MACB_AUTONEG_TIMEOUT 5000000 + +struct macb_dma_desc { + u32 addr; + u32 ctrl; +} __attribute__ ((packed, aligned(8))); + +#define RXADDR_USED 0x00000001 +#define RXADDR_WRAP 0x00000002 + +#define RXBUF_FRMLEN_MASK 0x00001fff +#define RXBUF_FRAME_START 0x00004000 +#define RXBUF_FRAME_END 0x00008000 +#define RXBUF_TYPEID_MATCH 0x00400000 +#define RXBUF_ADDR4_MATCH 0x06000000 +#define RXBUF_ADDR3_MATCH 0x04000000 +#define RXBUF_ADDR2_MATCH 0x02000000 +#define RXBUF_ADDR1_MATCH 0x00000000 +#define RXBUF_BROADCAST 0x80000000 + +#define TXBUF_FRMLEN_MASK 0x00003fff +#define TXBUF_FRAME_END 0x00008000 +#define TXBUF_NOCRC 0x00010000 +#define TXBUF_FCS_ERR 0x00700000 +#define TXBUF_COL 0x04000000 +#define TXBUF_FRAME_COR 0x08000000 +#define TXBUF_UNDERRUN 0x10000000 +#define TXBUF_MAXRETRY 0x20000000 +#define TXBUF_WRAP 0x40000000 +#define TXBUF_USED 0x80000000 + +struct macb_device { + void *regs; + + unsigned int rx_tail; + unsigned int tx_head; + unsigned int tx_tail; + + void *rx_buffer; + void *tx_buffer; + struct macb_dma_desc *rx_ring; + struct macb_dma_desc *tx_ring; + + unsigned long rx_buffer_dma; + unsigned long rx_ring_dma; + unsigned long tx_ring_dma; + + const struct device *dev; + struct eth_device netdev; + unsigned short phy_addr; +}; +#define to_macb(_nd) container_of(_nd, struct macb_device, netdev) + +static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value) +{ + unsigned long netctl; + unsigned long netstat; + unsigned long frame; + + netctl = macb_readl(macb, NCR); + netctl |= MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + + frame = (MACB_BF(CLTTO, 1) + | MACB_BF(OP, 1) + | MACB_BF(PHYA, macb->phy_addr) + | MACB_BF(REGA, reg) + | MACB_BF(WTN, 2) + | MACB_BF(DATA, value)); + macb_writel(macb, MAN, frame); + + do { + netstat = macb_readl(macb, NSR); + } while (!(netstat & MACB_BIT(IDLE))); + + netctl = macb_readl(macb, NCR); + netctl &= ~MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); +} + +static u16 macb_mdio_read(struct macb_device *macb, u8 reg) +{ + unsigned long netctl; + unsigned long netstat; + unsigned long frame; + + netctl = macb_readl(macb, NCR); + netctl |= MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + + frame = (MACB_BF(CLTTO, 1) + | MACB_BF(OP, 2) + | MACB_BF(PHYA, macb->phy_addr) + | MACB_BF(REGA, reg) + | MACB_BF(WTN, 2)); + macb_writel(macb, MAN, frame); + + do { + netstat = macb_readl(macb, NSR); + } while (!(netstat & MACB_BIT(IDLE))); + + frame = macb_readl(macb, MAN); + + netctl = macb_readl(macb, NCR); + netctl &= ~MACB_BIT(MPE); + macb_writel(macb, NCR, netctl); + + return MACB_BFEXT(DATA, frame); +} + +#if defined(CONFIG_CMD_MII) + +int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value) +{ + struct eth_device *dev = eth_get_dev_by_name(devname); + struct macb_device *macb = to_macb(dev); + + if ( macb->phy_addr != phy_adr ) + return -1; + + *value = macb_mdio_read(macb, reg); + + return 0; +} + +int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) +{ + struct eth_device *dev = eth_get_dev_by_name(devname); + struct macb_device *macb = to_macb(dev); + + if ( macb->phy_addr != phy_adr ) + return -1; + + macb_mdio_write(macb, reg, value); + + return 0; +} +#endif + + +#if defined(CONFIG_CMD_NET) + +static int macb_send(struct eth_device *netdev, volatile void *packet, + int length) +{ + struct macb_device *macb = to_macb(netdev); + unsigned long paddr, ctrl; + unsigned int tx_head = macb->tx_head; + int i; + + paddr = dma_map_single(packet, length, DMA_TO_DEVICE); + + macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | macb_readl(macb, NCR)); + ctrl = length & TXBUF_FRMLEN_MASK; + ctrl |= TXBUF_FRAME_END; + if (tx_head == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) { + ctrl |= TXBUF_WRAP; + macb->tx_head = 0; + } else + macb->tx_head++; + + macb->tx_ring[tx_head].ctrl = ctrl; + macb->tx_ring[tx_head].addr = paddr; + barrier(); + + macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); + + /* + * I guess this is necessary because the networking core may + * re-use the transmit buffer as soon as we return... + */ + for (i = 0; i <= CONFIG_SYS_MACB_TX_TIMEOUT; i++) { + barrier(); + ctrl = macb->tx_ring[tx_head].ctrl; + if (ctrl & TXBUF_USED) + break; + udelay(1); + } + + dma_unmap_single(packet, length, paddr); + + if (i <= CONFIG_SYS_MACB_TX_TIMEOUT) { + if (ctrl & TXBUF_UNDERRUN) + printf("%s: TX underrun\n", netdev->name); + } else { + printf("%s: TX timeout\n", netdev->name); + } + + /* No one cares anyway */ + return 0; +} + +static void reclaim_rx_buffers(struct macb_device *macb, + unsigned int new_tail) +{ + unsigned int i; + + i = macb->rx_tail; + while (i > new_tail) { + macb->rx_ring[i].addr &= ~RXADDR_USED; + i++; + if (i > CONFIG_SYS_MACB_RX_RING_SIZE) + i = 0; + } + + while (i < new_tail) { + macb->rx_ring[i].addr &= ~RXADDR_USED; + i++; + } + + barrier(); + macb->rx_tail = new_tail; +} + +static int macb_recv(struct eth_device *netdev) +{ + struct macb_device *macb = to_macb(netdev); + unsigned int rx_tail = macb->rx_tail; + void *buffer; + int length; + int wrapped = 0; + u32 status; + + for (;;) { + if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED)) + return -1; + + status = macb->rx_ring[rx_tail].ctrl; + if (status & RXBUF_FRAME_START) { + if (rx_tail != macb->rx_tail) + reclaim_rx_buffers(macb, rx_tail); + wrapped = 0; + } + + if (status & RXBUF_FRAME_END) { + buffer = macb->rx_buffer + 128 * macb->rx_tail; + length = status & RXBUF_FRMLEN_MASK; + if (wrapped) { + unsigned int headlen, taillen; + + headlen = 128 * (CONFIG_SYS_MACB_RX_RING_SIZE + - macb->rx_tail); + taillen = length - headlen; + memcpy((void *)NetRxPackets[0], + buffer, headlen); + memcpy((void *)NetRxPackets[0] + headlen, + macb->rx_buffer, taillen); + buffer = (void *)NetRxPackets[0]; + } + + NetReceive(buffer, length); + if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE) + rx_tail = 0; + reclaim_rx_buffers(macb, rx_tail); + } else { + if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE) { + wrapped = 1; + rx_tail = 0; + } + } + barrier(); + } + + return 0; +} + +static void macb_phy_reset(struct macb_device *macb) +{ + struct eth_device *netdev = &macb->netdev; + int i; + u16 status, adv; + + adv = ADVERTISE_CSMA | ADVERTISE_ALL; + macb_mdio_write(macb, MII_ADVERTISE, adv); + printf("%s: Starting autonegotiation...\n", netdev->name); + macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE + | BMCR_ANRESTART)); + + for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { + status = macb_mdio_read(macb, MII_BMSR); + if (status & BMSR_ANEGCOMPLETE) + break; + udelay(100); + } + + if (status & BMSR_ANEGCOMPLETE) + printf("%s: Autonegotiation complete\n", netdev->name); + else + printf("%s: Autonegotiation timed out (status=0x%04x)\n", + netdev->name, status); +} + +#ifdef CONFIG_MACB_SEARCH_PHY +static int macb_phy_find(struct macb_device *macb) +{ + int i; + u16 phy_id; + + /* Search for PHY... */ + for (i = 0; i < 32; i++) { + macb->phy_addr = i; + phy_id = macb_mdio_read(macb, MII_PHYSID1); + if (phy_id != 0xffff) { + printf("%s: PHY present at %d\n", macb->netdev.name, i); + return 1; + } + } + + /* PHY isn't up to snuff */ + printf("%s: PHY not found", macb->netdev.name); + + return 0; +} +#endif /* CONFIG_MACB_SEARCH_PHY */ + + +static int macb_phy_init(struct macb_device *macb) +{ + struct eth_device *netdev = &macb->netdev; + u32 ncfgr; + u16 phy_id, status, adv, lpa; + int media, speed, duplex; + int i; + +#ifdef CONFIG_MACB_SEARCH_PHY + /* Auto-detect phy_addr */ + if (!macb_phy_find(macb)) { + return 0; + } +#endif /* CONFIG_MACB_SEARCH_PHY */ + + /* Check if the PHY is up to snuff... */ + phy_id = macb_mdio_read(macb, MII_PHYSID1); + if (phy_id == 0xffff) { + printf("%s: No PHY present\n", netdev->name); + return 0; + } + + /* Timing configuration for KSZ9021RN PHY */ + macb_mdio_write(macb, 11, 260 | 0x8000); + macb_mdio_write(macb, 12, 0xF2F4); + macb_mdio_write(macb, 11, 261 | 0x8000); + macb_mdio_write(macb, 12, 0x2222); + + status = macb_mdio_read(macb, MII_BMSR); + if (!(status & BMSR_LSTATUS)) { + /* Try to re-negotiate if we don't have link already. */ + macb_phy_reset(macb); + for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { + status = macb_mdio_read(macb, MII_BMSR); + if (status & BMSR_LSTATUS) + break; + udelay(100); + } + } + + if (!(status & BMSR_LSTATUS)) { + printf("%s: link down (status: 0x%04x)\n", + netdev->name, status); + return 0; + } else { + /* Judge whether work in 1000Base-T mode */ + adv = macb_mdio_read(macb, MII_STAT1000); + lpa = macb_mdio_read(macb, MII_CTRL1000); + if (adv & (1 << 11)) { + speed = 1000; + + if (lpa & (1 << 9)) { + duplex = 1; + } else { + duplex = 0; + } + + printf("%s: link up, %dMbps %s-duplex (lpa: 0x%04x)\n", + netdev->name, + speed, + duplex ? "full" : "half", + lpa); + + ncfgr = macb_readl(macb, NCFGR); + ncfgr &= ~(MACB_BIT(GBE) | MACB_BIT (SPD) | MACB_BIT(FD)); + if (speed) + ncfgr |= MACB_BIT(GBE); + if (duplex) + ncfgr |= MACB_BIT(FD); + macb_writel(macb, NCFGR, ncfgr); + } else { + /* Judge whether work in 100Base-T mode */ + adv = macb_mdio_read(macb, MII_ADVERTISE); + lpa = macb_mdio_read(macb, MII_LPA); + media = mii_nway_result(lpa & adv); + speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) + ? 1 : 0); + duplex = (media & ADVERTISE_FULL) ? 1 : 0; + + printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", + netdev->name, + speed? "100" : "10", + duplex ? "full" : "half", + lpa); + + ncfgr = macb_readl(macb, NCFGR); + ncfgr &= ~(MACB_BIT(GBE) | MACB_BIT(SPD) | MACB_BIT(FD)); + if (speed) + ncfgr |= MACB_BIT(SPD); + if (duplex) + ncfgr |= MACB_BIT(FD); + macb_writel(macb, NCFGR, ncfgr); + } + } + + return 1; +} + +static int macb_init(struct eth_device *netdev, bd_t *bd) +{ + struct macb_device *macb = to_macb(netdev); + unsigned long paddr; + int i; + + /* + * macb_halt should have been called at some point before now, + * so we'll assume the controller is idle. + */ + + /* initialize DMA descriptors */ + paddr = macb->rx_buffer_dma; + for (i = 0; i < CONFIG_SYS_MACB_RX_RING_SIZE; i++) { + if (i == (CONFIG_SYS_MACB_RX_RING_SIZE - 1)) + paddr |= RXADDR_WRAP; + macb->rx_ring[i].addr = paddr; + macb->rx_ring[i].ctrl = 0; + paddr += 128; + } + for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) { + macb->tx_ring[i].addr = 0; + if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) + macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP; + else + macb->tx_ring[i].ctrl = TXBUF_USED; + } + macb->rx_tail = macb->tx_head = macb->tx_tail = 0; + + macb_writel(macb, RBQB, macb->rx_ring_dma); + macb_writel(macb, TBQB, macb->tx_ring_dma); + + /* choose RMII or MII mode. This depends on the board */ +#ifdef CONFIG_RGMII +#if defined(CONFIG_AT91SAMA5) + macb_writel(macb, UR, MACB_BIT(RGMII)); +#else + macb_writel(macb, UR, 0); +#endif +#endif /* CONFIG_RGMII */ + + if (!macb_phy_init(macb)) + return -1; + + /* Enable TX and RX */ + macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE)); + + return 0; +} + +static void macb_halt(struct eth_device *netdev) +{ + struct macb_device *macb = to_macb(netdev); + u32 ncr, tsr; + + /* Halt the controller and wait for any ongoing transmission to end. */ + ncr = macb_readl(macb, NCR); + ncr |= MACB_BIT(THALT); + macb_writel(macb, NCR, ncr); + + do { + tsr = macb_readl(macb, TSR); + } while (tsr & MACB_BIT(TGO)); + + /* Disable TX and RX, and clear statistics */ + macb_writel(macb, NCR, MACB_BIT(CLRSTAT)); +} + +static int macb_write_hwaddr(struct eth_device *dev) +{ + struct macb_device *macb = to_macb(dev); + u32 hwaddr_bottom; + u16 hwaddr_top; + + /* set hardware address */ + hwaddr_bottom = dev->enetaddr[0] | dev->enetaddr[1] << 8 | + dev->enetaddr[2] << 16 | dev->enetaddr[3] << 24; + macb_writel(macb, SA1B, hwaddr_bottom); + hwaddr_top = dev->enetaddr[4] | dev->enetaddr[5] << 8; + macb_writel(macb, SA1T, hwaddr_top); + return 0; +} + +int gmacb_eth_initialize(int id, void *regs, unsigned int phy_addr) +{ + struct macb_device *macb; + struct eth_device *netdev; + unsigned long macb_hz; + u32 ncfgr; + + macb = malloc(sizeof(struct macb_device)); + if (!macb) { + printf("Error: Failed to allocate memory for MACB%d\n", id); + return -1; + } + memset(macb, 0, sizeof(struct macb_device)); + + netdev = &macb->netdev; + + macb->rx_buffer = dma_alloc_coherent(CONFIG_SYS_MACB_RX_BUFFER_SIZE, + &macb->rx_buffer_dma); + + macb->rx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_RX_RING_SIZE + * sizeof(struct macb_dma_desc), + &macb->rx_ring_dma); + macb->tx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_TX_RING_SIZE + * sizeof(struct macb_dma_desc), + &macb->tx_ring_dma); + + macb->regs = regs; + macb->phy_addr = phy_addr; + + sprintf(netdev->name, "gmacb%d", id); + netdev->init = macb_init; + netdev->halt = macb_halt; + netdev->send = macb_send; + netdev->recv = macb_recv; + netdev->write_hwaddr = macb_write_hwaddr; + + /* + * Do some basic initialization so that we at least can talk + * to the PHY + */ + macb_hz = get_macb_pclk_rate(id); + if (macb_hz < 20000000) + ncfgr = MACB_BF(CLK, GMACB_CLK_DIV8); + else if (macb_hz < 40000000) + ncfgr = MACB_BF(CLK, GMACB_CLK_DIV16); + else if (macb_hz < 80000000) + ncfgr = MACB_BF(CLK, GMACB_CLK_DIV32); + else if (macb_hz < 120000000) + ncfgr = MACB_BF(CLK, GMACB_CLK_DIV48); + else + ncfgr = MACB_BF(CLK, GMACB_CLK_DIV64); + + macb_writel(macb, NCFGR, ncfgr); + + /* Configuration the Datapath 64 bit */ + macb_writel(macb, NCFGR, MACB_BF(DBW, 1) | macb_readl(macb, NCFGR)); + + eth_register(netdev); + +#if defined(CONFIG_CMD_MII) + miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write); +#endif + return 0; +} + +#endif diff --git a/drivers/net/gmacb.h b/drivers/net/gmacb.h new file mode 100644 index 0000000000..cd755bccc3 --- /dev/null +++ b/drivers/net/gmacb.h @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __DRIVERS_GMACB_H__ +#define __DRIVERS_GMACB_H__ + +/* MACB register offsets */ +#define GMACB_NCR 0x0000 +#define GMACB_NCFGR 0x0004 +#define GMACB_NSR 0x0008 +#define GMACB_UR 0x000c +#define GMACB_DCFGR 0x0010 +#define GMACB_TSR 0x0014 +#define GMACB_RBQB 0x0018 +#define GMACB_TBQB 0x001c +#define GMACB_RSR 0x0020 +#define GMACB_ISR 0x0024 +#define GMACB_IER 0x0028 +#define GMACB_IDR 0x002c +#define GMACB_IMR 0x0030 +#define GMACB_MAN 0x0034 +#define GMACB_RPQ 0x0038 +#define GMACB_TPQ 0x003c +#define GMACB_TPSF 0x0040 +#define GMACB_RPSF 0x0044 +#define GMACB_HRB 0x0080 +#define GMACB_HRT 0x0084 +#define GMACB_SA1B 0x0088 +#define GMACB_SA1T 0x008c +#define GMACB_SA2B 0x0090 +#define GMACB_SA2T 0x0094 +#define GMACB_SA3B 0x0098 +#define GMACB_SA3T 0x009c +#define GMACB_SA4B 0x00a0 +#define GMACB_SA4T 0x00a4 +#define GMACB_TIDM1 0x00a8 +#define GMACB_TIDM2 0x00ac +#define GMACB_TIDM3 0x00b0 +#define GMACB_TIDM4 0x00b4 +#define GMACB_WOL 0x00b8 +#define GMACB_IPGS 0x00bc +#define GMACB_SVLAN 0x00c0 +#define GMACB_TPFCP 0x00c4 +#define GMACB_SAMB1 0x00c8 +#define GMACB_SAMT1 0x00cc + +#define GMACB_FT 0x0108 +#define GMACB_BCFT 0x010c + + + + + /* Bitfields in NCR */ +#define GMACB_LB_OFFSET 0 +#define GMACB_LB_SIZE 1 +#define GMACB_LBL_OFFSET 1 +#define GMACB_LBL_SIZE 1 +#define GMACB_RE_OFFSET 2 +#define GMACB_RE_SIZE 1 +#define GMACB_TE_OFFSET 3 +#define GMACB_TE_SIZE 1 +#define GMACB_MPE_OFFSET 4 +#define GMACB_MPE_SIZE 1 +#define GMACB_CLRSTAT_OFFSET 5 +#define GMACB_CLRSTAT_SIZE 1 +#define GMACB_INCSTAT_OFFSET 6 +#define GMACB_INCSTAT_SIZE 1 +#define GMACB_WESTAT_OFFSET 7 +#define GMACB_WESTAT_SIZE 1 +#define GMACB_BP_OFFSET 8 +#define GMACB_BP_SIZE 1 +#define GMACB_TSTART_OFFSET 9 +#define GMACB_TSTART_SIZE 1 +#define GMACB_THALT_OFFSET 10 +#define GMACB_THALT_SIZE 1 +#define GMACB_NCR_TPF_OFFSET 11 +#define GMACB_NCR_TPF_SIZE 1 +#define GMACB_TZQ_OFFSET 12 +#define GMACB_TZQ_SIZE 1 + + /* Bitfields in NCFGR */ +#define GMACB_SPD_OFFSET 0 +#define GMACB_SPD_SIZE 1 +#define GMACB_FD_OFFSET 1 +#define GMACB_FD_SIZE 1 +#define GMACB_DNVLAN_OFFSET 2 +#define GMACB_DNVLAN_SIZE 1 +#define GMACB_JFRAME_OFFSET 3 +#define GMACB_JFRAME_SIZE 1 +#define GMACB_CAF_OFFSET 4 +#define GMACB_CAF_SIZE 1 +#define GMACB_NBC_OFFSET 5 +#define GMACB_NBC_SIZE 1 +#define GMACB_NCFGR_MTI_OFFSET 6 +#define GMACB_NCFGR_MTI_SIZE 1 +#define GMACB_UNI_OFFSET 7 +#define GMACB_UNI_SIZE 1 +#define MACB_MAXFS_OFFSET 8 +#define MACB_MAXFS_SIZE 1 +#define GMACB_GBE_OFFSET 10 +#define GMACB_GBE_SIZE 1 +#define GMACB_PIS_OFFSET 11 +#define GMACB_PIS_SIZE 1 +#define GMACB_RTY_OFFSET 12 +#define GMACB_RTY_SIZE 1 +#define GMACB_PEN_OFFSET 13 +#define GMACB_PEN_SIZE 1 +#define GMACB_RXBUFO_OFFSET 14 +#define GMACB_RXBUFO_SIZE 2 +#define GMACB_LFERD_OFFSET 16 +#define GMACB_LFERD_SIZE 1 +#define GMACB_RFCS_OFFSET 17 +#define GMACB_RFCS_SIZE 1 +#define GMACB_CLK_OFFSET 18 +#define GMACB_CLK_SIZE 3 +#define GMACB_DBW_OFFSET 21 +#define GMACB_DBW_SIZE 2 + + /* Bitfields in NSR */ +#define GMACB_NSR_LINK_OFFSET 0 +#define GMACB_NSR_LINK_SIZE 1 +#define GMACB_MDIO_OFFSET 1 +#define GMACB_MDIO_SIZE 1 +#define GMACB_IDLE_OFFSET 2 +#define GMACB_IDLE_SIZE 1 + + /* Bitfields in TSR */ +#define GMACB_UBR_OFFSET 0 +#define GMACB_UBR_SIZE 1 +#define GMACB_COL_OFFSET 1 +#define GMACB_COL_SIZE 1 +#define GMACB_TSR_RLE_OFFSET 2 +#define GMACB_TSR_RLE_SIZE 1 +#define GMACB_TGO_OFFSET 3 +#define GMACB_TGO_SIZE 1 +#define GMACB_BEX_OFFSET 4 +#define GMACB_BEX_SIZE 1 +#define GMACB_COMP_OFFSET 5 +#define GMACB_COMP_SIZE 1 +#define GMACB_UND_OFFSET 6 +#define GMACB_UND_SIZE 1 + + /* Bitfields in RSR */ +#define GMACB_BNA_OFFSET 0 +#define GMACB_BNA_SIZE 1 +#define GMACB_REC_OFFSET 1 +#define GMACB_REC_SIZE 1 +#define GMACB_OVR_OFFSET 2 +#define GMACB_OVR_SIZE 1 + + /* Bitfields in ISR/IER/IDR/IMR */ +#define GMACB_MFD_OFFSET 0 +#define GMACB_MFD_SIZE 1 +#define GMACB_RCOMP_OFFSET 1 +#define GMACB_RCOMP_SIZE 1 +#define GMACB_RXUBR_OFFSET 2 +#define GMACB_RXUBR_SIZE 1 +#define GMACB_TXUBR_OFFSET 3 +#define GMACB_TXUBR_SIZE 1 +#define GMACB_ISR_TUND_OFFSET 4 +#define GMACB_ISR_TUND_SIZE 1 +#define GMACB_ISR_RLE_OFFSET 5 +#define GMACB_ISR_RLE_SIZE 1 +#define GMACB_TXERR_OFFSET 6 +#define GMACB_TXERR_SIZE 1 +#define GMACB_TCOMP_OFFSET 7 +#define GMACB_TCOMP_SIZE 1 +#define GMACB_ISR_LINK_OFFSET 9 +#define GMACB_ISR_LINK_SIZE 1 +#define GMACB_ISR_ROVR_OFFSET 10 +#define GMACB_ISR_ROVR_SIZE 1 +#define GMACB_HRESP_OFFSET 11 +#define GMACB_HRESP_SIZE 1 +#define GMACB_PFR_OFFSET 12 +#define GMACB_PFR_SIZE 1 +#define GMACB_PTZ_OFFSET 13 +#define GMACB_PTZ_SIZE 1 + + /* Bitfields in MAN */ +#define GMACB_DATA_OFFSET 0 +#define GMACB_DATA_SIZE 16 +#define GMACB_WTN_OFFSET 16 +#define GMACB_WTN_SIZE 2 +#define GMACB_REGA_OFFSET 18 +#define GMACB_REGA_SIZE 5 +#define GMACB_PHYA_OFFSET 23 +#define GMACB_PHYA_SIZE 5 +#define GMACB_OP_OFFSET 28 +#define GMACB_OP_SIZE 2 +#define GMACB_CLTTO_OFFSET 30 +#define GMACB_CLTTO_SIZE 1 +#define GMACB_WZO_OFFSET 31 +#define GMACB_WZO_SIZE 1 + + /* Bitfields in US */ +#define GMACB_GMII_OFFSET 0 +#define GMACB_GMII_SIZE 1 + + /* Bitfields in USRIO (AT91) */ +#define GMACB_RGMII_OFFSET 0 +#define GMACB_RGMII_SIZE 1 + + /* Bitfields in WOL */ +#define GMACB_IP_OFFSET 0 +#define GMACB_IP_SIZE 16 +#define GMACB_MAG_OFFSET 16 +#define GMACB_MAG_SIZE 1 +#define GMACB_ARP_OFFSET 17 +#define GMACB_ARP_SIZE 1 +#define GMACB_SA1_OFFSET 18 +#define GMACB_SA1_SIZE 1 +#define GMACB_WOL_MTI_OFFSET 19 +#define GMACB_WOL_MTI_SIZE 1 + + /* Constants for CLK */ +#define GMACB_CLK_DIV8 0 +#define GMACB_CLK_DIV16 1 +#define GMACB_CLK_DIV32 2 +#define GMACB_CLK_DIV48 3 +#define GMACB_CLK_DIV64 4 + +/* Constants for MAN register */ +#define GMACB_MAN_SOF 1 +#define GMACB_MAN_WRITE 1 +#define GMACB_MAN_READ 2 +#define GMACB_MAN_CODE 2 + +/* Bit manipulation macros */ +#define MACB_BIT(name) \ + (1 << GMACB_##name##_OFFSET) +#define MACB_BF(name,value) \ + (((value) & ((1 << GMACB_##name##_SIZE) - 1)) \ + << GMACB_##name##_OFFSET) +#define MACB_BFEXT(name,value)\ + (((value) >> GMACB_##name##_OFFSET) \ + & ((1 << GMACB_##name##_SIZE) - 1)) +#define MACB_BFINS(name,value,old) \ + (((old) & ~(((1 << GMACB_##name##_SIZE) - 1) \ + << GMACB_##name##_OFFSET)) \ + | MACB_BF(name,value)) + +/* Register access macros */ +#define macb_readl(port,reg) \ + readl((port)->regs + GMACB_##reg) +#define macb_writel(port,reg,value) \ + writel((value), (port)->regs + GMACB_##reg) + +#endif /* __DRIVERS_MACB_H__ */ diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 0e1ced71c5..f05a566521 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -471,7 +471,8 @@ static int macb_init(struct eth_device *netdev, bd_t *bd) #if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) || \ defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \ - defined(CONFIG_AT91SAM9XE) || defined(CONFIG_AT91SAM9X5) + defined(CONFIG_AT91SAM9XE) || defined(CONFIG_AT91SAM9X5) || \ + defined(CONFIG_AT91SAMA5) macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN)); #else macb_writel(macb, USRIO, 0); @@ -480,7 +481,8 @@ static int macb_init(struct eth_device *netdev, bd_t *bd) #if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) || \ defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \ - defined(CONFIG_AT91SAM9XE) || defined(CONFIG_AT91SAM9X5) + defined(CONFIG_AT91SAM9XE) || defined(CONFIG_AT91SAM9X5) || \ + defined(CONFIG_AT91SAMA5) macb_writel(macb, USRIO, MACB_BIT(CLKEN)); #else macb_writel(macb, USRIO, MACB_BIT(MII)); diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 9532dd9ef6..48de03d36b 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -41,7 +41,8 @@ int usb_cpu_init(void) writel(get_pllb_init(), &pmc->pllbr); while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB) ; -#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \ + || defined(CONFIG_AT91SAMA5) /* Enable UPLL */ writel(readl(&pmc->uckr) | AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr); @@ -52,8 +53,13 @@ int usb_cpu_init(void) writel(AT91_PMC_USBS_USB_UPLL | AT91_PMC_USBDIV_10, &pmc->usb); #endif +#if defined(CONFIG_AT91SAMA5) /* Enable USB host clock. */ + writel(1 << (ATMEL_ID_UHP - 32), &pmc->pcer1); +#else writel(1 << ATMEL_ID_UHP, &pmc->pcer); +#endif + #ifdef CONFIG_AT91SAM9261 writel(ATMEL_PMC_UHP | AT91_PMC_HCK0, &pmc->scer); #else diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index c02ffd8036..860cbcc4d2 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -28,6 +28,9 @@ #include <asm/arch/clk.h> #include <lcd.h> #include <atmel_lcdc.h> +#if defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAMA5) +#include <atmel_9x5_lcdc.h> +#endif int lcd_line_length; int lcd_color_fg; @@ -66,10 +69,187 @@ void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) #endif } +#if defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAMA5) +void lcd_9x5_ctrl_init(void *lcdbase) +{ + unsigned long value; + lcd_dma_desc *desc; + + if (!has_lcdc()) + return; /* No lcdc */ + + /* Disable DISP signal */ + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_DISPDIS); + while ((lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDSR) + & LCDC_LCDSR_DISPSTS)) + udelay(1); + /* Disable synchronization */ + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_SYNCDIS); + while ((lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDSR) + & LCDC_LCDSR_LCDSTS)) + udelay(1); + /* Disable pixel clock */ + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_CLKDIS); + while ((lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDSR) + & LCDC_LCDSR_CLKSTS)) + udelay(1); + /* Disable PWM */ + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_PWMDIS); + while ((lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDSR) + & LCDC_LCDSR_PWMSTS)) + udelay(1); + + /* Set pixel clock */ + value = get_lcdc_clk_rate(0) / panel_info.vl_clk; + if (get_lcdc_clk_rate(0) % panel_info.vl_clk) + value++; + + if (value < 1) { + /* Using system clock as pixel clock */ + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCFG0, + LCDC_LCDCFG0_CLKDIV(0) + | LCDC_LCDCFG0_CGDISHCR + | LCDC_LCDCFG0_CGDISHEO + | LCDC_LCDCFG0_CGDISOVR1 + | LCDC_LCDCFG0_CGDISBASE + | LCDC_LCDCFG0_CLKPOL + | LCDC_LCDCFG0_CLKSEL); + + } else { + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCFG0, + LCDC_LCDCFG0_CLKDIV(value - 2) + | LCDC_LCDCFG0_CGDISHCR + | LCDC_LCDCFG0_CGDISHEO + | LCDC_LCDCFG0_CGDISOVR1 + | LCDC_LCDCFG0_CGDISBASE + | LCDC_LCDCFG0_CLKPOL); + } + + /* Initialize control register 5 */ + value = 0; + + value |= LCDC_LCDCFG5_HSPOL; + value |= LCDC_LCDCFG5_VSPOL; + +#ifndef LCD_OUTPUT_BPP + /* Output is 24bpp */ + value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; +#else + switch (LCD_OUTPUT_BPP) { + case 12: + value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP; + break; + case 16: + value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP; + break; + case 18: + value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP; + break; + case 24: + value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; + break; + default: + BUG(); + break; + } +#endif + + value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME); + value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS); + + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCFG5, value); + + /* Vertical & Horizontal Timing */ + value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1); + value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCFG1, value); + + value = LCDC_LCDCFG2_VBPW(panel_info.vl_lower_margin); + value |= LCDC_LCDCFG2_VFPW(panel_info.vl_upper_margin - 1); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCFG2, value); + + value = LCDC_LCDCFG3_HBPW(panel_info.vl_right_margin - 1); + value |= LCDC_LCDCFG3_HFPW(panel_info.vl_left_margin - 1); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCFG3, value); + + /* Display size */ + value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1); + value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCFG4, value); + + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASECFG0, + LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO); + + switch (NBITS(panel_info.vl_bpix)) { + case 16: + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASECFG1, + LCDC_BASECFG1_RGBMODE_16BPP_RGB_565); + break; + default: + BUG(); + break; + } + + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASECFG2, + LCDC_BASECFG2_XSTRIDE(0)); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASECFG3, 0); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASECFG4, LCDC_BASECFG4_DMA); + + /* Disable all interrupts */ + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDIDR, ~0UL); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASEIDR, ~0UL); + + /* Setup the DMA descriptor, this descriptor will loop to itself */ + desc = (lcd_dma_desc *)(lcdbase - 16); + + desc->address = (u32)lcdbase; + /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ + desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN + | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; + desc->next = (u32)desc; + + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASEADDR, desc->address); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASECTRL, desc->control); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASENEXT, desc->next); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_BASECHER, LCDC_BASECHER_CHEN + | LCDC_BASECHER_UPDATEEN); + + /* Enable LCD */ + value = lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDEN); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDEN, value + | LCDC_LCDEN_CLKEN); + while (!(lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDSR) + & LCDC_LCDSR_CLKSTS)) + udelay(1); + value = lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDEN); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDEN, value + | LCDC_LCDEN_SYNCEN); + while (!(lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDSR) + & LCDC_LCDSR_LCDSTS)) + udelay(1); + value = lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDEN); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDEN, value + | LCDC_LCDEN_DISPEN); + while (!(lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDSR) + & LCDC_LCDSR_DISPSTS)) + udelay(1); + value = lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDEN); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDEN, value + | LCDC_LCDEN_PWMEN); + while (!(lcdc_readl(panel_info.mmio, ATMEL_LCDC_LCDSR) + & LCDC_LCDSR_PWMSTS)) + udelay(1); +} +#endif + void lcd_ctrl_init(void *lcdbase) { unsigned long value; +#if defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAMA5) + return lcd_9x5_ctrl_init(lcdbase); +#endif + /* Turn off the LCD controller and the DMA controller */ lcdc_writel(panel_info.mmio, ATMEL_LCDC_PWRCON, ATMEL_LCDC_GUARD_TIME << ATMEL_LCDC_GUARDT_OFFSET); @@ -96,7 +276,8 @@ void lcd_ctrl_init(void *lcdbase) value = (value / 2) - 1; if (!value) { - lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCON1, + ATMEL_LCDC_BYPASS); } else lcdc_writel(panel_info.mmio, ATMEL_LCDC_LCDCON1, value << ATMEL_LCDC_CLKVAL_OFFSET); @@ -143,18 +324,19 @@ void lcd_ctrl_init(void *lcdbase) /* Set contrast */ value = ATMEL_LCDC_PS_DIV8 | + ATMEL_LCDC_POL_POSITIVE | ATMEL_LCDC_ENA_PWMENABLE; - if (!panel_info.vl_cont_pol_low) - value |= ATMEL_LCDC_POL_POSITIVE; lcdc_writel(panel_info.mmio, ATMEL_LCDC_CONTRAST_CTR, value); - lcdc_writel(panel_info.mmio, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); + lcdc_writel(panel_info.mmio, ATMEL_LCDC_CONTRAST_VAL, + ATMEL_LCDC_CVAL_DEFAULT); /* Set framebuffer DMA base address and pixel offset */ lcdc_writel(panel_info.mmio, ATMEL_LCDC_DMABADDR1, (u_long)lcdbase); lcdc_writel(panel_info.mmio, ATMEL_LCDC_DMACON, ATMEL_LCDC_DMAEN); lcdc_writel(panel_info.mmio, ATMEL_LCDC_PWRCON, - (ATMEL_LCDC_GUARD_TIME << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); + (ATMEL_LCDC_GUARD_TIME << ATMEL_LCDC_GUARDT_OFFSET) + | ATMEL_LCDC_PWR); } ulong calc_fbsize(void) diff --git a/include/atmel_9x5_lcdc.h b/include/atmel_9x5_lcdc.h new file mode 100644 index 0000000000..6bd8cfeebe --- /dev/null +++ b/include/atmel_9x5_lcdc.h @@ -0,0 +1,223 @@ +/* + * Header file for AT91/AT32 SAM9X5 LCD Controller + * + * Data structure and register user interface + * + * Copyright (C) 2010 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ATMEL_9X5_LCDC_H__ +#define __ATMEL_9X5_LCDC_H__ + +/* Atmel 9x5 lcdc hardware registers */ +#define ATMEL_LCDC_LCDCFG0 0x0000 +#define LCDC_LCDCFG0_CLKPOL (0x1 << 0) +#define LCDC_LCDCFG0_CLKSEL (0x1 << 2) +#define LCDC_LCDCFG0_CLKPWMSEL (0x1 << 3) +#define LCDC_LCDCFG0_CGDISBASE (0x1 << 8) +#define LCDC_LCDCFG0_CGDISOVR1 (0x1 << 9) +#define LCDC_LCDCFG0_CGDISHEO (0x1 << 11) +#define LCDC_LCDCFG0_CGDISHCR (0x1 << 12) +#define LCDC_LCDCFG0_CLKDIV_Pos 16 +#define LCDC_LCDCFG0_CLKDIV_Msk (0xff << LCDC_LCDCFG0_CLKDIV_Pos) +#define LCDC_LCDCFG0_CLKDIV(value) \ + ((LCDC_LCDCFG0_CLKDIV_Msk & ((value) << LCDC_LCDCFG0_CLKDIV_Pos))) + +#define ATMEL_LCDC_LCDCFG1 0x0004 +#define LCDC_LCDCFG1_HSPW_Pos 0 +#define LCDC_LCDCFG1_HSPW_Msk (0x3f << LCDC_LCDCFG1_HSPW_Pos) +#define LCDC_LCDCFG1_HSPW(value) \ + ((LCDC_LCDCFG1_HSPW_Msk & ((value) << LCDC_LCDCFG1_HSPW_Pos))) +#define LCDC_LCDCFG1_VSPW_Pos 16 +#define LCDC_LCDCFG1_VSPW_Msk (0x3f << LCDC_LCDCFG1_VSPW_Pos) +#define LCDC_LCDCFG1_VSPW(value) \ + ((LCDC_LCDCFG1_VSPW_Msk & ((value) << LCDC_LCDCFG1_VSPW_Pos))) + +#define ATMEL_LCDC_LCDCFG2 0x0008 +#define LCDC_LCDCFG2_VFPW_Pos 0 +#define LCDC_LCDCFG2_VFPW_Msk (0x3f << LCDC_LCDCFG2_VFPW_Pos) +#define LCDC_LCDCFG2_VFPW(value) \ + ((LCDC_LCDCFG2_VFPW_Msk & ((value) << LCDC_LCDCFG2_VFPW_Pos))) +#define LCDC_LCDCFG2_VBPW_Pos 16 +#define LCDC_LCDCFG2_VBPW_Msk (0x3f << LCDC_LCDCFG2_VBPW_Pos) +#define LCDC_LCDCFG2_VBPW(value) \ + ((LCDC_LCDCFG2_VBPW_Msk & ((value) << LCDC_LCDCFG2_VBPW_Pos))) + +#define ATMEL_LCDC_LCDCFG3 0x000C +#define LCDC_LCDCFG3_HFPW_Pos 0 +#define LCDC_LCDCFG3_HFPW_Msk (0xff << LCDC_LCDCFG3_HFPW_Pos) +#define LCDC_LCDCFG3_HFPW(value) \ + ((LCDC_LCDCFG3_HFPW_Msk & ((value) << LCDC_LCDCFG3_HFPW_Pos))) +#define LCDC_LCDCFG3_HBPW_Pos 16 +#define LCDC_LCDCFG3_HBPW_Msk (0xff << LCDC_LCDCFG3_HBPW_Pos) +#define LCDC_LCDCFG3_HBPW(value) \ + ((LCDC_LCDCFG3_HBPW_Msk & ((value) << LCDC_LCDCFG3_HBPW_Pos))) + +#define ATMEL_LCDC_LCDCFG4 0x0010 +#define LCDC_LCDCFG4_PPL_Pos 0 +#define LCDC_LCDCFG4_PPL_Msk (0x7ff << LCDC_LCDCFG4_PPL_Pos) +#define LCDC_LCDCFG4_PPL(value) \ + ((LCDC_LCDCFG4_PPL_Msk & ((value) << LCDC_LCDCFG4_PPL_Pos))) +#define LCDC_LCDCFG4_RPF_Pos 16 +#define LCDC_LCDCFG4_RPF_Msk (0x7ff << LCDC_LCDCFG4_RPF_Pos) +#define LCDC_LCDCFG4_RPF(value) \ + ((LCDC_LCDCFG4_RPF_Msk & ((value) << LCDC_LCDCFG4_RPF_Pos))) + +#define ATMEL_LCDC_LCDCFG5 0x0014 +#define LCDC_LCDCFG5_HSPOL (0x1 << 0) +#define LCDC_LCDCFG5_VSPOL (0x1 << 1) +#define LCDC_LCDCFG5_VSPDLYS (0x1 << 2) +#define LCDC_LCDCFG5_VSPDLYE (0x1 << 3) +#define LCDC_LCDCFG5_DISPPOL (0x1 << 4) +#define LCDC_LCDCFG5_SERIAL (0x1 << 5) +#define LCDC_LCDCFG5_DITHER (0x1 << 6) +#define LCDC_LCDCFG5_DISPDLY (0x1 << 7) +#define LCDC_LCDCFG5_MODE_Pos 8 +#define LCDC_LCDCFG5_MODE_Msk (0x3 << LCDC_LCDCFG5_MODE_Pos) +#define LCDC_LCDCFG5_MODE_OUTPUT_12BPP (0x0 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_16BPP (0x1 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_18BPP (0x2 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_24BPP (0x3 << 8) +#define LCDC_LCDCFG5_VSPSU (0x1 << 12) +#define LCDC_LCDCFG5_VSPHO (0x1 << 13) +#define LCDC_LCDCFG5_GUARDTIME_Pos 16 +#define LCDC_LCDCFG5_GUARDTIME_Msk (0x1f << LCDC_LCDCFG5_GUARDTIME_Pos) +#define LCDC_LCDCFG5_GUARDTIME(value) \ + ((LCDC_LCDCFG5_GUARDTIME_Msk & ((value) << LCDC_LCDCFG5_GUARDTIME_Pos))) + +#define ATMEL_LCDC_LCDCFG6 0x0018 +#define LCDC_LCDCFG6_PWMPS_Pos 0 +#define LCDC_LCDCFG6_PWMPS_Msk (0x7 << LCDC_LCDCFG6_PWMPS_Pos) +#define LCDC_LCDCFG6_PWMPS(value) \ + ((LCDC_LCDCFG6_PWMPS_Msk & ((value) << LCDC_LCDCFG6_PWMPS_Pos))) +#define LCDC_LCDCFG6_PWMPOL (0x1 << 4) +#define LCDC_LCDCFG6_PWMCVAL_Pos 8 +#define LCDC_LCDCFG6_PWMCVAL_Msk (0xff << LCDC_LCDCFG6_PWMCVAL_Pos) +#define LCDC_LCDCFG6_PWMCVAL(value) \ + ((LCDC_LCDCFG6_PWMCVAL_Msk & ((value) << LCDC_LCDCFG6_PWMCVAL_Pos))) + +#define ATMEL_LCDC_LCDEN 0x0020 +#define LCDC_LCDEN_CLKEN (0x1 << 0) +#define LCDC_LCDEN_SYNCEN (0x1 << 1) +#define LCDC_LCDEN_DISPEN (0x1 << 2) +#define LCDC_LCDEN_PWMEN (0x1 << 3) + +#define ATMEL_LCDC_LCDDIS 0x0024 +#define LCDC_LCDDIS_CLKDIS (0x1 << 0) +#define LCDC_LCDDIS_SYNCDIS (0x1 << 1) +#define LCDC_LCDDIS_DISPDIS (0x1 << 2) +#define LCDC_LCDDIS_PWMDIS (0x1 << 3) +#define LCDC_LCDDIS_CLKRST (0x1 << 8) +#define LCDC_LCDDIS_SYNCRST (0x1 << 9) +#define LCDC_LCDDIS_DISPRST (0x1 << 10) +#define LCDC_LCDDIS_PWMRST (0x1 << 11) + +#define ATMEL_LCDC_LCDSR 0x0028 + +#define LCDC_LCDSR_CLKSTS (0x1 << 0) +#define LCDC_LCDSR_LCDSTS (0x1 << 1) +#define LCDC_LCDSR_DISPSTS (0x1 << 2) +#define LCDC_LCDSR_PWMSTS (0x1 << 3) +#define LCDC_LCDSR_SIPSTS (0x1 << 4) + +#define ATMEL_LCDC_LCDIDR 0x0030 +#define LCDC_LCDIDR_SOFID (0x1 << 0) +#define LCDC_LCDIDR_DISID (0x1 << 1) +#define LCDC_LCDIDR_DISPID (0x1 << 2) +#define LCDC_LCDIDR_FIFOERRID (0x1 << 4) +#define LCDC_LCDIDR_BASEID (0x1 << 8) +#define LCDC_LCDIDR_OVR1ID (0x1 << 9) +#define LCDC_LCDIDR_HEOID (0x1 << 11) +#define LCDC_LCDIDR_HCRID (0x1 << 12) + +#define ATMEL_LCDC_BASECHER 0x0040 +#define LCDC_BASECHER_CHEN (0x1 << 0) +#define LCDC_BASECHER_UPDATEEN (0x1 << 1) +#define LCDC_BASECHER_A2QEN (0x1 << 2) + +#define ATMEL_LCDC_BASEIDR 0x0050 +#define LCDC_BASEIDR_DMA (0x1 << 2) +#define LCDC_BASEIDR_DSCR (0x1 << 3) +#define LCDC_BASEIDR_ADD (0x1 << 4) +#define LCDC_BASEIDR_DONE (0x1 << 5) +#define LCDC_BASEIDR_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEADDR 0x0060 + +#define ATMEL_LCDC_BASECTRL 0x0064 +#define LCDC_BASECTRL_DFETCH (0x1 << 0) +#define LCDC_BASECTRL_LFETCH (0x1 << 1) +#define LCDC_BASECTRL_DMAIEN (0x1 << 2) +#define LCDC_BASECTRL_DSCRIEN (0x1 << 3) +#define LCDC_BASECTRL_ADDIEN (0x1 << 4) +#define LCDC_BASECTRL_DONEIEN (0x1 << 5) + +#define ATMEL_LCDC_BASENEXT 0x0068 +#define ATMEL_LCDC_BASECFG0 0x006C +#define LCDC_BASECFG0_BLEN_Pos 4 +#define LCDC_BASECFG0_BLEN_AHB_SINGLE (0x0 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR4 (0x1 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR8 (0x2 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR16 (0x3 << 4) +#define LCDC_BASECFG0_DLBO (0x1 << 8) + +#define ATMEL_LCDC_BASECFG1 0x0070 +#define LCDC_BASECFG1_RGBMODE_12BPP_RGB_444 (0x0 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_ARGB_4444 (0x1 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_RGBA_4444 (0x2 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_RGB_565 (0x3 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_TRGB_1555 (0x4 << 4) +#define LCDC_BASECFG1_RGBMODE_18BPP_RGB_666 (0x5 << 4) +#define LCDC_BASECFG1_RGBMODE_18BPP_RGB_666_PACKED (0x6 << 4) +#define LCDC_BASECFG1_RGBMODE_19BPP_TRGB_1666 (0x7 << 4) +#define LCDC_BASECFG1_RGBMODE_19BPP_TRGB_PACKED (0x8 << 4) +#define LCDC_BASECFG1_RGBMODE_24BPP_RGB_888 (0x9 << 4) +#define LCDC_BASECFG1_RGBMODE_24BPP_RGB_888_PACKED (0xA << 4) +#define LCDC_BASECFG1_RGBMODE_25BPP_TRGB_1888 (0xB << 4) +#define LCDC_BASECFG1_RGBMODE_32BPP_ARGB_8888 (0xC << 4) +#define LCDC_BASECFG1_RGBMODE_32BPP_RGBA_8888 (0xD << 4) + +#define ATMEL_LCDC_BASECFG2 0x0074 +#define LCDC_BASECFG2_XSTRIDE_Pos 0 +#define LCDC_BASECFG2_XSTRIDE_Msk (0xffffffff << LCDC_BASECFG2_XSTRIDE_Pos) +#define LCDC_BASECFG2_XSTRIDE(value) \ + ((LCDC_BASECFG2_XSTRIDE_Msk & ((value) << LCDC_BASECFG2_XSTRIDE_Pos))) + +#define ATMEL_LCDC_BASECFG3 0x0078 +#define LCDC_BASECFG3_BDEF_Pos 0 +#define LCDC_BASECFG3_BDEF_Msk (0xff << LCDC_BASECFG3_BDEF_Pos) +#define LCDC_BASECFG3_BDEF(value) \ + ((LCDC_BASECFG3_BDEF_Msk & ((value) << LCDC_BASECFG3_BDEF_Pos))) +#define LCDC_BASECFG3_GDEF_Pos 8 +#define LCDC_BASECFG3_GDEF_Msk (0xff << LCDC_BASECFG3_GDEF_Pos) +#define LCDC_BASECFG3_GDEF(value) \ + ((LCDC_BASECFG3_GDEF_Msk & ((value) << LCDC_BASECFG3_GDEF_Pos))) +#define LCDC_BASECFG3_RDEF_Pos 16 +#define LCDC_BASECFG3_RDEF_Msk (0xff << LCDC_BASECFG3_RDEF_Pos) +#define LCDC_BASECFG3_RDEF(value) \ + ((LCDC_BASECFG3_RDEF_Msk & ((value) << LCDC_BASECFG3_RDEF_Pos))) + +#define ATMEL_LCDC_BASECFG4 0x007C +#define LCDC_BASECFG4_DMA (0x1 << 8) +#define LCDC_BASECFG4_REP (0x1 << 9) + +typedef struct { + u32 address; + u32 control; + u32 next; +} lcd_dma_desc; + +#endif /* __ATMEL_9X5_LCDC_H__ */ diff --git a/include/atmel_mci.h b/include/atmel_mci.h index 3dd5d67be9..4455b32fc7 100644 --- a/include/atmel_mci.h +++ b/include/atmel_mci.h @@ -38,7 +38,7 @@ typedef struct atmel_mci { u32 sdcr; /* 0x0c */ u32 argr; /* 0x10 */ u32 cmdr; /* 0x14 */ - u32 _18; /* 0x18 */ + u32 blkr; /* 0x18 */ u32 _1c; /* 0x1c */ u32 rspr; /* 0x20 */ u32 rspr1; /* 0x24 */ diff --git a/include/configs/at91sama5ek.h b/include/configs/at91sama5ek.h new file mode 100644 index 0000000000..842bd1e2f9 --- /dev/null +++ b/include/configs/at91sama5ek.h @@ -0,0 +1,283 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop <stelian@popies.net> + * Lead Tech Design <www.leadtechdesign.com> + * + * Configuation settings for the AT91SAMA5EK board. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <asm/hardware.h> + +#define CONFIG_AT91_LEGACY + +/* ARM asynchronous clock */ +#define CONFIG_SYS_AT91_SLOW_CLOCK 32768 +#define CONFIG_SYS_AT91_MAIN_CLOCK 12000000 /* from 12 MHz crystal */ +#define CONFIG_SYS_HZ 1000 + +#define CONFIG_AT91SAMA5EK +#define CONFIG_AT91FAMILY +#define CONFIG_ARCH_CPU_INIT +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ + +#undef CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ +#undef CONFIG_SETUP_MEMORY_TAGS +#undef CONFIG_INITRD_TAG +#define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_DISPLAY_CPUINFO + +#define CONFIG_OF_LIBFDT /* Device Tree support */ + +/* general purpose I/O */ +#define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ +#define CONFIG_AT91_GPIO +#define CONFIG_AT91_GPIO_PULLUP 1 /* keep pullups on peripheral pins */ + +/* serial console */ +#define CONFIG_ATMEL_USART +#undef CONFIG_USART1 +#ifdef CONFIG_USART1 +#define CONFIG_USART_BASE ATMEL_BASE_USART1 +#define CONFIG_USART_ID ATMEL_ID_USART1 +#else +#define CONFIG_USART_BASE ATMEL_BASE_DBGU +#define CONFIG_USART_ID ATMEL_ID_DBGU +#endif + +/* + * This needs to be defined for the OHCI code to work but it is defined as + * ATMEL_ID_UHPHS in the CPU specific header files. + */ +#define ATMEL_ID_UHP ATMEL_ID_UHPHS + +/* + * Specify the clock enable bit in the PMC_SCER register. + */ + #define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP + +/* LCD */ +#define CONFIG_LCD +#define LCD_BPP LCD_COLOR16 +#define LCD_OUTPUT_BPP 24 +#define CONFIG_LCD_LOGO +#undef LCD_TEST_PATTERN +#define CONFIG_LCD_INFO +#define CONFIG_LCD_INFO_BELOW_LOGO +#define CONFIG_SYS_WHITE_ON_BLACK +#define CONFIG_ATMEL_LCD +#define CONFIG_ATMEL_LCD_RGB565 +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + +/* board specific(not enough SRAM) */ +#define CONFIG_AT91SAMA5_LCD_BASE 0x23E00000 + +/* LED */ +#if 0 +#define CONFIG_AT91_LED +#define CONFIG_RED_LED AT91_PIN_PE24 /* this is the user1 led */ +#define CONFIG_GREEN_LED AT91_PIN_PE25 /* this is the user2 led */ +#endif + +#define CONFIG_BOOTDELAY 3 + +/* + * BOOTP options + */ +#define CONFIG_BOOTP_BOOTFILESIZE +#define CONFIG_BOOTP_BOOTPATH +#define CONFIG_BOOTP_GATEWAY +#define CONFIG_BOOTP_HOSTNAME + +/* + * Command line configuration. + */ +#include <config_cmd_default.h> +#undef CONFIG_CMD_BDI +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_IMI +#undef CONFIG_CMD_IMLS +#undef CONFIG_CMD_AUTOSCRIPT +#undef CONFIG_CMD_LOADS + +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP + +/* SDRAM */ +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_SDRAM_BASE ATMEL_BASE_DDRCS +#define CONFIG_SYS_SDRAM_SIZE 0x20000000 + +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE) + +/* SerialFlash */ +#define CONFIG_CMD_SF + +#ifdef CONFIG_CMD_SF +#define CONFIG_ATMEL_SPI +#define CONFIG_SPI_FLASH 1 +#define CONFIG_SPI_FLASH_ATMEL 1 +#endif + +/* No NOR flash */ +#define CONFIG_SYS_NO_FLASH + +/* NAND flash */ +#define CONFIG_CMD_NAND + +#ifdef CONFIG_CMD_NAND +#define CONFIG_NAND_MAX_CHIPS 1 +#define CONFIG_NAND_ATMEL +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_SYS_NAND_BASE ATMEL_BASE_CS3 +#define CONFIG_SYS_NAND_DBW_8 +/* our ALE is AD21 */ +#define CONFIG_SYS_NAND_MASK_ALE (1 << 21) +/* our CLE is AD22 */ +#define CONFIG_SYS_NAND_MASK_CLE (1 << 22) +#define CONFIG_SYS_NAND_ONFI_DETECTION 1 +/* PMECC & PMERRLOC */ +#define CONFIG_ATMEL_NAND_HWECC +#define CONFIG_ATMEL_NAND_HW_PMECC +#define CONFIG_PMECC_CAP 2 +#define CONFIG_PMECC_SECTOR_SIZE 512 +#define CONFIG_PMECC_INDEX_TABLE_OFFSET ATMEL_PMECC_INDEX_OFFSET_512 + +#define CONFIG_CMD_NAND_TRIMFFS +#endif + +/* Ethernet Hardware */ +#define CONFIG_MACB +#define CONFIG_RMII +#define CONFIG_GMACB +#define CONFIG_RGMII +#define CONFIG_NET_MULTI +#define CONFIG_NET_RETRY_COUNT 20 +#define CONFIG_RESET_PHY_R +#define CONFIG_MACB_SEARCH_PHY + +/* MMC */ +#define CONFIG_CMD_MMC + +#ifdef CONFIG_CMD_MMC +#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_GENERIC_ATMEL_MCI +#undef CONFIG_ATMEL_MCI_8BIT +#define ATMEL_BASE_MMCI ATMEL_BASE_MCI0 +#endif + +/* USB */ +#define CONFIG_CMD_USB + +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_ATMEL +#define CONFIG_USB_OHCI_NEW +#define CONFIG_DOS_PARTITION +#define CONFIG_SYS_USB_OHCI_CPU_INIT +#define CONFIG_SYS_USB_OHCI_REGS_BASE ATMEL_BASE_OHCI +#define CONFIG_SYS_USB_OHCI_SLOT_NAME "at91sama5" +#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 3 +#define CONFIG_USB_STORAGE +#endif + +#if defined(CONFIG_CMD_USB) || defined (CONFIG_CMD_MMC) +#define CONFIG_CMD_FAT +#endif + +#define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ + +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END 0x23e00000 + +#ifdef CONFIG_SYS_USE_SERIALFLASH +/* bootstrap + u-boot + env + linux in serial flash */ +#define CONFIG_ENV_IS_IN_SPI_FLASH 1 +#define CONFIG_SYS_MONITOR_BASE (0x10000000 + 0x8400) +#define CONFIG_ENV_OFFSET 0x5000 +#define CONFIG_ENV_ADDR (0x10000000 + CONFIG_ENV_OFFSET) +#define CONFIG_ENV_SIZE 0x3000 +#define CONFIG_ENV_SECT_SIZE 0x1000 +#define CONFIG_BOOTCOMMAND "sf probe 0; " \ + "sf read 0x22000000 0x42000 0x300000; " \ + "bootm 0x22000000" +#elif CONFIG_SYS_USE_NANDFLASH +/* bootstrap + u-boot + env in nandflash */ +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_OFFSET 0xc0000 +#define CONFIG_ENV_OFFSET_REDUND 0x100000 +#define CONFIG_ENV_SIZE 0x20000 +#define CONFIG_BOOTCOMMAND "nand read 0x21000000 0x180000 0x80000;" \ + "nand read 0x22000000 0x200000 0x600000;" \ + "bootm 0x22000000 - 0x21000000" +#elif CONFIG_SYS_USE_MMC +/* bootstrap + u-boot + env in sd card */ +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_ENV_OFFSET 0x2000 +#define CONFIG_ENV_OFFSET_REDUND 0x4000 +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_BOOTCOMMAND "mmcinfo;fatload mmc 0:1 0x21000000 dtb;" \ + "fatload mmc 0:1 0x22000000 uImage;" \ + "bootm 0x22000000 - 0x21000000" +#define CONFIG_SYS_MMC_ENV_DEV 0 +#else +#define CONIG_ENV_IS_NOWHERE +#endif + +#ifdef CONFIG_SYS_USE_MMC +#define CONFIG_BOOTARGS \ + "console=ttyS0,115200 earlyprintk " \ + "root=/dev/mmcblk0p2 " \ + "rw rootfstype=ext2 rootdelay=2" +#else +#define CONFIG_BOOTARGS \ + "console=ttyS0,115200 earlyprintk " \ + "mtdparts=atmel_nand:8M(bootstrap/uboot/kernel)ro,-(rootfs)" \ + "rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs" +#endif + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 } + +#define CONFIG_SYS_PROMPT "U-Boot> " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_LONGHELP +#define CONFIG_CMDLINE_EDITING +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) + +#ifdef CONFIG_USE_IRQ +#error CONFIG_USE_IRQ not supported +#endif + +#endif diff --git a/include/netdev.h b/include/netdev.h index b8d303d089..fff84bee81 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -73,6 +73,7 @@ int inca_switch_initialize(bd_t *bis); int ks8695_eth_initialize(void); int lan91c96_initialize(u8 dev_num, int base_addr); int macb_eth_initialize(int id, void *regs, unsigned int phy_addr); +int gmacb_eth_initialize(int id, void *regs, unsigned int phy_addr); int mcdmafec_initialize(bd_t *bis); int mcffec_initialize(bd_t *bis); int mpc512x_fec_initialize(bd_t *bis); |