From 567fb852178dbf59529d7301620a3f3732a4b02d Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Thu, 8 May 2008 22:52:09 +0200 Subject: Fix @ -> substitution When applying the AT91CAP9 patches upstream, something transformed the '@' character into the ' ' sequence. The patch below restores the original form in all the places where it has been modified (the AT91CAP9 files, the AT91SAM9260 files which were copied from AT91CAP9, and a couple of other files where the ' ' sequence was present). Signed-off-by: Stelian Pop Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- cpu/arm926ejs/at91sam9/Makefile | 2 +- cpu/arm926ejs/at91sam9/ether.c | 2 +- cpu/arm926ejs/at91sam9/lowlevel_init.S | 2 +- cpu/arm926ejs/at91sam9/timer.c | 2 +- cpu/arm926ejs/at91sam9/usb.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'cpu') diff --git a/cpu/arm926ejs/at91sam9/Makefile b/cpu/arm926ejs/at91sam9/Makefile index 203abc28e14..44cde1a9c31 100644 --- a/cpu/arm926ejs/at91sam9/Makefile +++ b/cpu/arm926ejs/at91sam9/Makefile @@ -1,6 +1,6 @@ # # (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd denx.de. +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # See file CREDITS for list of people who contributed to this # project. diff --git a/cpu/arm926ejs/at91sam9/ether.c b/cpu/arm926ejs/at91sam9/ether.c index e4f56012aa1..7e11fe4d8eb 100644 --- a/cpu/arm926ejs/at91sam9/ether.c +++ b/cpu/arm926ejs/at91sam9/ether.c @@ -1,6 +1,6 @@ /* * (C) Copyright 2007-2008 - * Stelian Pop leadtechdesign.com> + * Stelian Pop * Lead Tech Design * * See file CREDITS for list of people who contributed to this diff --git a/cpu/arm926ejs/at91sam9/lowlevel_init.S b/cpu/arm926ejs/at91sam9/lowlevel_init.S index 40a3f6aaef6..ec6ad5da18c 100644 --- a/cpu/arm926ejs/at91sam9/lowlevel_init.S +++ b/cpu/arm926ejs/at91sam9/lowlevel_init.S @@ -2,7 +2,7 @@ * AT91CAP9/SAM9 setup stuff * * (C) Copyright 2007-2008 - * Stelian Pop leadtechdesign.com> + * Stelian Pop * Lead Tech Design * * See file CREDITS for list of people who contributed to this diff --git a/cpu/arm926ejs/at91sam9/timer.c b/cpu/arm926ejs/at91sam9/timer.c index 4e794662865..c79ec7e7ae1 100644 --- a/cpu/arm926ejs/at91sam9/timer.c +++ b/cpu/arm926ejs/at91sam9/timer.c @@ -1,6 +1,6 @@ /* * (C) Copyright 2007-2008 - * Stelian Pop leadtechdesign.com> + * Stelian Pop * Lead Tech Design * * See file CREDITS for list of people who contributed to this diff --git a/cpu/arm926ejs/at91sam9/usb.c b/cpu/arm926ejs/at91sam9/usb.c index d678897dc71..441349df3af 100644 --- a/cpu/arm926ejs/at91sam9/usb.c +++ b/cpu/arm926ejs/at91sam9/usb.c @@ -1,6 +1,6 @@ /* * (C) Copyright 2006 - * DENX Software Engineering denx.de> + * DENX Software Engineering * * See file CREDITS for list of people who contributed to this * project. -- cgit v1.3.1 From 11b162bae058e96c7929e358d4adff2bee6c2cc4 Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Thu, 8 May 2008 20:52:13 +0200 Subject: Use a common u-boot.lds file across all AT91CAP9/AT91SAM9 platforms All the AT91CAP9/AT91SAM9 boards have the same linker script. The patch below avoids the duplication of u-boot.lds by putting the file in the cpu directory instead of the board one. Signed-off-by: Stelian Pop Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- board/atmel/at91cap9adk/u-boot.lds | 57 ------------------------------------ board/atmel/at91sam9260ek/u-boot.lds | 57 ------------------------------------ cpu/arm926ejs/at91sam9/config.mk | 1 + cpu/arm926ejs/at91sam9/u-boot.lds | 57 ++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 114 deletions(-) delete mode 100644 board/atmel/at91cap9adk/u-boot.lds delete mode 100644 board/atmel/at91sam9260ek/u-boot.lds create mode 100644 cpu/arm926ejs/at91sam9/u-boot.lds (limited to 'cpu') diff --git a/board/atmel/at91cap9adk/u-boot.lds b/board/atmel/at91cap9adk/u-boot.lds deleted file mode 100644 index 996f401f0b9..00000000000 --- a/board/atmel/at91cap9adk/u-boot.lds +++ /dev/null @@ -1,57 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * 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 - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/ -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm926ejs/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(.rodata) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) } - _end = .; -} diff --git a/board/atmel/at91sam9260ek/u-boot.lds b/board/atmel/at91sam9260ek/u-boot.lds deleted file mode 100644 index 996f401f0b9..00000000000 --- a/board/atmel/at91sam9260ek/u-boot.lds +++ /dev/null @@ -1,57 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * 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 - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/ -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - cpu/arm926ejs/start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(.rodata) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = .; - __u_boot_cmd_start = .; - .u_boot_cmd : { *(.u_boot_cmd) } - __u_boot_cmd_end = .; - - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) } - _end = .; -} diff --git a/cpu/arm926ejs/at91sam9/config.mk b/cpu/arm926ejs/at91sam9/config.mk index ca2cae181bc..83040ebe737 100644 --- a/cpu/arm926ejs/at91sam9/config.mk +++ b/cpu/arm926ejs/at91sam9/config.mk @@ -1,2 +1,3 @@ PLATFORM_CPPFLAGS += -march=armv5te PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,) +LDSCRIPT := $(SRCTREE)/cpu/arm926ejs/at91sam9/u-boot.lds diff --git a/cpu/arm926ejs/at91sam9/u-boot.lds b/cpu/arm926ejs/at91sam9/u-boot.lds new file mode 100644 index 00000000000..996f401f0b9 --- /dev/null +++ b/cpu/arm926ejs/at91sam9/u-boot.lds @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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 + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/ +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/arm926ejs/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +} -- cgit v1.3.1 From d99a8ff66d8ae87e5c87590ed2e4ead629540607 Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Thu, 8 May 2008 20:52:22 +0200 Subject: AT91SAM9261EK support This patch adds support for the AT91SAM9261 chip and the AT91SAM9261EK board. Signed-off-by: Stelian Pop Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- MAINTAINERS | 1 + MAKEALL | 1 + Makefile | 3 + board/atmel/at91sam9261ek/Makefile | 57 ++++++ board/atmel/at91sam9261ek/at91sam9261ek.c | 194 +++++++++++++++++++++ board/atmel/at91sam9261ek/config.mk | 1 + board/atmel/at91sam9261ek/led.c | 78 +++++++++ board/atmel/at91sam9261ek/nand.c | 79 +++++++++ board/atmel/at91sam9261ek/partition.c | 40 +++++ cpu/arm926ejs/at91sam9/usb.c | 8 + drivers/net/dm9000x.c | 2 + include/asm-arm/arch-at91sam9/at91sam9261.h | 105 +++++++++++ include/asm-arm/arch-at91sam9/at91sam9261_matrix.h | 64 +++++++ include/asm-arm/arch-at91sam9/hardware.h | 3 + include/configs/at91sam9261ek.h | 191 ++++++++++++++++++++ 15 files changed, 827 insertions(+) create mode 100644 board/atmel/at91sam9261ek/Makefile create mode 100644 board/atmel/at91sam9261ek/at91sam9261ek.c create mode 100644 board/atmel/at91sam9261ek/config.mk create mode 100644 board/atmel/at91sam9261ek/led.c create mode 100644 board/atmel/at91sam9261ek/nand.c create mode 100644 board/atmel/at91sam9261ek/partition.c create mode 100644 include/asm-arm/arch-at91sam9/at91sam9261.h create mode 100644 include/asm-arm/arch-at91sam9/at91sam9261_matrix.h create mode 100644 include/configs/at91sam9261ek.h (limited to 'cpu') diff --git a/MAINTAINERS b/MAINTAINERS index 58f833c1491..26f31fda5eb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -538,6 +538,7 @@ Stelian Pop at91cap9adk ARM926EJS (AT91CAP9 SoC) at91sam9260ek ARM926EJS (AT91SAM9260 SoC) + at91sam9261ek ARM926EJS (AT91SAM9261 SoC) Stefan Roese diff --git a/MAKEALL b/MAKEALL index 791eabc7f68..d4ae09cdcff 100755 --- a/MAKEALL +++ b/MAKEALL @@ -459,6 +459,7 @@ LIST_ARM9=" \ at91cap9adk \ at91rm9200dk \ at91sam9260ek \ + at91sam9261ek \ cmc_pu2 \ ap920t \ ap922_XA10 \ diff --git a/Makefile b/Makefile index 167a71741c8..5e06ff554e8 100644 --- a/Makefile +++ b/Makefile @@ -2326,6 +2326,9 @@ shannon_config : unconfig at91rm9200dk_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t at91rm9200dk atmel at91rm9200 +at91sam9261ek_config : unconfig + @$(MKCONFIG) $(@:_config=) arm arm926ejs at91sam9261ek atmel at91sam9 + cmc_pu2_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t cmc_pu2 NULL at91rm9200 diff --git a/board/atmel/at91sam9261ek/Makefile b/board/atmel/at91sam9261ek/Makefile new file mode 100644 index 00000000000..7702a9c9034 --- /dev/null +++ b/board/atmel/at91sam9261ek/Makefile @@ -0,0 +1,57 @@ +# +# (C) Copyright 2003-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Stelian Pop +# Lead Tech Design +# +# 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).a + +COBJS-y += at91sam9261ek.o +COBJS-y += led.o +COBJS-y += partition.o +COBJS-$(CONFIG_CMD_NAND) += nand.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/atmel/at91sam9261ek/at91sam9261ek.c b/board/atmel/at91sam9261ek/at91sam9261ek.c new file mode 100644 index 00000000000..96b4422c973 --- /dev/null +++ b/board/atmel/at91sam9261ek/at91sam9261ek.c @@ -0,0 +1,194 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_DRIVER_DM9000) +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* ------------------------------------------------------------------------- */ +/* + * Miscelaneous platform dependent initialisations + */ + +static void at91sam9261ek_serial_hw_init(void) +{ +#ifdef CONFIG_USART0 + at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ + at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_US0); +#endif + +#ifdef CONFIG_USART1 + at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ + at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_US1); +#endif + +#ifdef CONFIG_USART2 + at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ + at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_US2); +#endif + +#ifdef CONFIG_USART3 /* DBGU */ + at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ + at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS); +#endif +} + +#ifdef CONFIG_CMD_NAND +static void at91sam9261ek_nand_hw_init(void) +{ + unsigned long csa; + + /* Enable CS3 */ + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, + csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + + /* Configure SMC CS3 for NAND/SmartMedia */ + at91_sys_write(AT91_SMC_SETUP(3), + AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | + AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); + at91_sys_write(AT91_SMC_PULSE(3), + AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5) | + AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5)); + at91_sys_write(AT91_SMC_CYCLE(3), + AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); + at91_sys_write(AT91_SMC_MODE(3), + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_EXNWMODE_DISABLE | +#ifdef CFG_NAND_DBW_16 + AT91_SMC_DBW_16 | +#else /* CFG_NAND_DBW_8 */ + AT91_SMC_DBW_8 | +#endif + AT91_SMC_TDF_(1)); + + at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9261_ID_PIOC); + + /* Configure RDY/BSY */ + at91_set_gpio_input(AT91_PIN_PC15, 1); + + /* Enable NandFlash */ + at91_set_gpio_output(AT91_PIN_PC14, 1); + + at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */ +} +#endif + +#ifdef CONFIG_HAS_DATAFLASH +static void at91sam9261ek_spi_hw_init(void) +{ + at91_set_A_periph(AT91_PIN_PA3, 0); /* SPI0_NPCS0 */ + + at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ + + /* Enable clock */ + at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9261_ID_SPI0); +} +#endif + +#ifdef CONFIG_DRIVER_DM9000 +static void at91sam9261ek_dm9000_hw_init(void) +{ + /* Configure SMC CS2 for DM9000 */ + at91_sys_write(AT91_SMC_SETUP(2), + AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(0) | + AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(0)); + at91_sys_write(AT91_SMC_PULSE(2), + AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(8) | + AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(8)); + at91_sys_write(AT91_SMC_CYCLE(2), + AT91_SMC_NWECYCLE_(16) | AT91_SMC_NRDCYCLE_(16)); + at91_sys_write(AT91_SMC_MODE(2), + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_EXNWMODE_DISABLE | + AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16 | + AT91_SMC_TDF_(1)); + + /* Configure Reset signal as output */ + at91_set_gpio_output(AT91_PIN_PC10, 0); + + /* Configure Interrupt pin as input, no pull-up */ + at91_set_gpio_input(AT91_PIN_PC11, 0); +} +#endif + +int board_init(void) +{ + /* Enable Ctrlc */ + console_init_f(); + + /* arch number of AT91SAM9261EK-Board */ + gd->bd->bi_arch_number = MACH_TYPE_AT91SAM9261EK; + /* adress of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + at91sam9261ek_serial_hw_init(); +#ifdef CONFIG_CMD_NAND + at91sam9261ek_nand_hw_init(); +#endif +#ifdef CONFIG_HAS_DATAFLASH + at91sam9261ek_spi_hw_init(); +#endif +#ifdef CONFIG_DRIVER_DM9000 + at91sam9261ek_dm9000_hw_init(); +#endif + return 0; +} + +int dram_init(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM; + gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE; + return 0; +} + +#ifdef CONFIG_RESET_PHY_R +void reset_phy(void) +{ +#ifdef CONFIG_DRIVER_DM9000 + /* + * Initialize ethernet HW addr prior to starting Linux, + * needed for nfsroot + */ + eth_init(gd->bd); +#endif +} +#endif diff --git a/board/atmel/at91sam9261ek/config.mk b/board/atmel/at91sam9261ek/config.mk new file mode 100644 index 00000000000..ff2cfd170bb --- /dev/null +++ b/board/atmel/at91sam9261ek/config.mk @@ -0,0 +1 @@ +TEXT_BASE = 0x23f00000 diff --git a/board/atmel/at91sam9261ek/led.c b/board/atmel/at91sam9261ek/led.c new file mode 100644 index 00000000000..eb2bb23411a --- /dev/null +++ b/board/atmel/at91sam9261ek/led.c @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * 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 +#include +#include +#include +#include + +#define RED_LED AT91_PIN_PA23 /* this is the power led */ +#define GREEN_LED AT91_PIN_PA13 /* this is the user1 led */ +#define YELLOW_LED AT91_PIN_PA14 /* this is the user2 led */ + +void red_LED_on(void) +{ + at91_set_gpio_value(RED_LED, 1); +} + +void red_LED_off(void) +{ + at91_set_gpio_value(RED_LED, 0); +} + +void green_LED_on(void) +{ + at91_set_gpio_value(GREEN_LED, 0); +} + +void green_LED_off(void) +{ + at91_set_gpio_value(GREEN_LED, 1); +} + +void yellow_LED_on(void) +{ + at91_set_gpio_value(YELLOW_LED, 0); +} + +void yellow_LED_off(void) +{ + at91_set_gpio_value(YELLOW_LED, 1); +} + + +void coloured_LED_init(void) +{ + /* Enable clock */ + at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9261_ID_PIOA); + + at91_set_gpio_output(RED_LED, 1); + at91_set_gpio_output(GREEN_LED, 1); + at91_set_gpio_output(YELLOW_LED, 1); + + at91_set_gpio_value(RED_LED, 0); + at91_set_gpio_value(GREEN_LED, 1); + at91_set_gpio_value(YELLOW_LED, 1); +} diff --git a/board/atmel/at91sam9261ek/nand.c b/board/atmel/at91sam9261ek/nand.c new file mode 100644 index 00000000000..35b26dbefef --- /dev/null +++ b/board/atmel/at91sam9261ek/nand.c @@ -0,0 +1,79 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * (C) Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas + * + * 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 +#include +#include +#include + +#include + +/* + * hardware specific access to control-lines + */ +#define MASK_ALE (1 << 22) /* our ALE is AD22 */ +#define MASK_CLE (1 << 21) /* our CLE is AD21 */ + +static void at91sam9261ek_nand_hwcontrol(struct mtd_info *mtd, int cmd) +{ + struct nand_chip *this = mtd->priv; + ulong IO_ADDR_W = (ulong) this->IO_ADDR_W; + + IO_ADDR_W &= ~(MASK_ALE|MASK_CLE); + switch (cmd) { + case NAND_CTL_SETCLE: + IO_ADDR_W |= MASK_CLE; + break; + case NAND_CTL_SETALE: + IO_ADDR_W |= MASK_ALE; + break; + case NAND_CTL_CLRNCE: + at91_set_gpio_value(AT91_PIN_PC14, 1); + break; + case NAND_CTL_SETNCE: + at91_set_gpio_value(AT91_PIN_PC14, 0); + break; + } + this->IO_ADDR_W = (void *) IO_ADDR_W; +} + +static int at91sam9261ek_nand_ready(struct mtd_info *mtd) +{ + return at91_get_gpio_value(AT91_PIN_PC15); +} + +int board_nand_init(struct nand_chip *nand) +{ + nand->eccmode = NAND_ECC_SOFT; +#ifdef CFG_NAND_DBW_16 + nand->options = NAND_BUSWIDTH_16; +#endif + nand->hwcontrol = at91sam9261ek_nand_hwcontrol; + nand->dev_ready = at91sam9261ek_nand_ready; + nand->chip_delay = 20; + + return 0; +} diff --git a/board/atmel/at91sam9261ek/partition.c b/board/atmel/at91sam9261ek/partition.c new file mode 100644 index 00000000000..975be174647 --- /dev/null +++ b/board/atmel/at91sam9261ek/partition.c @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2008 + * Ulf Samuelsson + * + * 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 +#include +#include +#include + +AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS]; + +struct dataflash_addr cs[CFG_MAX_DATAFLASH_BANKS] = { + {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */ + {CFG_DATAFLASH_LOGIC_ADDR_CS3, 3} +}; + +/*define the area offsets*/ +dataflash_protect_t area_list[NB_DATAFLASH_AREA] = { + {0x00000000, 0x000041FF, FLAG_PROTECT_SET, 0, "Bootstrap"}, + {0x00004200, 0x000083FF, FLAG_PROTECT_CLEAR, 0, "Environment"}, + {0x00008400, 0x00041FFF, FLAG_PROTECT_SET, 0, "U-Boot"}, + {0x00042000, 0x00251FFF, FLAG_PROTECT_CLEAR, 0, "Kernel"}, + {0x00252000, 0xFFFFFFFF, FLAG_PROTECT_CLEAR, 0, "FS"}, +}; diff --git a/cpu/arm926ejs/at91sam9/usb.c b/cpu/arm926ejs/at91sam9/usb.c index 441349df3af..2a92f734ddc 100644 --- a/cpu/arm926ejs/at91sam9/usb.c +++ b/cpu/arm926ejs/at91sam9/usb.c @@ -33,7 +33,11 @@ int usb_cpu_init(void) { /* Enable USB host clock. */ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_UHP); +#ifdef CONFIG_AT91SAM9261 + at91_sys_write(AT91_PMC_SCER, AT91_PMC_UHP | AT91_PMC_HCK0); +#else at91_sys_write(AT91_PMC_SCER, AT91_PMC_UHP); +#endif return 0; } @@ -42,7 +46,11 @@ int usb_cpu_stop(void) { /* Disable USB host clock. */ at91_sys_write(AT91_PMC_PCDR, 1 << AT91_ID_UHP); +#ifdef CONFIG_AT91SAM9261 + at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP | AT91_PMC_HCK0); +#else at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP); +#endif return 0; } diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 6131b5c3570..db6d3bd284d 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -300,8 +300,10 @@ eth_init(bd_t * bd) DM9000_iow(DM9000_ISR, 0x0f); /* Clear interrupt status */ /* Set Node address */ +#ifndef CONFIG_AT91SAM9261EK for (i = 0; i < 6; i++) ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i); +#endif if (is_zero_ether_addr(bd->bi_enetaddr) || is_multicast_ether_addr(bd->bi_enetaddr)) { diff --git a/include/asm-arm/arch-at91sam9/at91sam9261.h b/include/asm-arm/arch-at91sam9/at91sam9261.h new file mode 100644 index 00000000000..752d81dfe3f --- /dev/null +++ b/include/asm-arm/arch-at91sam9/at91sam9261.h @@ -0,0 +1,105 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9261.h] + * + * Copyright (C) SAN People + * + * Common definitions. + * Based on AT91SAM9261 datasheet revision E. (Preliminary) + * + * 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 AT91SAM9261_H +#define AT91SAM9261_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define AT91_ID_SYS 1 /* System Peripherals */ +#define AT91SAM9261_ID_PIOA 2 /* Parallel IO Controller A */ +#define AT91SAM9261_ID_PIOB 3 /* Parallel IO Controller B */ +#define AT91SAM9261_ID_PIOC 4 /* Parallel IO Controller C */ +#define AT91SAM9261_ID_US0 6 /* USART 0 */ +#define AT91SAM9261_ID_US1 7 /* USART 1 */ +#define AT91SAM9261_ID_US2 8 /* USART 2 */ +#define AT91SAM9261_ID_MCI 9 /* Multimedia Card Interface */ +#define AT91SAM9261_ID_UDP 10 /* USB Device Port */ +#define AT91SAM9261_ID_TWI 11 /* Two-Wire Interface */ +#define AT91SAM9261_ID_SPI0 12 /* Serial Peripheral Interface 0 */ +#define AT91SAM9261_ID_SPI1 13 /* Serial Peripheral Interface 1 */ +#define AT91SAM9261_ID_SSC0 14 /* Serial Synchronous Controller 0 */ +#define AT91SAM9261_ID_SSC1 15 /* Serial Synchronous Controller 1 */ +#define AT91SAM9261_ID_SSC2 16 /* Serial Synchronous Controller 2 */ +#define AT91SAM9261_ID_TC0 17 /* Timer Counter 0 */ +#define AT91SAM9261_ID_TC1 18 /* Timer Counter 1 */ +#define AT91SAM9261_ID_TC2 19 /* Timer Counter 2 */ +#define AT91SAM9261_ID_UHP 20 /* USB Host port */ +#define AT91SAM9261_ID_LCDC 21 /* LDC Controller */ +#define AT91SAM9261_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */ +#define AT91SAM9261_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */ +#define AT91SAM9261_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */ + + +/* + * User Peripheral physical base addresses. + */ +#define AT91SAM9261_BASE_TCB0 0xfffa0000 +#define AT91SAM9261_BASE_TC0 0xfffa0000 +#define AT91SAM9261_BASE_TC1 0xfffa0040 +#define AT91SAM9261_BASE_TC2 0xfffa0080 +#define AT91SAM9261_BASE_UDP 0xfffa4000 +#define AT91SAM9261_BASE_MCI 0xfffa8000 +#define AT91SAM9261_BASE_TWI 0xfffac000 +#define AT91SAM9261_BASE_US0 0xfffb0000 +#define AT91SAM9261_BASE_US1 0xfffb4000 +#define AT91SAM9261_BASE_US2 0xfffb8000 +#define AT91SAM9261_BASE_SSC0 0xfffbc000 +#define AT91SAM9261_BASE_SSC1 0xfffc0000 +#define AT91SAM9261_BASE_SSC2 0xfffc4000 +#define AT91SAM9261_BASE_SPI0 0xfffc8000 +#define AT91SAM9261_BASE_SPI1 0xfffcc000 +#define AT91_BASE_SYS 0xffffea00 + + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_SDRAMC (0xffffea00 - AT91_BASE_SYS) +#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) +#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) +#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) +#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) +#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) +#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) +#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) +#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) +#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) +#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) +#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) +#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) +#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) + +#define AT91_USART0 AT91SAM9261_BASE_US0 +#define AT91_USART1 AT91SAM9261_BASE_US1 +#define AT91_USART2 AT91SAM9261_BASE_US2 + + +/* + * Internal Memory. + */ +#define AT91SAM9261_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define AT91SAM9261_SRAM_SIZE 0x00028000 /* Internal SRAM size (160Kb) */ + +#define AT91SAM9261_ROM_BASE 0x00400000 /* Internal ROM base address */ +#define AT91SAM9261_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ + +#define AT91SAM9261_UHP_BASE 0x00500000 /* USB Host controller */ +#define AT91SAM9261_LCDC_BASE 0x00600000 /* LDC controller */ + + +#endif diff --git a/include/asm-arm/arch-at91sam9/at91sam9261_matrix.h b/include/asm-arm/arch-at91sam9/at91sam9261_matrix.h new file mode 100644 index 00000000000..e2bfc4b0c9b --- /dev/null +++ b/include/asm-arm/arch-at91sam9/at91sam9261_matrix.h @@ -0,0 +1,64 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9261_matrix.h] + * + * Copyright (C) 2007 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9261 datasheet revision D. + * + * 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 AT91SAM9261_MATRIX_H +#define AT91SAM9261_MATRIX_H + +#define AT91_MATRIX_MCFG (AT91_MATRIX + 0x00) /* Master Configuration Register */ +#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ + +#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x04) /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x08) /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x0C) /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x10) /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x14) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ +#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */ + +#define AT91_MATRIX_TCR (AT91_MATRIX + 0x24) /* TCM Configuration Register */ +#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ +#define AT91_MATRIX_ITCM_0 (0 << 0) +#define AT91_MATRIX_ITCM_16 (5 << 0) +#define AT91_MATRIX_ITCM_32 (6 << 0) +#define AT91_MATRIX_ITCM_64 (7 << 0) +#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */ +#define AT91_MATRIX_DTCM_0 (0 << 4) +#define AT91_MATRIX_DTCM_16 (5 << 4) +#define AT91_MATRIX_DTCM_32 (6 << 4) +#define AT91_MATRIX_DTCM_64 (7 << 4) + +#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x30) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_CS1A_SMC (0 << 1) +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_CS3A_SMC (0 << 3) +#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */ +#define AT91_MATRIX_CS4A_SMC (0 << 4) +#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */ +#define AT91_MATRIX_CS5A_SMC (0 << 5) +#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ + +#define AT91_MATRIX_USBPUCR (AT91_MATRIX + 0x34) /* USB Pad Pull-Up Control Register */ +#define AT91_MATRIX_USBPUCR_PUON (1 << 30) /* USB Device PAD Pull-up Enable */ + +#endif diff --git a/include/asm-arm/arch-at91sam9/hardware.h b/include/asm-arm/arch-at91sam9/hardware.h index d2fe45388b3..06bab621f61 100644 --- a/include/asm-arm/arch-at91sam9/hardware.h +++ b/include/asm-arm/arch-at91sam9/hardware.h @@ -26,6 +26,9 @@ #define AT91_PMC_UHP AT91SAM926x_PMC_UHP #elif defined(CONFIG_AT91SAM9261) #include +#define AT91_BASE_SPI AT91SAM9261_BASE_SPI0 +#define AT91_ID_UHP AT91SAM9261_ID_UHP +#define AT91_PMC_UHP AT91SAM926x_PMC_UHP #elif defined(CONFIG_AT91SAM9263) #include #elif defined(CONFIG_AT91SAM9RL) diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h new file mode 100644 index 00000000000..96fc6afcfeb --- /dev/null +++ b/include/configs/at91sam9261ek.h @@ -0,0 +1,191 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * Configuation settings for the AT91SAM9261EK 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 + +/* ARM asynchronous clock */ +#define AT91_MAIN_CLOCK 198656000 /* from 18.432 MHz crystal */ +#define AT91_MASTER_CLOCK 99328000 /* peripheral = main / 2 */ +#define CFG_HZ 1000000 /* 1us resolution */ + +#define AT91_SLOW_CLOCK 32768 /* slow clock */ + +#define CONFIG_ARM926EJS 1 /* This is an ARM926EJS Core */ +#define CONFIG_AT91SAM9261 1 /* It's an Atmel AT91SAM9261 SoC*/ +#define CONFIG_AT91SAM9261EK 1 /* on an AT91SAM9261EK Board */ +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 + +#define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_SKIP_RELOCATE_UBOOT + +/* + * Hardware drivers + */ +#define CONFIG_ATMEL_USART 1 +#undef CONFIG_USART0 +#undef CONFIG_USART1 +#undef CONFIG_USART2 +#define CONFIG_USART3 1 /* USART 3 is DBGU */ + +#define CONFIG_BOOTDELAY 3 + +/* #define CONFIG_ENV_OVERWRITE 1 */ + +/* + * BOOTP options + */ +#define CONFIG_BOOTP_BOOTFILESIZE 1 +#define CONFIG_BOOTP_BOOTPATH 1 +#define CONFIG_BOOTP_GATEWAY 1 +#define CONFIG_BOOTP_HOSTNAME 1 + +/* + * Command line configuration. + */ +#include +#undef CONFIG_CMD_BDI +#undef CONFIG_CMD_IMI +#undef CONFIG_CMD_AUTOSCRIPT +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_LOADS +#undef CONFIG_CMD_IMLS + +#define CONFIG_CMD_PING 1 +#define CONFIG_CMD_DHCP 1 +#define CONFIG_CMD_NAND 1 +#define CONFIG_CMD_USB 1 + +/* SDRAM */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM 0x20000000 +#define PHYS_SDRAM_SIZE 0x04000000 /* 64 megs */ + +/* DataFlash */ +#define CONFIG_HAS_DATAFLASH 1 +#define CFG_SPI_WRITE_TOUT (5*CFG_HZ) +#define CFG_MAX_DATAFLASH_BANKS 2 +#define CFG_DATAFLASH_LOGIC_ADDR_CS0 0xC0000000 /* CS0 */ +#define CFG_DATAFLASH_LOGIC_ADDR_CS3 0xD0000000 /* CS3 */ +#define AT91_SPI_CLK 15000000 +#define DATAFLASH_TCSS (0x1a << 16) +#define DATAFLASH_TCHS (0x1 << 24) + +/* NAND flash */ +#define NAND_MAX_CHIPS 1 +#define CFG_MAX_NAND_DEVICE 1 +#define CFG_NAND_BASE 0x40000000 +#define CFG_NAND_DBW_8 1 + +/* NOR flash - no real flash on this board */ +#define CFG_NO_FLASH 1 + +/* Ethernet */ +#define CONFIG_DRIVER_DM9000 1 +#define CONFIG_DM9000_BASE 0x30000000 +#define DM9000_IO CONFIG_DM9000_BASE +#define DM9000_DATA (CONFIG_DM9000_BASE + 4) +#define CONFIG_DM9000_USE_16BIT 1 +#define CONFIG_NET_RETRY_COUNT 20 +#define CONFIG_RESET_PHY_R 1 + +/* USB */ +#define CONFIG_USB_OHCI_NEW 1 +#define LITTLEENDIAN 1 +#define CONFIG_DOS_PARTITION 1 +#define CFG_USB_OHCI_CPU_INIT 1 +#define CFG_USB_OHCI_REGS_BASE 0x00500000 /* AT91SAM9261_UHP_BASE */ +#define CFG_USB_OHCI_SLOT_NAME "at91sam9261" +#define CFG_USB_OHCI_MAX_ROOT_PORTS 2 +#define CONFIG_USB_STORAGE 1 + +#define CFG_LOAD_ADDR 0x22000000 /* load address */ + +#define CFG_MEMTEST_START PHYS_SDRAM +#define CFG_MEMTEST_END 0x23e00000 + +#define CFG_USE_DATAFLASH_CS0 1 +#undef CFG_USE_NANDFLASH + +#ifdef CFG_USE_DATAFLASH_CS0 + +/* bootstrap + u-boot + env + linux in dataflash on CS0 */ +#define CFG_ENV_IS_IN_DATAFLASH 1 +#define CFG_MONITOR_BASE (CFG_DATAFLASH_LOGIC_ADDR_CS0 + 0x8400) +#define CFG_ENV_OFFSET 0x4200 +#define CFG_ENV_ADDR (CFG_DATAFLASH_LOGIC_ADDR_CS0 + CFG_ENV_OFFSET) +#define CFG_ENV_SIZE 0x4200 +#define CONFIG_BOOTCOMMAND "cp.b 0xC0042000 0x22000000 0x210000; bootm" +#define CONFIG_BOOTARGS "console=ttyS0,115200 " \ + "root=/dev/mtdblock0 " \ + "mtdparts=at91_nand:-(root) " \ + "rw rootfstype=jffs2" + +#else /* CFG_USE_NANDFLASH */ + +/* bootstrap + u-boot + env + linux in nandflash */ +#define CFG_ENV_IS_IN_NAND 1 +#define CFG_ENV_OFFSET 0x60000 +#define CFG_ENV_OFFSET_REDUND 0x80000 +#define CFG_ENV_SIZE 0x20000 /* 1 sector = 128 kB */ +#define CONFIG_BOOTCOMMAND "nand read 0x22000000 0xA0000 0x200000; bootm" +#define CONFIG_BOOTARGS "console=ttyS0,115200 " \ + "root=/dev/mtdblock5 " \ + "mtdparts=at91_nand:128k(bootstrap)ro," \ + "256k(uboot)ro,128k(env1)ro," \ + "128k(env2)ro,2M(linux),-(root) " \ + "rw rootfstype=jffs2" + +#endif + +#define CONFIG_BAUDRATE 115200 +#define CFG_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 } + +#define CFG_PROMPT "U-Boot> " +#define CFG_CBSIZE 256 +#define CFG_MAXARGS 16 +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) +#define CFG_LONGHELP 1 +#define CONFIG_CMDLINE_EDITING 1 + +#define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN ROUND(3 * CFG_ENV_SIZE + 128*1024, 0x1000) +#define CFG_GBL_DATA_SIZE 128 /* 128 bytes for initial data */ + +#define CONFIG_STACKSIZE (32*1024) /* regular stack */ + +#ifdef CONFIG_USE_IRQ +#error CONFIG_USE_IRQ not supported +#endif + +#endif -- cgit v1.3.1 From f793a3581901ff39c2abb94012d9bbc8573ccf02 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 16 Apr 2008 22:57:58 -0700 Subject: avr32: Disable the AP7000 internal watchdog on startup This patch forces the watchdog off in all cases. That will at least get rid of the constant reboot cycle, though it won't let the watchdog actually run in the new kernels: its probe() comes up with a polite warning. Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/cpu.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'cpu') diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c index 311466b7814..4542e679732 100644 --- a/cpu/at32ap/cpu.c +++ b/cpu/at32ap/cpu.c @@ -86,6 +86,10 @@ int cpu_init(void) extern void _evba(void); char *p; + /* in case of soft resets, disable watchdog */ + sm_writel(WDT_CTRL, SM_BF(KEY, 0x55)); + sm_writel(WDT_CTRL, SM_BF(KEY, 0xaa)); + gd->cpu_hz = CFG_OSC0_HZ; /* TODO: Move somewhere else, but needs to be run before we -- cgit v1.3.1 From 781eb9a1e4af4bd34c138e6126ec5cc6dd4b5440 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 29 Apr 2008 12:53:05 +0200 Subject: avr32: Get rid of the .flashprog section The .flashprog section was only needed back when we were running directly from flash, and it's even more useless on NGW100 since it uses the CFI flash driver which never used this workaround in the first place. Remove it on STK1000 as well, and get rid of all the associated code and annotations. Signed-off-by: Haavard Skinnemoen --- board/atmel/atngw100/u-boot.lds | 8 -------- board/atmel/atstk1000/flash.c | 6 +++--- board/atmel/atstk1000/u-boot.lds | 8 -------- cpu/at32ap/cpu.c | 6 ------ include/asm-avr32/sections.h | 7 ------- 5 files changed, 3 insertions(+), 32 deletions(-) (limited to 'cpu') diff --git a/board/atmel/atngw100/u-boot.lds b/board/atmel/atngw100/u-boot.lds index 34e347aecd5..3c878d8657a 100644 --- a/board/atmel/atngw100/u-boot.lds +++ b/board/atmel/atngw100/u-boot.lds @@ -32,14 +32,6 @@ SECTIONS *(.text) *(.text.*) } - - . = ALIGN(32); - __flashprog_start = .; - .flashprog : { - *(.flashprog) - } - . = ALIGN(32); - __flashprog_end = .; _etext = .; .rodata : { diff --git a/board/atmel/atstk1000/flash.c b/board/atmel/atstk1000/flash.c index 40478258e7c..12537f3142e 100644 --- a/board/atmel/atstk1000/flash.c +++ b/board/atmel/atstk1000/flash.c @@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; flash_info_t flash_info[1]; -static void __flashprog flash_identify(uint16_t *flash, flash_info_t *info) +static void flash_identify(uint16_t *flash, flash_info_t *info) { unsigned long flags; @@ -76,7 +76,7 @@ void flash_print_info(flash_info_t *info) info->size >> 10, info->sector_count); } -int __flashprog flash_erase(flash_info_t *info, int s_first, int s_last) +int flash_erase(flash_info_t *info, int s_first, int s_last) { unsigned long flags; unsigned long start_time; @@ -154,7 +154,7 @@ int __flashprog flash_erase(flash_info_t *info, int s_first, int s_last) return ERR_OK; } -int __flashprog write_buff(flash_info_t *info, uchar *src, +int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong count) { unsigned long flags; diff --git a/board/atmel/atstk1000/u-boot.lds b/board/atmel/atstk1000/u-boot.lds index 247812e1036..f63bc4ff27a 100644 --- a/board/atmel/atstk1000/u-boot.lds +++ b/board/atmel/atstk1000/u-boot.lds @@ -32,14 +32,6 @@ SECTIONS *(.text) *(.text.*) } - - . = ALIGN(32); - __flashprog_start = .; - .flashprog : { - *(.flashprog) - } - . = ALIGN(32); - __flashprog_end = .; _etext = .; .rodata : { diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c index 4542e679732..a7a66cc1a0b 100644 --- a/cpu/at32ap/cpu.c +++ b/cpu/at32ap/cpu.c @@ -84,7 +84,6 @@ static void pm_init(void) int cpu_init(void) { extern void _evba(void); - char *p; /* in case of soft resets, disable watchdog */ sm_writel(WDT_CTRL, SM_BF(KEY, 0x55)); @@ -104,11 +103,6 @@ int cpu_init(void) sysreg_write(EVBA, (unsigned long)&_evba); asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET)); - /* Lock everything that mess with the flash in the icache */ - for (p = __flashprog_start; p <= (__flashprog_end + CFG_ICACHE_LINESZ); - p += CFG_ICACHE_LINESZ) - asm volatile("cache %0, 0x02" : "=m"(*p) :: "memory"); - return 0; } diff --git a/include/asm-avr32/sections.h b/include/asm-avr32/sections.h index 75373abde73..fe819b2db6e 100644 --- a/include/asm-avr32/sections.h +++ b/include/asm-avr32/sections.h @@ -25,15 +25,8 @@ /* References to section boundaries */ extern char _text[], _etext[]; -extern char __flashprog_start[], __flashprog_end[]; extern char _data[], __data_lma[], _edata[], __edata_lma[]; extern char __got_start[], __got_lma[], __got_end[]; extern char _end[]; -/* - * Everything in .flashprog will be locked in the icache so it doesn't - * get disturbed when executing flash commands. - */ -#define __flashprog __attribute__((section(".flashprog"), __noinline__)) - #endif /* __ASM_AVR32_SECTIONS_H */ -- cgit v1.3.1 From a9b2bb78a1bd8ebdb633509bdd1c8134d527b213 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 30 Apr 2008 14:36:47 +0200 Subject: avr32: Remove unused file cpu/at32ap/pm.c Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/pm.c | 42 ------------------------------------------ 1 file changed, 42 deletions(-) delete mode 100644 cpu/at32ap/pm.c (limited to 'cpu') diff --git a/cpu/at32ap/pm.c b/cpu/at32ap/pm.c deleted file mode 100644 index c78d547f85e..00000000000 --- a/cpu/at32ap/pm.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 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 - */ -#include - -#ifdef CFG_POWER_MANAGER -#include -#include - -#include - -#include "sm.h" - - -#ifdef CONFIG_PLL -#define MAIN_CLK_RATE ((CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL) -#else -#define MAIN_CLK_RATE (CFG_OSC0_HZ) -#endif - -DECLARE_GLOBAL_DATA_PTR; - - -#endif /* CFG_POWER_MANAGER */ -- cgit v1.3.1 From 4f5972c3b2454c22957f2842cfe64ec8118e015b Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 30 Apr 2008 16:15:57 +0200 Subject: avr32: Use new-style Makefile for the at32ap platform This makes it easier to avoid compiling certain files later. Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/Makefile | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'cpu') diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile index f69b1f38546..8e384c7e07f 100644 --- a/cpu/at32ap/Makefile +++ b/cpu/at32ap/Makefile @@ -27,13 +27,20 @@ include $(TOPDIR)/config.mk LIB := $(obj)lib$(CPU).a -START := start.o -SOBJS := entry.o -COBJS := cpu.o hsdramc.o exception.o cache.o -COBJS += interrupts.o pio.o atmel_mci.o -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) +START-y += start.o + +SOBJS-y += entry.o +COBJS-y += cpu.o +COBJS-y += hsdramc.o +COBJS-y += exception.o +COBJS-y += cache.o +COBJS-y += interrupts.o +COBJS-y += pio.o +COBJS-y += atmel_mci.o + +SRCS := $(START-y:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +START := $(addprefix $(obj),$(START-y)) all: $(obj).depend $(START) $(LIB) -- cgit v1.3.1 From 3ace2527ba80bd2fe1bceaab50d0b3c4fb5dd020 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 2 May 2008 15:21:40 +0200 Subject: avr32: Rename pm_init() as clk_init() and make SoC-specific pm_init() was always more about clock initialization than anything else. Dealing with PLLs, clock gating and such is also inherently SoC-specific, so move it into a SoC-specific directory. Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/at32ap700x/Makefile | 2 +- cpu/at32ap/at32ap700x/clk.c | 68 +++++++++++ cpu/at32ap/at32ap700x/sm.h | 204 ++++++++++++++++++++++++++++++++ cpu/at32ap/cpu.c | 48 +------- cpu/at32ap/sm.h | 204 -------------------------------- include/asm-avr32/arch-at32ap700x/clk.h | 2 + 6 files changed, 280 insertions(+), 248 deletions(-) create mode 100644 cpu/at32ap/at32ap700x/clk.c create mode 100644 cpu/at32ap/at32ap700x/sm.h delete mode 100644 cpu/at32ap/sm.h (limited to 'cpu') diff --git a/cpu/at32ap/at32ap700x/Makefile b/cpu/at32ap/at32ap700x/Makefile index d2767121184..740423563ed 100644 --- a/cpu/at32ap/at32ap700x/Makefile +++ b/cpu/at32ap/at32ap700x/Makefile @@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)lib$(SOC).a -COBJS := gpio.o +COBJS := gpio.o clk.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/at32ap/at32ap700x/clk.c b/cpu/at32ap/at32ap700x/clk.c new file mode 100644 index 00000000000..b3aa03495f5 --- /dev/null +++ b/cpu/at32ap/at32ap700x/clk.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005-2008 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 + */ +#include + +#include + +#include +#include + +#include "sm.h" + +void clk_init(void) +{ + uint32_t cksel; + + /* in case of soft resets, disable watchdog */ + sm_writel(WDT_CTRL, SM_BF(KEY, 0x55)); + sm_writel(WDT_CTRL, SM_BF(KEY, 0xaa)); + +#ifdef CONFIG_PLL + /* Initialize the PLL */ + sm_writel(PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES) + | SM_BF(PLLMUL, CFG_PLL0_MUL - 1) + | SM_BF(PLLDIV, CFG_PLL0_DIV - 1) + | SM_BF(PLLOPT, CFG_PLL0_OPT) + | SM_BF(PLLOSC, 0) + | SM_BIT(PLLEN))); + + /* Wait for lock */ + while (!(sm_readl(PM_ISR) & SM_BIT(LOCK0))) ; +#endif + + /* Set up clocks for the CPU and all peripheral buses */ + cksel = 0; + if (CFG_CLKDIV_CPU) + cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1); + if (CFG_CLKDIV_HSB) + cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1); + if (CFG_CLKDIV_PBA) + cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1); + if (CFG_CLKDIV_PBB) + cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1); + sm_writel(PM_CKSEL, cksel); + +#ifdef CONFIG_PLL + /* Use PLL0 as main clock */ + sm_writel(PM_MCCTRL, SM_BIT(PLLSEL)); +#endif +} diff --git a/cpu/at32ap/at32ap700x/sm.h b/cpu/at32ap/at32ap700x/sm.h new file mode 100644 index 00000000000..6492c8e81d2 --- /dev/null +++ b/cpu/at32ap/at32ap700x/sm.h @@ -0,0 +1,204 @@ +/* + * Register definitions for System Manager + */ +#ifndef __CPU_AT32AP_SM_H__ +#define __CPU_AT32AP_SM_H__ + +/* SM register offsets */ +#define SM_PM_MCCTRL 0x0000 +#define SM_PM_CKSEL 0x0004 +#define SM_PM_CPU_MASK 0x0008 +#define SM_PM_HSB_MASK 0x000c +#define SM_PM_PBA_MASK 0x0010 +#define SM_PM_PBB_MASK 0x0014 +#define SM_PM_PLL0 0x0020 +#define SM_PM_PLL1 0x0024 +#define SM_PM_VCTRL 0x0030 +#define SM_PM_VMREF 0x0034 +#define SM_PM_VMV 0x0038 +#define SM_PM_IER 0x0040 +#define SM_PM_IDR 0x0044 +#define SM_PM_IMR 0x0048 +#define SM_PM_ISR 0x004c +#define SM_PM_ICR 0x0050 +#define SM_PM_GCCTRL 0x0060 +#define SM_RTC_CTRL 0x0080 +#define SM_RTC_VAL 0x0084 +#define SM_RTC_TOP 0x0088 +#define SM_RTC_IER 0x0090 +#define SM_RTC_IDR 0x0094 +#define SM_RTC_IMR 0x0098 +#define SM_RTC_ISR 0x009c +#define SM_RTC_ICR 0x00a0 +#define SM_WDT_CTRL 0x00b0 +#define SM_WDT_CLR 0x00b4 +#define SM_WDT_EXT 0x00b8 +#define SM_RC_RCAUSE 0x00c0 +#define SM_EIM_IER 0x0100 +#define SM_EIM_IDR 0x0104 +#define SM_EIM_IMR 0x0108 +#define SM_EIM_ISR 0x010c +#define SM_EIM_ICR 0x0110 +#define SM_EIM_MODE 0x0114 +#define SM_EIM_EDGE 0x0118 +#define SM_EIM_LEVEL 0x011c +#define SM_EIM_TEST 0x0120 +#define SM_EIM_NMIC 0x0124 + +/* Bitfields in PM_CKSEL */ +#define SM_CPUSEL_OFFSET 0 +#define SM_CPUSEL_SIZE 3 +#define SM_CPUDIV_OFFSET 7 +#define SM_CPUDIV_SIZE 1 +#define SM_HSBSEL_OFFSET 8 +#define SM_HSBSEL_SIZE 3 +#define SM_HSBDIV_OFFSET 15 +#define SM_HSBDIV_SIZE 1 +#define SM_PBASEL_OFFSET 16 +#define SM_PBASEL_SIZE 3 +#define SM_PBADIV_OFFSET 23 +#define SM_PBADIV_SIZE 1 +#define SM_PBBSEL_OFFSET 24 +#define SM_PBBSEL_SIZE 3 +#define SM_PBBDIV_OFFSET 31 +#define SM_PBBDIV_SIZE 1 + +/* Bitfields in PM_PLL0 */ +#define SM_PLLEN_OFFSET 0 +#define SM_PLLEN_SIZE 1 +#define SM_PLLOSC_OFFSET 1 +#define SM_PLLOSC_SIZE 1 +#define SM_PLLOPT_OFFSET 2 +#define SM_PLLOPT_SIZE 3 +#define SM_PLLDIV_OFFSET 8 +#define SM_PLLDIV_SIZE 8 +#define SM_PLLMUL_OFFSET 16 +#define SM_PLLMUL_SIZE 8 +#define SM_PLLCOUNT_OFFSET 24 +#define SM_PLLCOUNT_SIZE 6 +#define SM_PLLTEST_OFFSET 31 +#define SM_PLLTEST_SIZE 1 + +/* Bitfields in PM_VCTRL */ +#define SM_VAUTO_OFFSET 0 +#define SM_VAUTO_SIZE 1 +#define SM_PM_VCTRL_VAL_OFFSET 8 +#define SM_PM_VCTRL_VAL_SIZE 7 + +/* Bitfields in PM_VMREF */ +#define SM_REFSEL_OFFSET 0 +#define SM_REFSEL_SIZE 4 + +/* Bitfields in PM_VMV */ +#define SM_PM_VMV_VAL_OFFSET 0 +#define SM_PM_VMV_VAL_SIZE 8 + +/* Bitfields in PM_ICR */ +#define SM_LOCK0_OFFSET 0 +#define SM_LOCK0_SIZE 1 +#define SM_LOCK1_OFFSET 1 +#define SM_LOCK1_SIZE 1 +#define SM_WAKE_OFFSET 2 +#define SM_WAKE_SIZE 1 +#define SM_VOK_OFFSET 3 +#define SM_VOK_SIZE 1 +#define SM_VMRDY_OFFSET 4 +#define SM_VMRDY_SIZE 1 +#define SM_CKRDY_OFFSET 5 +#define SM_CKRDY_SIZE 1 + +/* Bitfields in PM_GCCTRL */ +#define SM_OSCSEL_OFFSET 0 +#define SM_OSCSEL_SIZE 1 +#define SM_PLLSEL_OFFSET 1 +#define SM_PLLSEL_SIZE 1 +#define SM_CEN_OFFSET 2 +#define SM_CEN_SIZE 1 +#define SM_CPC_OFFSET 3 +#define SM_CPC_SIZE 1 +#define SM_DIVEN_OFFSET 4 +#define SM_DIVEN_SIZE 1 +#define SM_DIV_OFFSET 8 +#define SM_DIV_SIZE 8 + +/* Bitfields in RTC_CTRL */ +#define SM_PCLR_OFFSET 1 +#define SM_PCLR_SIZE 1 +#define SM_TOPEN_OFFSET 2 +#define SM_TOPEN_SIZE 1 +#define SM_CLKEN_OFFSET 3 +#define SM_CLKEN_SIZE 1 +#define SM_PSEL_OFFSET 8 +#define SM_PSEL_SIZE 16 + +/* Bitfields in RTC_VAL */ +#define SM_RTC_VAL_VAL_OFFSET 0 +#define SM_RTC_VAL_VAL_SIZE 31 + +/* Bitfields in RTC_TOP */ +#define SM_RTC_TOP_VAL_OFFSET 0 +#define SM_RTC_TOP_VAL_SIZE 32 + +/* Bitfields in RTC_ICR */ +#define SM_TOPI_OFFSET 0 +#define SM_TOPI_SIZE 1 + +/* Bitfields in WDT_CTRL */ +#define SM_KEY_OFFSET 24 +#define SM_KEY_SIZE 8 + +/* Bitfields in RC_RCAUSE */ +#define SM_POR_OFFSET 0 +#define SM_POR_SIZE 1 +#define SM_BOD_OFFSET 1 +#define SM_BOD_SIZE 1 +#define SM_EXT_OFFSET 2 +#define SM_EXT_SIZE 1 +#define SM_WDT_OFFSET 3 +#define SM_WDT_SIZE 1 +#define SM_NTAE_OFFSET 4 +#define SM_NTAE_SIZE 1 +#define SM_SERP_OFFSET 5 +#define SM_SERP_SIZE 1 + +/* Bitfields in EIM_EDGE */ +#define SM_INT0_OFFSET 0 +#define SM_INT0_SIZE 1 +#define SM_INT1_OFFSET 1 +#define SM_INT1_SIZE 1 +#define SM_INT2_OFFSET 2 +#define SM_INT2_SIZE 1 +#define SM_INT3_OFFSET 3 +#define SM_INT3_SIZE 1 + +/* Bitfields in EIM_LEVEL */ + +/* Bitfields in EIM_TEST */ +#define SM_TESTEN_OFFSET 31 +#define SM_TESTEN_SIZE 1 + +/* Bitfields in EIM_NMIC */ +#define SM_EN_OFFSET 0 +#define SM_EN_SIZE 1 + +/* Bit manipulation macros */ +#define SM_BIT(name) \ + (1 << SM_##name##_OFFSET) +#define SM_BF(name,value) \ + (((value) & ((1 << SM_##name##_SIZE) - 1)) \ + << SM_##name##_OFFSET) +#define SM_BFEXT(name,value) \ + (((value) >> SM_##name##_OFFSET) \ + & ((1 << SM_##name##_SIZE) - 1)) +#define SM_BFINS(name,value,old) \ + (((old) & ~(((1 << SM_##name##_SIZE) - 1) \ + << SM_##name##_OFFSET)) \ + | SM_BF(name,value)) + +/* Register access macros */ +#define sm_readl(reg) \ + readl((void *)SM_BASE + SM_##reg) +#define sm_writel(reg,value) \ + writel((value), (void *)SM_BASE + SM_##reg) + +#endif /* __CPU_AT32AP_SM_H__ */ diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c index a7a66cc1a0b..0ba836180e4 100644 --- a/cpu/at32ap/cpu.c +++ b/cpu/at32ap/cpu.c @@ -30,7 +30,6 @@ #include #include "hsmc3.h" -#include "sm.h" /* Sanity checks */ #if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB) \ @@ -44,51 +43,10 @@ DECLARE_GLOBAL_DATA_PTR; -static void pm_init(void) -{ - uint32_t cksel; - -#ifdef CONFIG_PLL - /* Initialize the PLL */ - sm_writel(PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES) - | SM_BF(PLLMUL, CFG_PLL0_MUL - 1) - | SM_BF(PLLDIV, CFG_PLL0_DIV - 1) - | SM_BF(PLLOPT, CFG_PLL0_OPT) - | SM_BF(PLLOSC, 0) - | SM_BIT(PLLEN))); - - /* Wait for lock */ - while (!(sm_readl(PM_ISR) & SM_BIT(LOCK0))) ; -#endif - - /* Set up clocks for the CPU and all peripheral buses */ - cksel = 0; - if (CFG_CLKDIV_CPU) - cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1); - if (CFG_CLKDIV_HSB) - cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1); - if (CFG_CLKDIV_PBA) - cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1); - if (CFG_CLKDIV_PBB) - cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1); - sm_writel(PM_CKSEL, cksel); - - gd->cpu_hz = get_cpu_clk_rate(); - -#ifdef CONFIG_PLL - /* Use PLL0 as main clock */ - sm_writel(PM_MCCTRL, SM_BIT(PLLSEL)); -#endif -} - int cpu_init(void) { extern void _evba(void); - /* in case of soft resets, disable watchdog */ - sm_writel(WDT_CTRL, SM_BF(KEY, 0x55)); - sm_writel(WDT_CTRL, SM_BF(KEY, 0xaa)); - gd->cpu_hz = CFG_OSC0_HZ; /* TODO: Move somewhere else, but needs to be run before we @@ -98,8 +56,12 @@ int cpu_init(void) hsmc3_writel(PULSE0, 0x0b0a0906); hsmc3_writel(SETUP0, 0x00010002); - pm_init(); + clk_init(); + + /* Update the CPU speed according to the PLL configuration */ + gd->cpu_hz = get_cpu_clk_rate(); + /* Set up the exception handler table and enable exceptions */ sysreg_write(EVBA, (unsigned long)&_evba); asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET)); diff --git a/cpu/at32ap/sm.h b/cpu/at32ap/sm.h deleted file mode 100644 index 6492c8e81d2..00000000000 --- a/cpu/at32ap/sm.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Register definitions for System Manager - */ -#ifndef __CPU_AT32AP_SM_H__ -#define __CPU_AT32AP_SM_H__ - -/* SM register offsets */ -#define SM_PM_MCCTRL 0x0000 -#define SM_PM_CKSEL 0x0004 -#define SM_PM_CPU_MASK 0x0008 -#define SM_PM_HSB_MASK 0x000c -#define SM_PM_PBA_MASK 0x0010 -#define SM_PM_PBB_MASK 0x0014 -#define SM_PM_PLL0 0x0020 -#define SM_PM_PLL1 0x0024 -#define SM_PM_VCTRL 0x0030 -#define SM_PM_VMREF 0x0034 -#define SM_PM_VMV 0x0038 -#define SM_PM_IER 0x0040 -#define SM_PM_IDR 0x0044 -#define SM_PM_IMR 0x0048 -#define SM_PM_ISR 0x004c -#define SM_PM_ICR 0x0050 -#define SM_PM_GCCTRL 0x0060 -#define SM_RTC_CTRL 0x0080 -#define SM_RTC_VAL 0x0084 -#define SM_RTC_TOP 0x0088 -#define SM_RTC_IER 0x0090 -#define SM_RTC_IDR 0x0094 -#define SM_RTC_IMR 0x0098 -#define SM_RTC_ISR 0x009c -#define SM_RTC_ICR 0x00a0 -#define SM_WDT_CTRL 0x00b0 -#define SM_WDT_CLR 0x00b4 -#define SM_WDT_EXT 0x00b8 -#define SM_RC_RCAUSE 0x00c0 -#define SM_EIM_IER 0x0100 -#define SM_EIM_IDR 0x0104 -#define SM_EIM_IMR 0x0108 -#define SM_EIM_ISR 0x010c -#define SM_EIM_ICR 0x0110 -#define SM_EIM_MODE 0x0114 -#define SM_EIM_EDGE 0x0118 -#define SM_EIM_LEVEL 0x011c -#define SM_EIM_TEST 0x0120 -#define SM_EIM_NMIC 0x0124 - -/* Bitfields in PM_CKSEL */ -#define SM_CPUSEL_OFFSET 0 -#define SM_CPUSEL_SIZE 3 -#define SM_CPUDIV_OFFSET 7 -#define SM_CPUDIV_SIZE 1 -#define SM_HSBSEL_OFFSET 8 -#define SM_HSBSEL_SIZE 3 -#define SM_HSBDIV_OFFSET 15 -#define SM_HSBDIV_SIZE 1 -#define SM_PBASEL_OFFSET 16 -#define SM_PBASEL_SIZE 3 -#define SM_PBADIV_OFFSET 23 -#define SM_PBADIV_SIZE 1 -#define SM_PBBSEL_OFFSET 24 -#define SM_PBBSEL_SIZE 3 -#define SM_PBBDIV_OFFSET 31 -#define SM_PBBDIV_SIZE 1 - -/* Bitfields in PM_PLL0 */ -#define SM_PLLEN_OFFSET 0 -#define SM_PLLEN_SIZE 1 -#define SM_PLLOSC_OFFSET 1 -#define SM_PLLOSC_SIZE 1 -#define SM_PLLOPT_OFFSET 2 -#define SM_PLLOPT_SIZE 3 -#define SM_PLLDIV_OFFSET 8 -#define SM_PLLDIV_SIZE 8 -#define SM_PLLMUL_OFFSET 16 -#define SM_PLLMUL_SIZE 8 -#define SM_PLLCOUNT_OFFSET 24 -#define SM_PLLCOUNT_SIZE 6 -#define SM_PLLTEST_OFFSET 31 -#define SM_PLLTEST_SIZE 1 - -/* Bitfields in PM_VCTRL */ -#define SM_VAUTO_OFFSET 0 -#define SM_VAUTO_SIZE 1 -#define SM_PM_VCTRL_VAL_OFFSET 8 -#define SM_PM_VCTRL_VAL_SIZE 7 - -/* Bitfields in PM_VMREF */ -#define SM_REFSEL_OFFSET 0 -#define SM_REFSEL_SIZE 4 - -/* Bitfields in PM_VMV */ -#define SM_PM_VMV_VAL_OFFSET 0 -#define SM_PM_VMV_VAL_SIZE 8 - -/* Bitfields in PM_ICR */ -#define SM_LOCK0_OFFSET 0 -#define SM_LOCK0_SIZE 1 -#define SM_LOCK1_OFFSET 1 -#define SM_LOCK1_SIZE 1 -#define SM_WAKE_OFFSET 2 -#define SM_WAKE_SIZE 1 -#define SM_VOK_OFFSET 3 -#define SM_VOK_SIZE 1 -#define SM_VMRDY_OFFSET 4 -#define SM_VMRDY_SIZE 1 -#define SM_CKRDY_OFFSET 5 -#define SM_CKRDY_SIZE 1 - -/* Bitfields in PM_GCCTRL */ -#define SM_OSCSEL_OFFSET 0 -#define SM_OSCSEL_SIZE 1 -#define SM_PLLSEL_OFFSET 1 -#define SM_PLLSEL_SIZE 1 -#define SM_CEN_OFFSET 2 -#define SM_CEN_SIZE 1 -#define SM_CPC_OFFSET 3 -#define SM_CPC_SIZE 1 -#define SM_DIVEN_OFFSET 4 -#define SM_DIVEN_SIZE 1 -#define SM_DIV_OFFSET 8 -#define SM_DIV_SIZE 8 - -/* Bitfields in RTC_CTRL */ -#define SM_PCLR_OFFSET 1 -#define SM_PCLR_SIZE 1 -#define SM_TOPEN_OFFSET 2 -#define SM_TOPEN_SIZE 1 -#define SM_CLKEN_OFFSET 3 -#define SM_CLKEN_SIZE 1 -#define SM_PSEL_OFFSET 8 -#define SM_PSEL_SIZE 16 - -/* Bitfields in RTC_VAL */ -#define SM_RTC_VAL_VAL_OFFSET 0 -#define SM_RTC_VAL_VAL_SIZE 31 - -/* Bitfields in RTC_TOP */ -#define SM_RTC_TOP_VAL_OFFSET 0 -#define SM_RTC_TOP_VAL_SIZE 32 - -/* Bitfields in RTC_ICR */ -#define SM_TOPI_OFFSET 0 -#define SM_TOPI_SIZE 1 - -/* Bitfields in WDT_CTRL */ -#define SM_KEY_OFFSET 24 -#define SM_KEY_SIZE 8 - -/* Bitfields in RC_RCAUSE */ -#define SM_POR_OFFSET 0 -#define SM_POR_SIZE 1 -#define SM_BOD_OFFSET 1 -#define SM_BOD_SIZE 1 -#define SM_EXT_OFFSET 2 -#define SM_EXT_SIZE 1 -#define SM_WDT_OFFSET 3 -#define SM_WDT_SIZE 1 -#define SM_NTAE_OFFSET 4 -#define SM_NTAE_SIZE 1 -#define SM_SERP_OFFSET 5 -#define SM_SERP_SIZE 1 - -/* Bitfields in EIM_EDGE */ -#define SM_INT0_OFFSET 0 -#define SM_INT0_SIZE 1 -#define SM_INT1_OFFSET 1 -#define SM_INT1_SIZE 1 -#define SM_INT2_OFFSET 2 -#define SM_INT2_SIZE 1 -#define SM_INT3_OFFSET 3 -#define SM_INT3_SIZE 1 - -/* Bitfields in EIM_LEVEL */ - -/* Bitfields in EIM_TEST */ -#define SM_TESTEN_OFFSET 31 -#define SM_TESTEN_SIZE 1 - -/* Bitfields in EIM_NMIC */ -#define SM_EN_OFFSET 0 -#define SM_EN_SIZE 1 - -/* Bit manipulation macros */ -#define SM_BIT(name) \ - (1 << SM_##name##_OFFSET) -#define SM_BF(name,value) \ - (((value) & ((1 << SM_##name##_SIZE) - 1)) \ - << SM_##name##_OFFSET) -#define SM_BFEXT(name,value) \ - (((value) >> SM_##name##_OFFSET) \ - & ((1 << SM_##name##_SIZE) - 1)) -#define SM_BFINS(name,value,old) \ - (((old) & ~(((1 << SM_##name##_SIZE) - 1) \ - << SM_##name##_OFFSET)) \ - | SM_BF(name,value)) - -/* Register access macros */ -#define sm_readl(reg) \ - readl((void *)SM_BASE + SM_##reg) -#define sm_writel(reg,value) \ - writel((value), (void *)SM_BASE + SM_##reg) - -#endif /* __CPU_AT32AP_SM_H__ */ diff --git a/include/asm-avr32/arch-at32ap700x/clk.h b/include/asm-avr32/arch-at32ap700x/clk.h index 309fda50e21..4a1dd33b56b 100644 --- a/include/asm-avr32/arch-at32ap700x/clk.h +++ b/include/asm-avr32/arch-at32ap700x/clk.h @@ -75,6 +75,8 @@ static inline unsigned long get_mci_clk_rate(void) } #endif +extern void clk_init(void); + /* Board code may need the SDRAM base clock as a compile-time constant */ #define SDRAMC_BUS_HZ (MAIN_CLK_RATE >> CFG_CLKDIV_HSB) -- cgit v1.3.1 From caf83ea888a0220f41747d0b7748fa43b4a4bd49 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 2 May 2008 15:32:57 +0200 Subject: avr32: Use the same entry point for reset and exception handling Since the reset vector is always aligned to a very large boundary, we can save a couple of KB worth of alignment padding by placing the exception vectors at the same address. Deciding which one it is is easy: If we're handling an exception, the CPU is in Exception mode. If we're starting up after reset, the CPU is in Supervisor mode. So this adds a very minimal overhead to the reset path (only executed once) and the exception handling path (normally never executed at all.) Signed-off-by: Haavard Skinnemoen --- board/atmel/atngw100/u-boot.lds | 1 + board/atmel/atstk1000/u-boot.lds | 1 + cpu/at32ap/Makefile | 1 - cpu/at32ap/entry.S | 64 ------------------- cpu/at32ap/start.S | 129 ++++++++++++++++++++++++++++++++++++--- 5 files changed, 122 insertions(+), 74 deletions(-) delete mode 100644 cpu/at32ap/entry.S (limited to 'cpu') diff --git a/board/atmel/atngw100/u-boot.lds b/board/atmel/atngw100/u-boot.lds index 3c878d8657a..e736adf0fcd 100644 --- a/board/atmel/atngw100/u-boot.lds +++ b/board/atmel/atngw100/u-boot.lds @@ -29,6 +29,7 @@ SECTIONS . = 0; _text = .; .text : { + *(.exception.text) *(.text) *(.text.*) } diff --git a/board/atmel/atstk1000/u-boot.lds b/board/atmel/atstk1000/u-boot.lds index f63bc4ff27a..0d3b19c6402 100644 --- a/board/atmel/atstk1000/u-boot.lds +++ b/board/atmel/atstk1000/u-boot.lds @@ -29,6 +29,7 @@ SECTIONS . = 0; _text = .; .text : { + *(.exception.text) *(.text) *(.text.*) } diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile index 8e384c7e07f..29f9c0d04ae 100644 --- a/cpu/at32ap/Makefile +++ b/cpu/at32ap/Makefile @@ -29,7 +29,6 @@ LIB := $(obj)lib$(CPU).a START-y += start.o -SOBJS-y += entry.o COBJS-y += cpu.o COBJS-y += hsdramc.o COBJS-y += exception.o diff --git a/cpu/at32ap/entry.S b/cpu/at32ap/entry.S deleted file mode 100644 index a6fc68867a8..00000000000 --- a/cpu/at32ap/entry.S +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2004-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 - */ -#include -#include - - .section .text.exception,"ax" - .global _evba - .type _evba,@function - .align 10 -_evba: - .irp x,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 - .align 2 - rjmp unknown_exception - .endr - - .global timer_interrupt_handler - .type timer_interrupt_handler,@function - .align 2 -timer_interrupt_handler: - /* - * Increment timer_overflow and re-write COMPARE with 0xffffffff. - * - * We're running at interrupt level 3, so we don't need to save - * r8-r12 or lr to the stack. - */ - lda.w r8, timer_overflow - ld.w r9, r8[0] - mov r10, -1 - mtsr SYSREG_COMPARE, r10 - sub r9, -1 - st.w r8[0], r9 - rete - - .type unknown_exception, @function -unknown_exception: - pushm r0-r12 - sub r8, sp, REG_R12 - REG_R0 - 4 - mov r9, lr - mfsr r10, SYSREG_RAR_EX - mfsr r11, SYSREG_RSR_EX - pushm r8-r11 - mfsr r12, SYSREG_ECR - mov r11, sp - rcall do_unknown_exception -1: rjmp 1b diff --git a/cpu/at32ap/start.S b/cpu/at32ap/start.S index ab8c2b73d89..907e9b1534d 100644 --- a/cpu/at32ap/start.S +++ b/cpu/at32ap/start.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2006 Atmel Corporation + * Copyright (C) 2005-2008 Atmel Corporation * * See file CREDITS for list of people who contributed to this * project. @@ -20,12 +20,9 @@ * MA 02111-1307 USA */ #include +#include #include -#ifndef PART_SPECIFIC_BOOTSTRAP -# define PART_SPECIFIC_BOOTSTRAP -#endif - #define SYSREG_MMUCR_I_OFFSET 2 #define SYSREG_MMUCR_S_OFFSET 4 @@ -34,11 +31,115 @@ | SYSREG_BIT(FE) | SYSREG_BIT(RE) \ | SYSREG_BIT(IBE) | SYSREG_BIT(IEE)) - .text + /* + * To save some space, we use the same entry point for + * exceptions and reset. This avoids lots of alignment padding + * since the reset vector is always suitably aligned. + */ + .section .exception.text, "ax", @progbits .global _start + .global _evba + .type _start, @function + .type _evba, @function _start: - PART_SPECIFIC_BOOTSTRAP + .size _start, 0 +_evba: + .org 0x00 + rjmp unknown_exception /* Unrecoverable exception */ + .org 0x04 + rjmp unknown_exception /* TLB multiple hit */ + .org 0x08 + rjmp unknown_exception /* Bus error data fetch */ + .org 0x0c + rjmp unknown_exception /* Bus error instruction fetch */ + .org 0x10 + rjmp unknown_exception /* NMI */ + .org 0x14 + rjmp unknown_exception /* Instruction address */ + .org 0x18 + rjmp unknown_exception /* ITLB protection */ + .org 0x1c + rjmp unknown_exception /* Breakpoint */ + .org 0x20 + rjmp unknown_exception /* Illegal opcode */ + .org 0x24 + rjmp unknown_exception /* Unimplemented instruction */ + .org 0x28 + rjmp unknown_exception /* Privilege violation */ + .org 0x2c + rjmp unknown_exception /* Floating-point */ + .org 0x30 + rjmp unknown_exception /* Coprocessor absent */ + .org 0x34 + rjmp unknown_exception /* Data Address (read) */ + .org 0x38 + rjmp unknown_exception /* Data Address (write) */ + .org 0x3c + rjmp unknown_exception /* DTLB Protection (read) */ + .org 0x40 + rjmp unknown_exception /* DTLB Protection (write) */ + .org 0x44 + rjmp unknown_exception /* DTLB Modified */ + + .org 0x50 + rjmp unknown_exception /* ITLB Miss */ + .org 0x60 + rjmp unknown_exception /* DTLB Miss (read) */ + .org 0x70 + rjmp unknown_exception /* DTLB Miss (write) */ + + .size _evba, . - _evba + + .align 2 + .type unknown_exception, @function +unknown_exception: + /* Figure out whether we're handling an exception (Exception + * mode) or just booting (Supervisor mode). */ + csrfcz SYSREG_M1_OFFSET + brcc at32ap_cpu_bootstrap + + /* This is an exception. Complain. */ + pushm r0-r12 + sub r8, sp, REG_R12 - REG_R0 - 4 + mov r9, lr + mfsr r10, SYSREG_RAR_EX + mfsr r11, SYSREG_RSR_EX + pushm r8-r11 + mfsr r12, SYSREG_ECR + mov r11, sp + rcall do_unknown_exception +1: rjmp 1b + + /* The COUNT/COMPARE timer interrupt handler */ + .global timer_interrupt_handler + .type timer_interrupt_handler,@function + .align 2 +timer_interrupt_handler: + /* + * Increment timer_overflow and re-write COMPARE with 0xffffffff. + * + * We're running at interrupt level 3, so we don't need to save + * r8-r12 or lr to the stack. + */ + lda.w r8, timer_overflow + ld.w r9, r8[0] + mov r10, -1 + mtsr SYSREG_COMPARE, r10 + sub r9, -1 + st.w r8[0], r9 + rete + /* + * CPU bootstrap after reset is handled here. SoC code may + * override this in case they need to initialize oscillators, + * etc. + */ + .section .text.at32ap_cpu_bootstrap, "ax", @progbits + .global at32ap_cpu_bootstrap + .weak at32ap_cpu_bootstrap + .type at32ap_cpu_bootstrap, @function + .align 2 +at32ap_cpu_bootstrap: /* Reset the Status Register */ mov r0, lo(SR_INIT) orh r0, hi(SR_INIT) @@ -66,9 +167,16 @@ _start: lddpc pc, 1f .align 2 -1: .long 2f +1: .long at32ap_low_level_init + .size _start, . - _start -2: lddpc sp, sp_init + /* Common CPU bootstrap code after oscillator/cache/etc. init */ + .section .text.avr32ap_low_level_init, "ax", @progbits + .global at32ap_low_level_init + .type at32ap_low_level_init, @function + .align 2 +at32ap_low_level_init: + lddpc sp, sp_init /* Initialize the GOT pointer */ lddpc r6, got_init @@ -90,6 +198,7 @@ got_init: * Relocate the u-boot image into RAM and continue from there. * Does not return. */ + .section .text.relocate_code,"ax",@progbits .global relocate_code .type relocate_code,@function relocate_code: @@ -162,3 +271,5 @@ in_ram: .align 2 got_init_reloc: .long 3b - _GLOBAL_OFFSET_TABLE_ + + .size relocate_code, . - relocate_code -- cgit v1.3.1 From 95107b7c028806919630bf02c653aa8f4f867c94 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 19 May 2008 11:27:37 +0200 Subject: avr32: Do stricter stack checking in the exception handler Don't do a stack dump if the stack pointer is outside the memory area reserved for stack. Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/exception.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'cpu') diff --git a/cpu/at32ap/exception.c b/cpu/at32ap/exception.c index 0672685cd02..dc9c3002a49 100644 --- a/cpu/at32ap/exception.c +++ b/cpu/at32ap/exception.c @@ -111,7 +111,8 @@ void do_unknown_exception(unsigned int ecr, struct pt_regs *regs) printf("CPU Mode: %s\n", cpu_modes[mode]); /* Avoid exception loops */ - if (regs->sp < CFG_SDRAM_BASE || regs->sp >= gd->stack_end) + if (regs->sp < (gd->stack_end - CONFIG_STACKSIZE) + || regs->sp >= gd->stack_end) printf("\nStack pointer seems bogus, won't do stack dump\n"); else dump_mem("\nStack: ", regs->sp, gd->stack_end); -- cgit v1.3.1 From a23e277c4a3a2bbc42d237aae29da3a8971e757f Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 19 May 2008 11:36:28 +0200 Subject: avr32: Rework SDRAM initialization code This cleans up the SDRAM initialization and related code a bit, and allows faster booting. * Add definitions for EBI and internal SRAM to asm/arch/memory-map.h * Remove memory test from sdram_init() and make caller responsible for verifying the SDRAM and determining its size. * Remove base_address member from struct sdram_config (was sdram_info) * Add data_bits member to struct sdram_config and kill CFG_SDRAM_16BIT * Add support for a common STK1000 hack: 16MB SDRAM instead of 8. Signed-off-by: Haavard Skinnemoen --- board/atmel/atngw100/atngw100.c | 21 ++++- board/atmel/atstk1000/atstk1000.c | 42 +++++++--- cpu/at32ap/hsdramc.c | 102 ++++++++++--------------- include/asm-avr32/arch-at32ap700x/memory-map.h | 20 +++++ include/asm-avr32/sdram.h | 27 +++++-- include/configs/atngw100.h | 21 ++--- include/configs/atstk1002.h | 13 ++-- include/configs/atstk1003.h | 13 ++-- include/configs/atstk1004.h | 14 ++-- include/configs/atstk1006.h | 13 ++-- 10 files changed, 166 insertions(+), 120 deletions(-) (limited to 'cpu') diff --git a/board/atmel/atngw100/atngw100.c b/board/atmel/atngw100/atngw100.c index 3ff6f0feb20..c649855d639 100644 --- a/board/atmel/atngw100/atngw100.c +++ b/board/atmel/atngw100/atngw100.c @@ -29,8 +29,8 @@ DECLARE_GLOBAL_DATA_PTR; -static const struct sdram_info sdram = { - .phys_addr = CFG_SDRAM_BASE, +static const struct sdram_config sdram_config = { + .data_bits = SDRAM_DATA_16BIT, .row_bits = 13, .col_bits = 9, .bank_bits = 2, @@ -66,7 +66,22 @@ int board_early_init_f(void) long int initdram(int board_type) { - return sdram_init(&sdram); + unsigned long expected_size; + unsigned long actual_size; + void *sdram_base; + + sdram_base = map_physmem(EBI_SDRAM_BASE, EBI_SDRAM_SIZE, MAP_NOCACHE); + + expected_size = sdram_init(sdram_base, &sdram_config); + actual_size = get_ram_size(sdram_base, expected_size); + + unmap_physmem(sdram_base, EBI_SDRAM_SIZE); + + if (expected_size != actual_size) + printf("Warning: Only %u of %u MiB SDRAM is working\n", + actual_size >> 20, expected_size >> 20); + + return actual_size; } void board_init_info(void) diff --git a/board/atmel/atstk1000/atstk1000.c b/board/atmel/atstk1000/atstk1000.c index 52fec65c19d..33bdba6f5df 100644 --- a/board/atmel/atstk1000/atstk1000.c +++ b/board/atmel/atstk1000/atstk1000.c @@ -29,10 +29,10 @@ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_ATSTK1006 -/* Dual MT48LC16M16A2-7E on daughterboard */ -static const struct sdram_info sdram = { - .phys_addr = CFG_SDRAM_BASE, +static const struct sdram_config sdram_config = { +#if defined(CONFIG_ATSTK1006) + /* Dual MT48LC16M16A2-7E (64 MB) on daughterboard */ + .data_bits = SDRAM_DATA_32BIT, .row_bits = 13, .col_bits = 9, .bank_bits = 2, @@ -45,12 +45,19 @@ static const struct sdram_info sdram = { .txsr = 7, /* 7.81 us */ .refresh_period = (781 * (SDRAMC_BUS_HZ / 1000)) / 100000, -}; #else -/* MT48LC2M32B2-5 on motherboard */ -static const struct sdram_info sdram = { - .phys_addr = CFG_SDRAM_BASE, + /* MT48LC2M32B2P-5 (8 MB) on motherboard */ +#ifdef CONFIG_ATSTK1004 + .data_bits = SDRAM_DATA_16BIT, +#else + .data_bits = SDRAM_DATA_32BIT, +#endif +#ifdef CONFIG_ATSTK1000_16MB_SDRAM + /* MT48LC4M32B2P-6 (16 MB) on mod'ed motherboard */ + .row_bits = 12, +#else .row_bits = 11, +#endif .col_bits = 8, .bank_bits = 2, .cas = 3, @@ -62,8 +69,8 @@ static const struct sdram_info sdram = { .txsr = 5, /* 15.6 us */ .refresh_period = (156 * (SDRAMC_BUS_HZ / 1000)) / 10000, -}; #endif +}; int board_early_init_f(void) { @@ -85,7 +92,22 @@ int board_early_init_f(void) long int initdram(int board_type) { - return sdram_init(&sdram); + unsigned long expected_size; + unsigned long actual_size; + void *sdram_base; + + sdram_base = map_physmem(EBI_SDRAM_BASE, EBI_SDRAM_SIZE, MAP_NOCACHE); + + expected_size = sdram_init(sdram_base, &sdram_config); + actual_size = get_ram_size(sdram_base, expected_size); + + unmap_physmem(sdram_base, EBI_SDRAM_SIZE); + + if (expected_size != actual_size) + printf("Warning: Only %u of %u MiB SDRAM is working\n", + actual_size >> 20, expected_size >> 20); + + return actual_size; } void board_init_info(void) diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c index 1fcfe75d745..992612b4627 100644 --- a/cpu/at32ap/hsdramc.c +++ b/cpu/at32ap/hsdramc.c @@ -30,39 +30,32 @@ #include "hsdramc1.h" -unsigned long sdram_init(const struct sdram_info *info) +unsigned long sdram_init(void *sdram_base, const struct sdram_config *config) { - unsigned long *sdram = (unsigned long *)uncached(info->phys_addr); unsigned long sdram_size; - unsigned long tmp; - unsigned long bus_hz; + uint32_t cfgreg; unsigned int i; - if (!info->refresh_period) - panic("ERROR: SDRAM refresh period == 0. " - "Please update the board code\n"); - - tmp = (HSDRAMC1_BF(NC, info->col_bits - 8) - | HSDRAMC1_BF(NR, info->row_bits - 11) - | HSDRAMC1_BF(NB, info->bank_bits - 1) - | HSDRAMC1_BF(CAS, info->cas) - | HSDRAMC1_BF(TWR, info->twr) - | HSDRAMC1_BF(TRC, info->trc) - | HSDRAMC1_BF(TRP, info->trp) - | HSDRAMC1_BF(TRCD, info->trcd) - | HSDRAMC1_BF(TRAS, info->tras) - | HSDRAMC1_BF(TXSR, info->txsr)); - -#ifdef CFG_SDRAM_16BIT - tmp |= HSDRAMC1_BIT(DBW); - sdram_size = 1 << (info->row_bits + info->col_bits - + info->bank_bits + 1); -#else - sdram_size = 1 << (info->row_bits + info->col_bits - + info->bank_bits + 2); -#endif - - hsdramc1_writel(CR, tmp); + cfgreg = (HSDRAMC1_BF(NC, config->col_bits - 8) + | HSDRAMC1_BF(NR, config->row_bits - 11) + | HSDRAMC1_BF(NB, config->bank_bits - 1) + | HSDRAMC1_BF(CAS, config->cas) + | HSDRAMC1_BF(TWR, config->twr) + | HSDRAMC1_BF(TRC, config->trc) + | HSDRAMC1_BF(TRP, config->trp) + | HSDRAMC1_BF(TRCD, config->trcd) + | HSDRAMC1_BF(TRAS, config->tras) + | HSDRAMC1_BF(TXSR, config->txsr)); + + if (config->data_bits == SDRAM_DATA_16BIT) + cfgreg |= HSDRAMC1_BIT(DBW); + + hsdramc1_writel(CR, cfgreg); + + /* Send a NOP to turn on the clock (necessary on some chips) */ + hsdramc1_writel(MR, HSDRAMC1_MODE_NOP); + hsdramc1_readl(MR); + writel(0, sdram_base); /* * Initialization sequence for SDRAM, from the data sheet: @@ -77,7 +70,7 @@ unsigned long sdram_init(const struct sdram_info *info) */ hsdramc1_writel(MR, HSDRAMC1_MODE_BANKS_PRECHARGE); hsdramc1_readl(MR); - writel(0, sdram); + writel(0, sdram_base); /* * 3. Eight auto-refresh (CBR) cycles are provided @@ -85,58 +78,41 @@ unsigned long sdram_init(const struct sdram_info *info) hsdramc1_writel(MR, HSDRAMC1_MODE_AUTO_REFRESH); hsdramc1_readl(MR); for (i = 0; i < 8; i++) - writel(0, sdram); + writel(0, sdram_base); /* * 4. A mode register set (MRS) cycle is issued to program * SDRAM parameters, in particular CAS latency and burst * length. * - * CAS from info struct, burst length 1, serial burst type + * The address will be chosen by the SDRAMC automatically; we + * just have to make sure BA[1:0] are set to 0. */ hsdramc1_writel(MR, HSDRAMC1_MODE_LOAD_MODE); hsdramc1_readl(MR); - writel(0, sdram + (info->cas << 4)); + writel(0, sdram_base); /* - * 5. A Normal Mode command is provided, 3 clocks after tMRD - * is met. - * - * From the timing diagram, it looks like tMRD is 3 - * cycles...try a dummy read from the peripheral bus. + * 5. The application must go into Normal Mode, setting Mode + * to 0 in the Mode Register and performing a write access + * at any location in the SDRAM. */ - hsdramc1_readl(MR); hsdramc1_writel(MR, HSDRAMC1_MODE_NORMAL); hsdramc1_readl(MR); - writel(0, sdram); + writel(0, sdram_base); /* * 6. Write refresh rate into SDRAMC refresh timer count * register (refresh rate = timing between refresh cycles). - * - * 15.6 us is a typical value for a burst of length one */ - bus_hz = get_sdram_clk_rate(); - hsdramc1_writel(TR, info->refresh_period); - - printf("SDRAM: %u MB at address 0x%08lx\n", - sdram_size >> 20, info->phys_addr); - - printf("Testing SDRAM..."); - for (i = 0; i < sdram_size / 4; i++) - sdram[i] = i; - - for (i = 0; i < sdram_size / 4; i++) { - tmp = sdram[i]; - if (tmp != i) { - printf("FAILED at address 0x%08lx\n", - info->phys_addr + i * 4); - printf("SDRAM: read 0x%lx, expected 0x%lx\n", tmp, i); - return 0; - } - } - - puts("OK\n"); + hsdramc1_writel(TR, config->refresh_period); + + if (config->data_bits == SDRAM_DATA_16BIT) + sdram_size = 1 << (config->row_bits + config->col_bits + + config->bank_bits + 1); + else + sdram_size = 1 << (config->row_bits + config->col_bits + + config->bank_bits + 2); return sdram_size; } diff --git a/include/asm-avr32/arch-at32ap700x/memory-map.h b/include/asm-avr32/arch-at32ap700x/memory-map.h index 5513e88e7b0..6592c039fae 100644 --- a/include/asm-avr32/arch-at32ap700x/memory-map.h +++ b/include/asm-avr32/arch-at32ap700x/memory-map.h @@ -22,6 +22,26 @@ #ifndef __AT32AP7000_MEMORY_MAP_H__ #define __AT32AP7000_MEMORY_MAP_H__ +/* Internal and external memories */ +#define EBI_SRAM_CS0_BASE 0x00000000 +#define EBI_SRAM_CS0_SIZE 0x04000000 +#define EBI_SRAM_CS4_BASE 0x04000000 +#define EBI_SRAM_CS4_SIZE 0x04000000 +#define EBI_SRAM_CS2_BASE 0x08000000 +#define EBI_SRAM_CS2_SIZE 0x04000000 +#define EBI_SRAM_CS3_BASE 0x0c000000 +#define EBI_SRAM_CS3_SIZE 0x04000000 +#define EBI_SRAM_CS1_BASE 0x10000000 +#define EBI_SRAM_CS1_SIZE 0x10000000 +#define EBI_SRAM_CS5_BASE 0x20000000 +#define EBI_SRAM_CS5_SIZE 0x04000000 + +#define EBI_SDRAM_BASE EBI_SRAM_CS1_BASE +#define EBI_SDRAM_SIZE EBI_SRAM_CS1_SIZE + +#define INTERNAL_SRAM_BASE 0x24000000 +#define INTERNAL_SRAM_SIZE 0x00008000 + /* Devices on the High Speed Bus (HSB) */ #define LCDC_BASE 0xFF000000 #define DMAC_BASE 0xFF200000 diff --git a/include/asm-avr32/sdram.h b/include/asm-avr32/sdram.h index 833af6e6ad1..7bdefc1fd24 100644 --- a/include/asm-avr32/sdram.h +++ b/include/asm-avr32/sdram.h @@ -22,15 +22,32 @@ #ifndef __ASM_AVR32_SDRAM_H #define __ASM_AVR32_SDRAM_H -struct sdram_info { - unsigned long phys_addr; - unsigned int row_bits, col_bits, bank_bits; - unsigned int cas, twr, trc, trp, trcd, tras, txsr; +struct sdram_config { + /* Number of data bits. */ + enum { + SDRAM_DATA_16BIT, + SDRAM_DATA_32BIT, + } data_bits; + + /* Number of address bits */ + uint8_t row_bits, col_bits, bank_bits; + + /* SDRAM timings in cycles */ + uint8_t cas, twr, trc, trp, trcd, tras, txsr; /* SDRAM refresh period in cycles */ unsigned long refresh_period; }; -extern unsigned long sdram_init(const struct sdram_info *info); +/* + * Attempt to initialize the SDRAM controller using the specified + * parameters. Return the expected size of the memory area based on + * the number of address and data bits. + * + * The caller should verify that the configuration is correct by + * running a memory test, e.g. get_ram_size(). + */ +extern unsigned long sdram_init(void *sdram_base, + const struct sdram_config *config); #endif /* __ASM_AVR32_SDRAM_H */ diff --git a/include/configs/atngw100.h b/include/configs/atngw100.h index 313298a5c7f..3fc99756371 100644 --- a/include/configs/atngw100.h +++ b/include/configs/atngw100.h @@ -24,6 +24,8 @@ #ifndef __CONFIG_H #define __CONFIG_H +#include + #define CONFIG_AVR32 1 #define CONFIG_AT32AP 1 #define CONFIG_AT32AP7000 1 @@ -140,11 +142,9 @@ #define CFG_MONITOR_BASE CFG_FLASH_BASE -#define CFG_INTRAM_BASE 0x24000000 -#define CFG_INTRAM_SIZE 0x8000 - -#define CFG_SDRAM_BASE 0x10000000 -#define CFG_SDRAM_16BIT 1 +#define CFG_INTRAM_BASE INTERNAL_SRAM_BASE +#define CFG_INTRAM_SIZE INTERNAL_SRAM_SIZE +#define CFG_SDRAM_BASE EBI_SDRAM_BASE #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 65536 @@ -153,17 +153,10 @@ #define CFG_INIT_SP_ADDR (CFG_INTRAM_BASE + CFG_INTRAM_SIZE) #define CFG_MALLOC_LEN (256*1024) -#define CFG_MALLOC_END \ - ({ \ - DECLARE_GLOBAL_DATA_PTR; \ - CFG_SDRAM_BASE + gd->sdram_size; \ - }) -#define CFG_MALLOC_START (CFG_MALLOC_END - CFG_MALLOC_LEN) - #define CFG_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ -#define CFG_LOAD_ADDR (CFG_SDRAM_BASE + 0x00400000) +#define CFG_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) #define CFG_BOOTPARAMS_LEN (16 * 1024) /* Other configuration settings that shouldn't have to change all that often */ @@ -173,7 +166,7 @@ #define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) #define CFG_LONGHELP 1 -#define CFG_MEMTEST_START CFG_SDRAM_BASE +#define CFG_MEMTEST_START EBI_SDRAM_BASE #define CFG_MEMTEST_END (CFG_MEMTEST_START + 0x1f00000) #define CFG_BAUDRATE_TABLE { 115200, 38400, 19200, 9600, 2400 } diff --git a/include/configs/atstk1002.h b/include/configs/atstk1002.h index f652b287106..ba18eb63c7f 100644 --- a/include/configs/atstk1002.h +++ b/include/configs/atstk1002.h @@ -24,6 +24,8 @@ #ifndef __CONFIG_H #define __CONFIG_H +#include + #define CONFIG_AVR32 1 #define CONFIG_AT32AP 1 #define CONFIG_AT32AP7000 1 @@ -170,10 +172,9 @@ #define CFG_MONITOR_BASE CFG_FLASH_BASE -#define CFG_INTRAM_BASE 0x24000000 -#define CFG_INTRAM_SIZE 0x8000 - -#define CFG_SDRAM_BASE 0x10000000 +#define CFG_INTRAM_BASE INTERNAL_SRAM_BASE +#define CFG_INTRAM_SIZE INTERNAL_SRAM_SIZE +#define CFG_SDRAM_BASE EBI_SDRAM_BASE #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 65536 @@ -185,7 +186,7 @@ #define CFG_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ -#define CFG_LOAD_ADDR (CFG_SDRAM_BASE + 0x00400000) +#define CFG_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) #define CFG_BOOTPARAMS_LEN (16 * 1024) /* Other configuration settings that shouldn't have to change all that often */ @@ -195,7 +196,7 @@ #define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) #define CFG_LONGHELP 1 -#define CFG_MEMTEST_START CFG_SDRAM_BASE +#define CFG_MEMTEST_START EBI_SDRAM_BASE #define CFG_MEMTEST_END (CFG_MEMTEST_START + 0x700000) #define CFG_BAUDRATE_TABLE { 115200, 38400, 19200, 9600, 2400 } diff --git a/include/configs/atstk1003.h b/include/configs/atstk1003.h index 2d981ccbad8..a528ddfb0e9 100644 --- a/include/configs/atstk1003.h +++ b/include/configs/atstk1003.h @@ -24,6 +24,8 @@ #ifndef __CONFIG_H #define __CONFIG_H +#include + #define CONFIG_AVR32 1 #define CONFIG_AT32AP 1 #define CONFIG_AT32AP7001 1 @@ -153,10 +155,9 @@ #define CFG_MONITOR_BASE CFG_FLASH_BASE -#define CFG_INTRAM_BASE 0x24000000 -#define CFG_INTRAM_SIZE 0x8000 - -#define CFG_SDRAM_BASE 0x10000000 +#define CFG_INTRAM_BASE INTERNAL_SRAM_BASE +#define CFG_INTRAM_SIZE INTERNAL_SRAM_SIZE +#define CFG_SDRAM_BASE EBI_SDRAM_BASE #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 65536 @@ -167,7 +168,7 @@ #define CFG_MALLOC_LEN (256*1024) /* Allow 4MB for the kernel run-time image */ -#define CFG_LOAD_ADDR (CFG_SDRAM_BASE + 0x00400000) +#define CFG_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) #define CFG_BOOTPARAMS_LEN (16 * 1024) /* Other configuration settings that shouldn't have to change all that often */ @@ -177,7 +178,7 @@ #define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) #define CFG_LONGHELP 1 -#define CFG_MEMTEST_START CFG_SDRAM_BASE +#define CFG_MEMTEST_START EBI_SDRAM_BASE #define CFG_MEMTEST_END (CFG_MEMTEST_START + 0x700000) #define CFG_BAUDRATE_TABLE { 115200, 38400, 19200, 9600, 2400 } diff --git a/include/configs/atstk1004.h b/include/configs/atstk1004.h index 235c1cc9df8..fc9585e84d2 100644 --- a/include/configs/atstk1004.h +++ b/include/configs/atstk1004.h @@ -24,6 +24,8 @@ #ifndef __CONFIG_H #define __CONFIG_H +#include + #define CONFIG_AVR32 1 #define CONFIG_AT32AP 1 #define CONFIG_AT32AP7002 1 @@ -153,11 +155,9 @@ #define CFG_MONITOR_BASE CFG_FLASH_BASE -#define CFG_INTRAM_BASE 0x24000000 -#define CFG_INTRAM_SIZE 0x8000 - -#define CFG_SDRAM_BASE 0x10000000 -#define CFG_SDRAM_16BIT 1 +#define CFG_INTRAM_BASE INTERNAL_SRAM_BASE +#define CFG_INTRAM_SIZE INTERNAL_SRAM_SIZE +#define CFG_SDRAM_BASE EBI_SDRAM_BASE #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 65536 @@ -168,7 +168,7 @@ #define CFG_MALLOC_LEN (256*1024) /* Allow 2MB for the kernel run-time image */ -#define CFG_LOAD_ADDR (CFG_SDRAM_BASE + 0x00200000) +#define CFG_LOAD_ADDR (EBI_SDRAM_BASE + 0x00200000) #define CFG_BOOTPARAMS_LEN (16 * 1024) /* Other configuration settings that shouldn't have to change all that often */ @@ -178,7 +178,7 @@ #define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) #define CFG_LONGHELP 1 -#define CFG_MEMTEST_START CFG_SDRAM_BASE +#define CFG_MEMTEST_START EBI_SDRAM_BASE #define CFG_MEMTEST_END (CFG_MEMTEST_START + 0x700000) #define CFG_BAUDRATE_TABLE { 115200, 38400, 19200, 9600, 2400 } diff --git a/include/configs/atstk1006.h b/include/configs/atstk1006.h index c606d5dcc20..9fd49a53a34 100644 --- a/include/configs/atstk1006.h +++ b/include/configs/atstk1006.h @@ -24,6 +24,8 @@ #ifndef __CONFIG_H #define __CONFIG_H +#include + #define CONFIG_AVR32 1 #define CONFIG_AT32AP 1 #define CONFIG_AT32AP7000 1 @@ -170,10 +172,9 @@ #define CFG_MONITOR_BASE CFG_FLASH_BASE -#define CFG_INTRAM_BASE 0x24000000 -#define CFG_INTRAM_SIZE 0x8000 - -#define CFG_SDRAM_BASE 0x10000000 +#define CFG_INTRAM_BASE INTERNAL_SRAM_BASE +#define CFG_INTRAM_SIZE INTERNAL_SRAM_SIZE +#define CFG_SDRAM_BASE EBI_SDRAM_BASE #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 65536 @@ -185,7 +186,7 @@ #define CFG_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ -#define CFG_LOAD_ADDR (CFG_SDRAM_BASE + 0x00400000) +#define CFG_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) #define CFG_BOOTPARAMS_LEN (16 * 1024) /* Other configuration settings that shouldn't have to change all that often */ @@ -195,7 +196,7 @@ #define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) #define CFG_LONGHELP 1 -#define CFG_MEMTEST_START CFG_SDRAM_BASE +#define CFG_MEMTEST_START EBI_SDRAM_BASE #define CFG_MEMTEST_END (CFG_MEMTEST_START + 0x3f00000) #define CFG_BAUDRATE_TABLE { 115200, 38400, 19200, 9600, 2400 } -- cgit v1.3.1 From 7a96ddadd13e6ac9a829affce9b6f8823f580e49 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 21 May 2008 11:10:59 +0200 Subject: avr32: Fix two warnings in atmel_mci.c The warnings are harmless but annoying. Let's fix them. Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/atmel_mci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'cpu') diff --git a/cpu/at32ap/atmel_mci.c b/cpu/at32ap/atmel_mci.c index f59dfb5995e..3ce9ea53231 100644 --- a/cpu/at32ap/atmel_mci.c +++ b/cpu/at32ap/atmel_mci.c @@ -182,12 +182,13 @@ static int mmc_acmd(unsigned long cmd, unsigned long arg, static unsigned long mmc_bread(int dev, unsigned long start, lbaint_t blkcnt, - unsigned long *buffer) + void *buffer) { int ret, i = 0; unsigned long resp[4]; unsigned long card_status, data; unsigned long wordcount; + u32 *p = buffer; u32 status; if (blkcnt == 0) @@ -225,7 +226,7 @@ mmc_bread(int dev, unsigned long start, lbaint_t blkcnt, if (status & MMCI_BIT(RXRDY)) { data = mmci_readl(RDR); /* pr_debug("%x\n", data); */ - *buffer++ = data; + *p++ = data; wordcount++; } } while(wordcount < (mmc_blkdev.blksz / 4)); @@ -443,6 +444,7 @@ static void mci_set_data_timeout(struct mmc_csd *csd) dtocyc = timeout_clks; dtomul = 0; + shift = 0; while (dtocyc > 15 && dtomul < 8) { dtomul++; shift = dtomul_to_shift[dtomul]; -- cgit v1.3.1 From e92a5bf8330654e33ac13f6b3058634e58f5d1c0 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Thu, 22 May 2008 12:28:25 +0200 Subject: avr32: Fix wrong error flags in atmel_mci driver Make sure we check for CRC errors when sending commands that use CRC checking. Reported-by: Gururaja Hebbar K R Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/atmel_mci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cpu') diff --git a/cpu/at32ap/atmel_mci.c b/cpu/at32ap/atmel_mci.c index 3ce9ea53231..226b5c045ff 100644 --- a/cpu/at32ap/atmel_mci.c +++ b/cpu/at32ap/atmel_mci.c @@ -139,7 +139,7 @@ mmc_cmd(unsigned long cmd, unsigned long arg, pr_debug("mmc: status 0x%08lx\n", status); - if (status & ERROR_FLAGS) { + if (status & error_flags) { printf("mmc: command %lu failed (status: 0x%08lx)\n", cmd, status); return -EIO; -- cgit v1.3.1 From 48ea623eae8674793372e3e7c95e72e5a44d7a95 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 21 May 2008 13:01:09 +0200 Subject: avr32: Compile atmel_mci.o conditionally Remove #ifdef CONFIG_MMC from the source file and use conditional compilation in the Makefile instead. Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/Makefile | 2 +- cpu/at32ap/atmel_mci.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'cpu') diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile index 29f9c0d04ae..d16c58b7738 100644 --- a/cpu/at32ap/Makefile +++ b/cpu/at32ap/Makefile @@ -35,7 +35,7 @@ COBJS-y += exception.o COBJS-y += cache.o COBJS-y += interrupts.o COBJS-y += pio.o -COBJS-y += atmel_mci.o +COBJS-$(CONFIG_MMC) += atmel_mci.o SRCS := $(START-y:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/cpu/at32ap/atmel_mci.c b/cpu/at32ap/atmel_mci.c index 226b5c045ff..3795addf05a 100644 --- a/cpu/at32ap/atmel_mci.c +++ b/cpu/at32ap/atmel_mci.c @@ -21,8 +21,6 @@ */ #include -#ifdef CONFIG_MMC - #include #include @@ -548,5 +546,3 @@ int mmc2info(ulong addr) { return 0; } - -#endif /* CONFIG_MMC */ -- cgit v1.3.1 From a8092c021d27f27f4b323b7d49979ca01b3fc19d Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 26 May 2008 12:19:10 +0200 Subject: avr32: Fix theoretical race in udelay() If the specified delay is very short, the cycle counter may go past the "end" time we are waiting for before we get around to reading it. Fix it by checking the different between the cycle count "now" and the cycle count at the beginning. This will work as long as the delay measured in number of cycles is below 2^31. Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/interrupts.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'cpu') diff --git a/cpu/at32ap/interrupts.c b/cpu/at32ap/interrupts.c index bef1f30d79d..160838eeeb3 100644 --- a/cpu/at32ap/interrupts.c +++ b/cpu/at32ap/interrupts.c @@ -98,18 +98,16 @@ void set_timer(unsigned long t) */ void udelay(unsigned long usec) { - unsigned long now, end; + unsigned long cycles; + unsigned long base; + unsigned long now; - now = sysreg_read(COUNT); + base = sysreg_read(COUNT); + cycles = ((usec * (get_tbclk() / 10000)) + 50) / 100; - end = ((usec * (get_tbclk() / 10000)) + 50) / 100; - end += now; - - while (now > end) - now = sysreg_read(COUNT); - - while (now < end) + do { now = sysreg_read(COUNT); + } while ((now - base) < cycles); } static int set_interrupt_handler(unsigned int nr, void (*handler)(void), -- cgit v1.3.1 From e2ad8426624bac457acc6925b6ff408e9bf20466 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Fri, 30 May 2008 00:53:38 +0900 Subject: [MIPS] : Update coprocessor register access macros Signed-off-by: Shinya Kuribayashi --- board/dbau1x00/dbau1x00.c | 2 +- board/gth2/gth2.c | 2 +- board/pb1x00/pb1x00.c | 2 +- board/qemu-mips/qemu-mips.c | 6 +- cpu/mips/cpu.c | 10 +- include/asm-mips/mipsregs.h | 950 ++++++++++++++++++++++++++++++++++++++------ 6 files changed, 836 insertions(+), 136 deletions(-) (limited to 'cpu') diff --git a/board/dbau1x00/dbau1x00.c b/board/dbau1x00/dbau1x00.c index a13eeeb1232..1be72a2dd3e 100644 --- a/board/dbau1x00/dbau1x00.c +++ b/board/dbau1x00/dbau1x00.c @@ -52,7 +52,7 @@ int checkboard (void) *sys_counter = 0x100; /* Enable 32 kHz oscillator for RTC/TOY */ - proc_id = read_32bit_cp0_register(CP0_PRID); + proc_id = read_c0_prid(); switch (proc_id >> 24) { case 0: diff --git a/board/gth2/gth2.c b/board/gth2/gth2.c index 6da80dc758d..9bc4d3fe5e8 100644 --- a/board/gth2/gth2.c +++ b/board/gth2/gth2.c @@ -135,7 +135,7 @@ int checkboard (void) *sys_counter = 0x100; /* Enable 32 kHz oscillator for RTC/TOY */ - proc_id = read_32bit_cp0_register(CP0_PRID); + proc_id = read_c0_prid(); switch (proc_id >> 24) { case 0: diff --git a/board/pb1x00/pb1x00.c b/board/pb1x00/pb1x00.c index 536c9544f53..82b7235209d 100644 --- a/board/pb1x00/pb1x00.c +++ b/board/pb1x00/pb1x00.c @@ -51,7 +51,7 @@ int checkboard (void) *sys_counter = 0x100; /* Enable 32 kHz oscillator for RTC/TOY */ - proc_id = read_32bit_cp0_register(CP0_PRID); + proc_id = read_c0_prid(); switch (proc_id >> 24) { case 0: diff --git a/board/qemu-mips/qemu-mips.c b/board/qemu-mips/qemu-mips.c index 68690743d68..6e6eab27779 100644 --- a/board/qemu-mips/qemu-mips.c +++ b/board/qemu-mips/qemu-mips.c @@ -38,7 +38,7 @@ int checkboard(void) u32 proc_id; u32 config1; - proc_id = read_32bit_cp0_register(CP0_PRID); + proc_id = read_c0_prid(); printf("Board: Qemu -M mips CPU: "); switch (proc_id) { case 0x00018000: @@ -51,7 +51,7 @@ int checkboard(void) printf("4KEc"); break; case 0x00019300: - config1 = read_mips32_cp0_config1(); + config1 = read_c0_config1(); if (config1 & 1) printf("24Kf"); else @@ -64,7 +64,7 @@ int checkboard(void) printf("R4000"); break; case 0x00018100: - config1 = read_mips32_cp0_config1(); + config1 = read_c0_config1(); if (config1 & 1) printf("5Kf"); else diff --git a/cpu/mips/cpu.c b/cpu/mips/cpu.c index e267bba4691..0f58d25b892 100644 --- a/cpu/mips/cpu.c +++ b/cpu/mips/cpu.c @@ -66,10 +66,10 @@ void flush_cache(ulong start_addr, ulong size) void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) { - write_32bit_cp0_register(CP0_ENTRYLO0, low0); - write_32bit_cp0_register(CP0_PAGEMASK, pagemask); - write_32bit_cp0_register(CP0_ENTRYLO1, low1); - write_32bit_cp0_register(CP0_ENTRYHI, hi); - write_32bit_cp0_register(CP0_INDEX, index); + write_c0_entrylo0(low0); + write_c0_pagemask(pagemask); + write_c0_entrylo1(low1); + write_c0_entryhi(hi); + write_c0_index(index); tlb_write_indexed(); } diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index f05f3ada72f..be7e5c65ec1 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -207,81 +207,6 @@ #define PL_64M 26 #define PL_256M 28 -/* - * Macros to access the system control coprocessor - */ -#define read_32bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) - -#define read_32bit_cp0_set1_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "cfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) - -/* - * For now use this only with interrupts disabled! - */ -#define read_64bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmfc0\t%0,"STR(source)"\n\t" \ - ".set\tmips0" \ - : "=r" (__res)); \ - __res;}) - -#define write_32bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - "mtc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); - -#define write_32bit_cp0_set1_register(register,value) \ - __asm__ __volatile__( \ - "ctc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); - -#define write_64bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmtc0\t%0,"STR(register)"\n\t" \ - ".set\tmips0" \ - : : "r" (value)) - -/* - * This should be changed when we get a compiler that support the MIPS32 ISA. - */ -#define read_mips32_cp0_config1() \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - ".word\t0x40018001\n\t" \ - "move\t%0,$1\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - :"=r" (__res)); \ - __res;}) - -#define tlb_write_indexed() \ - __asm__ __volatile__( \ - ".set noreorder\n\t" \ - "tlbwi\n\t" \ -".set reorder") - /* * R4x00 interrupt enable / cause bits */ @@ -306,56 +231,6 @@ #define C_IRQ4 (_ULCAST_(1) << 14) #define C_IRQ5 (_ULCAST_(1) << 15) -#ifndef _LANGUAGE_ASSEMBLY -/* - * Manipulate the status register. - * Mostly used to access the interrupt bits. - */ -#define __BUILD_SET_CP0(name,register) \ -extern __inline__ unsigned int \ -set_cp0_##name(unsigned int set) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res |= set; \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} \ - \ -extern __inline__ unsigned int \ -clear_cp0_##name(unsigned int clear) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res &= ~clear; \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} \ - \ -extern __inline__ unsigned int \ -change_cp0_##name(unsigned int change, unsigned int new) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res &= ~change; \ - res |= (new & change); \ - if(change) \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} - -__BUILD_SET_CP0(status,CP0_STATUS) -__BUILD_SET_CP0(cause,CP0_CAUSE) -__BUILD_SET_CP0(config,CP0_CONFIG) - -#endif /* defined (_LANGUAGE_ASSEMBLY) */ - /* * Bitfields in the R4xx0 cp0 status register */ @@ -661,4 +536,829 @@ __BUILD_SET_CP0(config,CP0_CONFIG) #define MIPS_FPIR_L (_ULCAST_(1) << 21) #define MIPS_FPIR_F64 (_ULCAST_(1) << 22) +#ifndef __ASSEMBLY__ + +/* + * Functions to access the R10000 performance counters. These are basically + * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit + * performance counter number encoded into bits 1 ... 5 of the instruction. + * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware + * disassembler these will look like an access to sel 0 or 1. + */ +#define read_r10k_perf_cntr(counter) \ +({ \ + unsigned int __res; \ + __asm__ __volatile__( \ + "mfpc\t%0, %1" \ + : "=r" (__res) \ + : "i" (counter)); \ + \ + __res; \ +}) + +#define write_r10k_perf_cntr(counter,val) \ +do { \ + __asm__ __volatile__( \ + "mtpc\t%0, %1" \ + : \ + : "r" (val), "i" (counter)); \ +} while (0) + +#define read_r10k_perf_event(counter) \ +({ \ + unsigned int __res; \ + __asm__ __volatile__( \ + "mfps\t%0, %1" \ + : "=r" (__res) \ + : "i" (counter)); \ + \ + __res; \ +}) + +#define write_r10k_perf_cntl(counter,val) \ +do { \ + __asm__ __volatile__( \ + "mtps\t%0, %1" \ + : \ + : "r" (val), "i" (counter)); \ +} while (0) + +/* + * Macros to access the system control coprocessor + */ + +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __read_64bit_c0_register(source, sel) \ +({ unsigned long long __res; \ + if (sizeof(unsigned long) == 4) \ + __res = __read_64bit_c0_split(source, sel); \ + else if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmfc0\t%0, " #source "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define __write_64bit_c0_register(register, sel, value) \ +do { \ + if (sizeof(unsigned long) == 4) \ + __write_64bit_c0_split(register, sel, value); \ + else if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmtc0\t%z0, " #register "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ +} while (0) + +#define __read_ulong_c0_register(reg, sel) \ + ((sizeof(unsigned long) == 4) ? \ + (unsigned long) __read_32bit_c0_register(reg, sel) : \ + (unsigned long) __read_64bit_c0_register(reg, sel)) + +#define __write_ulong_c0_register(reg, sel, val) \ +do { \ + if (sizeof(unsigned long) == 4) \ + __write_32bit_c0_register(reg, sel, val); \ + else \ + __write_64bit_c0_register(reg, sel, val); \ +} while (0) + +/* + * On RM7000/RM9000 these are uses to access cop0 set 1 registers + */ +#define __read_32bit_c0_ctrl_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + "cfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_ctrl_register(register, value) \ +do { \ + __asm__ __volatile__( \ + "ctc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +/* + * These versions are only needed for systems with more than 38 bits of + * physical address space running the 32-bit kernel. That's none atm :-) + */ +#define __read_64bit_c0_split(source, sel) \ +({ \ + unsigned long long __val; \ + unsigned long __flags; \ + \ + local_irq_save(__flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsrl\t%M0, %M0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (__val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source ", " #sel "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsrl\t%M0, %M0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (__val)); \ + local_irq_restore(__flags); \ + \ + __val; \ +}) + +#define __write_64bit_c0_split(source, sel, val) \ +do { \ + unsigned long __flags; \ + \ + local_irq_save(__flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + local_irq_restore(__flags); \ +} while (0) + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_userlocal() __read_ulong_c0_register($4, 2) +#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ +#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_badvaddr() __read_ulong_c0_register($8, 0) +#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */ +#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val) + +#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */ +#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */ +#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val) + +#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */ +#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) +#ifdef CONFIG_MIPS_MT_SMTC +#define write_c0_status(val) \ +do { \ + __write_32bit_c0_register($12, 0, val); \ + __ehb(); \ +} while (0) +#else +/* + * Legacy non-SMTC code, which may be hazardous + * but which might not support EHB + */ +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) +#endif /* CONFIG_MIPS_MT_SMTC */ + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_epc() __read_ulong_c0_register($14, 0) +#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define read_c0_config3() __read_32bit_c0_register($16, 3) +#define read_c0_config4() __read_32bit_c0_register($16, 4) +#define read_c0_config5() __read_32bit_c0_register($16, 5) +#define read_c0_config6() __read_32bit_c0_register($16, 6) +#define read_c0_config7() __read_32bit_c0_register($16, 7) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) +#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) +#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val) +#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val) +#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val) +#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val) + +/* + * The WatchLo register. There may be upto 8 of them. + */ +#define read_c0_watchlo0() __read_ulong_c0_register($18, 0) +#define read_c0_watchlo1() __read_ulong_c0_register($18, 1) +#define read_c0_watchlo2() __read_ulong_c0_register($18, 2) +#define read_c0_watchlo3() __read_ulong_c0_register($18, 3) +#define read_c0_watchlo4() __read_ulong_c0_register($18, 4) +#define read_c0_watchlo5() __read_ulong_c0_register($18, 5) +#define read_c0_watchlo6() __read_ulong_c0_register($18, 6) +#define read_c0_watchlo7() __read_ulong_c0_register($18, 7) +#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val) +#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val) +#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val) +#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val) +#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val) +#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val) +#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val) +#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) + +/* + * The WatchHi register. There may be upto 8 of them. + */ +#define read_c0_watchhi0() __read_32bit_c0_register($19, 0) +#define read_c0_watchhi1() __read_32bit_c0_register($19, 1) +#define read_c0_watchhi2() __read_32bit_c0_register($19, 2) +#define read_c0_watchhi3() __read_32bit_c0_register($19, 3) +#define read_c0_watchhi4() __read_32bit_c0_register($19, 4) +#define read_c0_watchhi5() __read_32bit_c0_register($19, 5) +#define read_c0_watchhi6() __read_32bit_c0_register($19, 6) +#define read_c0_watchhi7() __read_32bit_c0_register($19, 7) + +#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val) +#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val) +#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val) +#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val) +#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val) +#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val) +#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val) +#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_ctrl_register($20) +#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +/* RM9000 PerfControl performance counter control register */ +#define read_c0_perfcontrol() __read_32bit_c0_register($22, 0) +#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val) + +#define read_c0_diag() __read_32bit_c0_register($22, 0) +#define write_c0_diag(val) __write_32bit_c0_register($22, 0, val) + +#define read_c0_diag1() __read_32bit_c0_register($22, 1) +#define write_c0_diag1(val) __write_32bit_c0_register($22, 1, val) + +#define read_c0_diag2() __read_32bit_c0_register($22, 2) +#define write_c0_diag2(val) __write_32bit_c0_register($22, 2, val) + +#define read_c0_diag3() __read_32bit_c0_register($22, 3) +#define write_c0_diag3(val) __write_32bit_c0_register($22, 3, val) + +#define read_c0_diag4() __read_32bit_c0_register($22, 4) +#define write_c0_diag4(val) __write_32bit_c0_register($22, 4, val) + +#define read_c0_diag5() __read_32bit_c0_register($22, 5) +#define write_c0_diag5(val) __write_32bit_c0_register($22, 5, val) + +#define read_c0_debug() __read_32bit_c0_register($23, 0) +#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val) + +#define read_c0_depc() __read_ulong_c0_register($24, 0) +#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val) + +/* + * MIPS32 / MIPS64 performance counters + */ +#define read_c0_perfctrl0() __read_32bit_c0_register($25, 0) +#define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val) +#define read_c0_perfcntr0() __read_32bit_c0_register($25, 1) +#define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val) +#define read_c0_perfctrl1() __read_32bit_c0_register($25, 2) +#define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val) +#define read_c0_perfcntr1() __read_32bit_c0_register($25, 3) +#define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val) +#define read_c0_perfctrl2() __read_32bit_c0_register($25, 4) +#define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val) +#define read_c0_perfcntr2() __read_32bit_c0_register($25, 5) +#define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val) +#define read_c0_perfctrl3() __read_32bit_c0_register($25, 6) +#define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val) +#define read_c0_perfcntr3() __read_32bit_c0_register($25, 7) +#define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val) + +/* RM9000 PerfCount performance counter register */ +#define read_c0_perfcount() __read_64bit_c0_register($25, 0) +#define write_c0_perfcount(val) __write_64bit_c0_register($25, 0, val) + +#define read_c0_ecc() __read_32bit_c0_register($26, 0) +#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) + +#define read_c0_derraddr0() __read_ulong_c0_register($26, 1) +#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val) + +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_derraddr1() __read_ulong_c0_register($27, 1) +#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_dtaglo() __read_32bit_c0_register($28, 2) +#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +/* MIPSR2 */ +#define read_c0_hwrena() __read_32bit_c0_register($7, 0) +#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_intctl() __read_32bit_c0_register($12, 1) +#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val) + +#define read_c0_srsctl() __read_32bit_c0_register($12, 2) +#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val) + +#define read_c0_srsmap() __read_32bit_c0_register($12, 3) +#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val) + +#define read_c0_ebase() __read_32bit_c0_register($15, 1) +#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val) + +/* + * Macros to access the floating point coprocessor control registers + */ +#define read_32bit_cp1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +#define rddsp(mask) \ +({ \ + unsigned int __res; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # rddsp $1, %x1 \n" \ + " .word 0x7c000cb8 | (%x1 << 16) \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__res) \ + : "i" (mask)); \ + __res; \ +}) + +#define wrdsp(val, mask) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # wrdsp $1, %x1 \n" \ + " .word 0x7c2004f8 | (%x1 << 11) \n" \ + " .set pop \n" \ + : \ + : "r" (val), "i" (mask)); \ +} while (0) + +#define mfhi0() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mfhi %0, $ac0 \n" \ + " .word 0x00000810 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mfhi1() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mfhi %0, $ac1 \n" \ + " .word 0x00200810 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mfhi2() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mfhi %0, $ac2 \n" \ + " .word 0x00400810 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mfhi3() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mfhi %0, $ac3 \n" \ + " .word 0x00600810 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mflo0() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mflo %0, $ac0 \n" \ + " .word 0x00000812 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mflo1() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mflo %0, $ac1 \n" \ + " .word 0x00200812 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mflo2() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mflo %0, $ac2 \n" \ + " .word 0x00400812 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mflo3() \ +({ \ + unsigned long __treg; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " # mflo %0, $ac3 \n" \ + " .word 0x00600812 \n" \ + " move %0, $1 \n" \ + " .set pop \n" \ + : "=r" (__treg)); \ + __treg; \ +}) + +#define mthi0(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mthi $1, $ac0 \n" \ + " .word 0x00200011 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mthi1(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mthi $1, $ac1 \n" \ + " .word 0x00200811 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mthi2(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mthi $1, $ac2 \n" \ + " .word 0x00201011 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mthi3(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mthi $1, $ac3 \n" \ + " .word 0x00201811 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mtlo0(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mtlo $1, $ac0 \n" \ + " .word 0x00200013 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mtlo1(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mtlo $1, $ac1 \n" \ + " .word 0x00200813 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mtlo2(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mtlo $1, $ac2 \n" \ + " .word 0x00201013 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +#define mtlo3(x) \ +do { \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ + " move $1, %0 \n" \ + " # mtlo $1, $ac3 \n" \ + " .word 0x00201813 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +} while (0) + +/* + * TLB operations. + * + * It is responsibility of the caller to take care of any TLB hazards. + */ +static inline void tlb_probe(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbp\n\t" + ".set reorder"); +} + +static inline void tlb_read(void) +{ +#if MIPS34K_MISSED_ITLB_WAR + int res = 0; + + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips32r2 \n" + " .word 0x41610001 # dvpe $1 \n" + " move %0, $1 \n" + " ehb \n" + " .set pop \n" + : "=r" (res)); + + instruction_hazard(); +#endif + + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbr\n\t" + ".set reorder"); + +#if MIPS34K_MISSED_ITLB_WAR + if ((res & _ULCAST_(1))) + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips32r2 \n" + " .word 0x41600021 # evpe \n" + " ehb \n" + " .set pop \n"); +#endif +} + +static inline void tlb_write_indexed(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwi\n\t" + ".set reorder"); +} + +static inline void tlb_write_random(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwr\n\t" + ".set reorder"); +} + +/* + * Manipulate bits in a c0 register. + */ +#define __BUILD_SET_C0(name) \ +static inline unsigned int \ +set_c0_##name(unsigned int set) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res |= set; \ + write_c0_##name(res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_c0_##name(unsigned int clear) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res &= ~clear; \ + write_c0_##name(res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_c0_##name(unsigned int change, unsigned int new) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res &= ~change; \ + res |= (new & change); \ + write_c0_##name(res); \ + \ + return res; \ +} + +__BUILD_SET_C0(status) +__BUILD_SET_C0(cause) +__BUILD_SET_C0(config) +__BUILD_SET_C0(intcontrol) +__BUILD_SET_C0(intctl) +__BUILD_SET_C0(srsmap) + +#endif /* !__ASSEMBLY__ */ + #endif /* _ASM_MIPSREGS_H */ -- cgit v1.3.1 From 31d826722434931e1152a09d140187dcf72f8aac Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Thu, 8 May 2008 19:02:12 -0500 Subject: PPC: Create and use CONFIG_HIGH_BATS Change all code that conditionally operates on high bat registers (that is, BATs 4-7) to look at CONFIG_HIGH_BATS instead of the myriad ways this is done now. Define the option for every config for which high bats are supported (and enabled by early boot, on parts where they're not always enabled) Signed-off-by: Becky Bruce --- cpu/74xx_7xx/start.S | 6 +++--- cpu/mpc83xx/start.S | 6 +++--- include/configs/Alaska8220.h | 2 ++ include/configs/BC3450.h | 2 ++ include/configs/CPCI750.h | 2 ++ include/configs/IceCube.h | 2 ++ include/configs/MPC8313ERDB.h | 2 ++ include/configs/MPC8315ERDB.h | 1 + include/configs/MPC8323ERDB.h | 1 + include/configs/MPC832XEMDS.h | 2 ++ include/configs/MPC8349EMDS.h | 1 + include/configs/MPC8349ITX.h | 1 + include/configs/MPC8360EMDS.h | 2 ++ include/configs/MPC8360ERDK.h | 2 ++ include/configs/MPC837XEMDS.h | 1 + include/configs/MPC837XERDB.h | 2 ++ include/configs/MPC8610HPCD.h | 1 + include/configs/MPC8641HPCN.h | 1 + include/configs/PM520.h | 2 ++ include/configs/TB5200.h | 2 ++ include/configs/TOP5200.h | 2 ++ include/configs/TQM5200.h | 2 ++ include/configs/TQM834x.h | 2 ++ include/configs/Total5200.h | 2 ++ include/configs/Yukon8220.h | 2 ++ include/configs/ads5121.h | 2 ++ include/configs/aev.h | 2 ++ include/configs/canmb.h | 2 ++ include/configs/cm5200.h | 2 ++ include/configs/cpci5200.h | 2 ++ include/configs/hmi1001.h | 2 ++ include/configs/inka4x0.h | 2 ++ include/configs/jupiter.h | 2 ++ include/configs/mcc200.h | 2 ++ include/configs/mecp5200.h | 2 ++ include/configs/motionpro.h | 1 + include/configs/mpc7448hpc2.h | 2 +- include/configs/munices.h | 1 + include/configs/o2dnt.h | 2 ++ include/configs/p3mx.h | 1 + include/configs/pf5200.h | 1 + include/configs/sbc8349.h | 2 ++ include/configs/smmaco4.h | 2 ++ include/configs/sorcery.h | 2 ++ include/configs/spieval.h | 2 ++ include/configs/uc101.h | 2 ++ include/configs/v38b.h | 2 ++ 47 files changed, 84 insertions(+), 7 deletions(-) (limited to 'cpu') diff --git a/cpu/74xx_7xx/start.S b/cpu/74xx_7xx/start.S index b5834b91e3e..42b0f72ac04 100644 --- a/cpu/74xx_7xx/start.S +++ b/cpu/74xx_7xx/start.S @@ -316,7 +316,7 @@ invalidate_bats: mtspr IBAT1U, r0 mtspr IBAT2U, r0 mtspr IBAT3U, r0 -#ifdef CONFIG_750FX +#ifdef CONFIG_HIGH_BATS mtspr IBAT4U, r0 mtspr IBAT5U, r0 mtspr IBAT6U, r0 @@ -327,7 +327,7 @@ invalidate_bats: mtspr DBAT1U, r0 mtspr DBAT2U, r0 mtspr DBAT3U, r0 -#ifdef CONFIG_750FX +#ifdef CONFIG_HIGH_BATS mtspr DBAT4U, r0 mtspr DBAT5U, r0 mtspr DBAT6U, r0 @@ -414,7 +414,7 @@ setup_bats: mtspr DBAT3U, r3 isync -#ifdef CONFIG_750FX +#ifdef CONFIG_HIGH_BATS /* IBAT 4 */ addis r4, r0, CFG_IBAT4L@h ori r4, r4, CFG_IBAT4L@l diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index 309eb30e8e9..c1821747917 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -557,7 +557,7 @@ invalidate_bats: mtspr IBAT1U, r0 mtspr IBAT2U, r0 mtspr IBAT3U, r0 -#if (CFG_HID2 & HID2_HBE) +#ifdef CONFIG_HIGH_BATS mtspr IBAT4U, r0 mtspr IBAT5U, r0 mtspr IBAT6U, r0 @@ -568,7 +568,7 @@ invalidate_bats: mtspr DBAT1U, r0 mtspr DBAT2U, r0 mtspr DBAT3U, r0 -#if (CFG_HID2 & HID2_HBE) +#ifdef CONFIG_HIGH_BATS mtspr DBAT4U, r0 mtspr DBAT5U, r0 mtspr DBAT6U, r0 @@ -655,7 +655,7 @@ setup_bats: mtspr DBAT3U, r3 isync -#if (CFG_HID2 & HID2_HBE) +#ifdef CONFIG_HIGH_BATS /* IBAT 4 */ addis r4, r0, CFG_IBAT4L@h ori r4, r4, CFG_IBAT4L@l diff --git a/include/configs/Alaska8220.h b/include/configs/Alaska8220.h index 3f2f6140f63..38b962f8232 100644 --- a/include/configs/Alaska8220.h +++ b/include/configs/Alaska8220.h @@ -31,6 +31,8 @@ #define CONFIG_MPC8220 1 #define CONFIG_ALASKA8220 1 /* ... on Alaska board */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* Input clock running at 30Mhz, read Hid1 for the CPU multiplier to determine the CPU speed. */ #define CFG_MPC8220_CLKIN 30000000/* ... running at 30MHz */ diff --git a/include/configs/BC3450.h b/include/configs/BC3450.h index 706c13efad4..b7574bf1494 100644 --- a/include/configs/BC3450.h +++ b/include/configs/BC3450.h @@ -61,6 +61,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/CPCI750.h b/include/configs/CPCI750.h index 48e29a20876..89edbde1de6 100644 --- a/include/configs/CPCI750.h +++ b/include/configs/CPCI750.h @@ -61,6 +61,8 @@ #undef CONFIG_ECC /* enable ECC support */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* which initialization functions to call for this board */ #define CONFIG_MISC_INIT_R #define CONFIG_BOARD_PRE_INIT diff --git a/include/configs/IceCube.h b/include/configs/IceCube.h index f85cff7abff..3a347eac55e 100644 --- a/include/configs/IceCube.h +++ b/include/configs/IceCube.h @@ -37,6 +37,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/MPC8313ERDB.h b/include/configs/MPC8313ERDB.h index 610151f5860..d547681c3d0 100644 --- a/include/configs/MPC8313ERDB.h +++ b/include/configs/MPC8313ERDB.h @@ -469,6 +469,8 @@ #define CFG_HID2 HID2_HBE +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* DDR @ 0x00000000 */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10) #define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) diff --git a/include/configs/MPC8315ERDB.h b/include/configs/MPC8315ERDB.h index e0a887c7e65..7a5d0aa1dde 100644 --- a/include/configs/MPC8315ERDB.h +++ b/include/configs/MPC8315ERDB.h @@ -453,6 +453,7 @@ /* * MMU Setup */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ /* DDR: cache cacheable */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) diff --git a/include/configs/MPC8323ERDB.h b/include/configs/MPC8323ERDB.h index 32f57ac7dad..977c041dca6 100644 --- a/include/configs/MPC8323ERDB.h +++ b/include/configs/MPC8323ERDB.h @@ -468,6 +468,7 @@ /* * MMU Setup */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ /* DDR: cache cacheable */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) diff --git a/include/configs/MPC832XEMDS.h b/include/configs/MPC832XEMDS.h index 1276a124c93..9ca2a2be04e 100644 --- a/include/configs/MPC832XEMDS.h +++ b/include/configs/MPC832XEMDS.h @@ -483,6 +483,8 @@ * MMU Setup */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* DDR: cache cacheable */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) #define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index 119e7ac7c61..bd775400032 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -626,6 +626,7 @@ #define CFG_HID2 HID2_HBE +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ /* DDR @ 0x00000000 */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h index c72de03c013..38410a1764c 100644 --- a/include/configs/MPC8349ITX.h +++ b/include/configs/MPC8349ITX.h @@ -555,6 +555,7 @@ boards, we say we have two, but don't display a message if we find only one. */ #define CFG_HID0_FINAL CFG_HID0_INIT #define CFG_HID2 HID2_HBE +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ /* DDR */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h index 983575eb0c1..fcfbe6f8219 100644 --- a/include/configs/MPC8360EMDS.h +++ b/include/configs/MPC8360EMDS.h @@ -515,6 +515,8 @@ * MMU Setup */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* DDR: cache cacheable */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) #define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) diff --git a/include/configs/MPC8360ERDK.h b/include/configs/MPC8360ERDK.h index 7b7d6f50c00..adedcb95af6 100644 --- a/include/configs/MPC8360ERDK.h +++ b/include/configs/MPC8360ERDK.h @@ -419,6 +419,8 @@ * MMU Setup */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* DDR: cache cacheable */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) #define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h index e92493ae4db..4e159a0b462 100644 --- a/include/configs/MPC837XEMDS.h +++ b/include/configs/MPC837XEMDS.h @@ -502,6 +502,7 @@ /* * MMU Setup */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ /* DDR: cache cacheable */ #define CFG_SDRAM_LOWER CFG_SDRAM_BASE diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h index f7e6fd2c52b..29c2490e6b1 100644 --- a/include/configs/MPC837XERDB.h +++ b/include/configs/MPC837XERDB.h @@ -524,6 +524,8 @@ * MMU Setup */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* DDR: cache cacheable */ #define CFG_SDRAM_LOWER CFG_SDRAM_BASE #define CFG_SDRAM_UPPER (CFG_SDRAM_BASE + 0x10000000) diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h index 15ff0eacf25..a051b6d39bf 100644 --- a/include/configs/MPC8610HPCD.h +++ b/include/configs/MPC8610HPCD.h @@ -55,6 +55,7 @@ #define CONFIG_NUM_DDR_CONTROLLERS 1 #define CONFIG_INTERRUPTS /* enable pci, srio, ddr interrupts */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported & enabled */ #define CONFIG_ALTIVEC 1 /* diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index 9acc3da54a2..49ee7ffd3a2 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -67,6 +67,7 @@ #define BANK_INTERLEAVING 0x22000000 #define SUPER_BANK_INTERLEAVING 0x23000000 +#define CONFIG_HIGH_BATS 1 /* High BATs supported and enabled */ #define CONFIG_ALTIVEC 1 diff --git a/include/configs/PM520.h b/include/configs/PM520.h index 6eb64449255..259178f857b 100644 --- a/include/configs/PM520.h +++ b/include/configs/PM520.h @@ -40,6 +40,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/TB5200.h b/include/configs/TB5200.h index 6cb3022b93f..d21783b838f 100644 --- a/include/configs/TB5200.h +++ b/include/configs/TB5200.h @@ -42,6 +42,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/TOP5200.h b/include/configs/TOP5200.h index 71fa36baae9..4c447356a44 100644 --- a/include/configs/TOP5200.h +++ b/include/configs/TOP5200.h @@ -50,6 +50,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h index bff2edf7696..bfb478a8688 100644 --- a/include/configs/TQM5200.h +++ b/include/configs/TQM5200.h @@ -47,6 +47,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index a86939e0978..89fc4654160 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -423,6 +423,8 @@ extern int tqm834x_num_flash_banks; #define CFG_HID0_FINAL CFG_HID0_INIT #define CFG_HID2 HID2_HBE +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* DDR 0 - 512M */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) #define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) diff --git a/include/configs/Total5200.h b/include/configs/Total5200.h index 31f10dd87c0..598fe7bf278 100644 --- a/include/configs/Total5200.h +++ b/include/configs/Total5200.h @@ -48,6 +48,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/Yukon8220.h b/include/configs/Yukon8220.h index 00c4ff093a6..1b4195a08fd 100644 --- a/include/configs/Yukon8220.h +++ b/include/configs/Yukon8220.h @@ -31,6 +31,8 @@ #define CONFIG_MPC8220 1 #define CONFIG_YUKON8220 1 /* ... on Yukon board */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* Input clock running at 30Mhz, read Hid1 for the CPU multiplier to determine the CPU speed. */ #define CFG_MPC8220_CLKIN 30000000/* ... running at 30MHz */ diff --git a/include/configs/ads5121.h b/include/configs/ads5121.h index c975a249c74..4226529eb7d 100644 --- a/include/configs/ads5121.h +++ b/include/configs/ads5121.h @@ -372,6 +372,8 @@ #define CFG_HID0_FINAL HID0_ENABLE_MACHINE_CHECK #define CFG_HID2 HID2_HBE +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Internal Definitions * diff --git a/include/configs/aev.h b/include/configs/aev.h index e3f810c5c89..c5e475921c4 100644 --- a/include/configs/aev.h +++ b/include/configs/aev.h @@ -41,6 +41,8 @@ #define CONFIG_AEVFIFO 1 #define CFG_MPC5XXX_CLKIN 33000000 /* ... running at 33.000000MHz */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ diff --git a/include/configs/canmb.h b/include/configs/canmb.h index 0f7bb619ceb..f097e2c2f09 100644 --- a/include/configs/canmb.h +++ b/include/configs/canmb.h @@ -40,6 +40,8 @@ #define CONFIG_BOARD_EARLY_INIT_R +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/cm5200.h b/include/configs/cm5200.h index d554348021f..ef50c7cabb7 100644 --- a/include/configs/cm5200.h +++ b/include/configs/cm5200.h @@ -31,6 +31,8 @@ #define CONFIG_MPC5200 1 /* (more precisely an MPC5200 CPU) */ #define CONFIG_CM5200 1 /* ... on CM5200 platform */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Supported commands */ diff --git a/include/configs/cpci5200.h b/include/configs/cpci5200.h index 1b30e51a3fe..fffd1fe1fa7 100644 --- a/include/configs/cpci5200.h +++ b/include/configs/cpci5200.h @@ -50,6 +50,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/hmi1001.h b/include/configs/hmi1001.h index e5a88977445..ad7cf76869a 100644 --- a/include/configs/hmi1001.h +++ b/include/configs/hmi1001.h @@ -40,6 +40,8 @@ #define CONFIG_BOARD_EARLY_INIT_R +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/inka4x0.h b/include/configs/inka4x0.h index c89f041ee47..6ec92c38c57 100644 --- a/include/configs/inka4x0.h +++ b/include/configs/inka4x0.h @@ -40,6 +40,8 @@ #define CONFIG_MISC_INIT_F 1 /* Use misc_init_f() */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/jupiter.h b/include/configs/jupiter.h index 980e9fe9cea..c9859270c00 100644 --- a/include/configs/jupiter.h +++ b/include/configs/jupiter.h @@ -41,6 +41,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h index a9c86f9e3f7..e4c3f7239be 100644 --- a/include/configs/mcc200.h +++ b/include/configs/mcc200.h @@ -40,6 +40,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration * diff --git a/include/configs/mecp5200.h b/include/configs/mecp5200.h index 5218d9ca975..8dfb9aa8a96 100644 --- a/include/configs/mecp5200.h +++ b/include/configs/mecp5200.h @@ -50,6 +50,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/motionpro.h b/include/configs/motionpro.h index 1503598166c..b6843af3dc6 100644 --- a/include/configs/motionpro.h +++ b/include/configs/motionpro.h @@ -35,6 +35,7 @@ #define CONFIG_MPC5200 1 /* More exactly a MPC5200 */ #define CONFIG_MOTIONPRO 1 /* ... on Promess Motion-PRO board */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ /* * BOOTP options diff --git a/include/configs/mpc7448hpc2.h b/include/configs/mpc7448hpc2.h index f614e679f9e..a218f7576c7 100644 --- a/include/configs/mpc7448hpc2.h +++ b/include/configs/mpc7448hpc2.h @@ -39,7 +39,7 @@ #define CONFIG_MPC7448HPC2 #define CONFIG_74xx -#define CONFIG_750FX /* this option to enable init of extended BATs */ +#define CONFIG_HIGH_BATS /* High BATs supported */ #define CONFIG_ALTIVEC /* undef to disable */ #define CFG_BOARD_NAME "MPC7448 HPC II" diff --git a/include/configs/munices.h b/include/configs/munices.h index 38b27bb3a77..e0046ec2d38 100644 --- a/include/configs/munices.h +++ b/include/configs/munices.h @@ -35,6 +35,7 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ #define CFG_CACHELINE_SIZE 32 /* For MPC5xxx CPUs */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ /* * Command line configuration. diff --git a/include/configs/o2dnt.h b/include/configs/o2dnt.h index 8dde1ef3916..88bdb03e67a 100644 --- a/include/configs/o2dnt.h +++ b/include/configs/o2dnt.h @@ -37,6 +37,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/p3mx.h b/include/configs/p3mx.h index 0dac5161ba7..0913b14a4ca 100644 --- a/include/configs/p3mx.h +++ b/include/configs/p3mx.h @@ -42,6 +42,7 @@ #if defined (CONFIG_P3M750) #define CONFIG_750FX /* 750GL/GX/FX */ +#define CONFIG_HIGH_BATS /* High BATs supported */ #define CFG_BOARD_NAME "P3M750" #define CFG_BUS_HZ 100000000 #define CFG_BUS_CLK CFG_BUS_HZ diff --git a/include/configs/pf5200.h b/include/configs/pf5200.h index 2ce39c913c8..c065d3328c9 100644 --- a/include/configs/pf5200.h +++ b/include/configs/pf5200.h @@ -49,6 +49,7 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ /* * Serial console configuration */ diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h index 0ebc674a69a..74815567ff9 100644 --- a/include/configs/sbc8349.h +++ b/include/configs/sbc8349.h @@ -570,6 +570,8 @@ #define CFG_HID2 HID2_HBE +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* DDR @ 0x00000000 */ #define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) #define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) diff --git a/include/configs/smmaco4.h b/include/configs/smmaco4.h index 4578cae7d66..3e47eb88a7c 100644 --- a/include/configs/smmaco4.h +++ b/include/configs/smmaco4.h @@ -42,6 +42,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/sorcery.h b/include/configs/sorcery.h index c62b9775c69..18f55337370 100644 --- a/include/configs/sorcery.h +++ b/include/configs/sorcery.h @@ -31,6 +31,8 @@ #define CONFIG_MPC8220 1 #define CONFIG_SORCERY 1 /* Sorcery board */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* Input clock running at 60Mhz, read Hid1 for the CPU multiplier to determine the CPU speed. */ #define CFG_MPC8220_CLKIN 60000000 /* ... running at 60MHz */ diff --git a/include/configs/spieval.h b/include/configs/spieval.h index 49213dc67ad..69d2d67ab1c 100644 --- a/include/configs/spieval.h +++ b/include/configs/spieval.h @@ -44,6 +44,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/uc101.h b/include/configs/uc101.h index dc1d7e1b3d4..042750e2fe9 100644 --- a/include/configs/uc101.h +++ b/include/configs/uc101.h @@ -40,6 +40,8 @@ #define CONFIG_BOARD_EARLY_INIT_R +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ diff --git a/include/configs/v38b.h b/include/configs/v38b.h index e24d6f77ae6..c2035225526 100644 --- a/include/configs/v38b.h +++ b/include/configs/v38b.h @@ -46,6 +46,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +#define CONFIG_HIGH_BATS 1 /* High BATs supported */ + /* * Serial console configuration */ -- cgit v1.3.1 From e34a0e911b6a1568d0ca864234fbd0ee060d9b35 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Thu, 8 May 2008 19:02:51 -0500 Subject: PPC: 86xx Add bat registers to reginfo command Signed-off-by: Becky Bruce --- cpu/mpc86xx/cpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'cpu') diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index 3c7476445d0..e26bf3671de 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -268,13 +269,14 @@ dma_xfer(void *dest, uint count, void *src) /* * Print out the state of various machine registers. - * Currently prints out LAWs and BR0/OR0 + * Currently prints out LAWs, BR0/OR0, and BATs */ void mpc86xx_reginfo(void) { immap_t *immap = (immap_t *)CFG_IMMR; ccsr_lbc_t *lbc = &immap->im_lbc; + print_bats(); print_laws(); printf ("Local Bus Controller Registers\n" -- cgit v1.3.1 From 9b124a68346ce9605b6e1fcf79e1021541cdba9e Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Wed, 14 May 2008 13:09:51 -0500 Subject: MPC512x: Change traps.c to not reference non-addressable memory Currently, END_OF_RAM is used by the trap code to determine if we should attempt to access the stack pointer or not. However, on systems with a lot of RAM, only a subset of the RAM is guaranteed to be mapped in and accessible. Change END_OF_RAM to use get_effective_memsize() instead of using the raw ram size out of the bd. Signed-off-by: Becky Bruce --- cpu/mpc512x/traps.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'cpu') diff --git a/cpu/mpc512x/traps.c b/cpu/mpc512x/traps.c index 8455c92761b..8000fabd4ad 100644 --- a/cpu/mpc512x/traps.c +++ b/cpu/mpc512x/traps.c @@ -34,7 +34,13 @@ DECLARE_GLOBAL_DATA_PTR; extern unsigned long search_exception_table(unsigned long); -#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize) +/* + * End of addressable memory. This may be less than the actual + * amount of memory on the system if we're unable to keep all + * the memory mapped in. + */ +extern ulong get_effective_memsize(void); +#define END_OF_MEM (gd->bd->bi_memstart + get_effective_memsize()) /* * Trap & Exception support -- cgit v1.3.1 From d255bb0e78d1cac5b7c8c98cb77a095f5f16de0d Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 16 May 2008 11:10:31 +0200 Subject: SPI API improvements This patch gets rid of the spi_chipsel table and adds a handful of new functions that makes the SPI layer cleaner and more flexible. Instead of the spi_chipsel table, each board that wants to use SPI gets to implement three hooks: * spi_cs_activate(): Activates the chipselect for a given slave * spi_cs_deactivate(): Deactivates the chipselect for a given slave * spi_cs_is_valid(): Determines if the given bus/chipselect combination can be activated. Not all drivers may need those extra functions however. If that's the case, the board code may just leave them out (assuming they know what the driver needs) or rely on the linker to strip them out (assuming --gc-sections is being used.) To set up communication parameters for a given slave, the driver needs to call spi_setup_slave(). This returns a pointer to an opaque spi_slave struct which must be passed as a parameter to subsequent SPI calls. This struct can be freed by calling spi_free_slave(), but most driver probably don't want to do this. Before starting one or more SPI transfers, the driver must call spi_claim_bus() to gain exclusive access to the SPI bus and initialize the hardware. When all transfers are done, the driver must call spi_release_bus() to make the bus available to others, and possibly shut down the SPI controller hardware. spi_xfer() behaves mostly the same as before, but it now takes a spi_slave parameter instead of a spi_chipsel function pointer. It also got a new parameter, flags, which is used to specify chip select behaviour. This may be extended with other flags in the future. This patch has been build-tested on all powerpc and arm boards involved. I have not tested NIOS since I don't have a toolchain for it installed, so I expect some breakage there even though I've tried fixing up everything I could find by visual inspection. I have run-time tested this on AVR32 ATNGW100 using the atmel_spi and DataFlash drivers posted as a follow-up. I'd like some help testing other boards that use the existing SPI API. But most of all, I'd like some comments on the new API. Is this stuff usable for everyone? If not, why? Changed in v4: - Build fixes for various boards, drivers and commands - Provide common struct spi_slave definition that can be extended by drivers - Pass a struct spi_slave * to spi_cs_activate and spi_cs_deactivate - Make default bus and mode build-time configurable - Override default SPI bus ID and mode on mx32ads and imx31_litekit. Changed in v3: - Add opaque struct spi_slave for controller-specific data associated with a slave. - Add spi_claim_bus() and spi_release_bus() - Add spi_free_slave() - spi_setup() is now called spi_setup_slave() and returns a struct spi_slave - soft_spi now supports four SPI modes (CPOL|CPHA) - Add bus parameter to spi_setup_slave() - Convert the new i.MX32 SPI driver - Convert the new MC13783 RTC driver Changed in v2: - Convert the mpc8xxx_spi driver and the mpc8349emds board to the new API. Signed-off-by: Haavard Skinnemoen Tested-by: Guennadi Liakhovetski --- board/amcc/taihu/taihu.c | 16 ++-- board/freescale/mpc8349emds/mpc8349emds.c | 25 +++-- board/sacsng/sacsng.c | 35 +++---- board/ssv/adnpesc1/adnpesc1.c | 27 +++--- common/cmd_df.c | 37 ++++++++ common/cmd_spi.c | 42 +++++---- common/soft_spi.c | 124 ++++++++++++++++++------ cpu/nios/spi.c | 79 +++++++++++----- drivers/rtc/ds1306.c | 67 +++++++++---- drivers/rtc/mc13783-rtc.c | 43 +++++++-- drivers/spi/mpc8xxx_spi.c | 54 +++++++++-- drivers/spi/mxc_spi.c | 88 ++++++++++++------ include/configs/imx31_litekit.h | 3 +- include/configs/mx31ads.h | 3 +- include/spi.h | 150 +++++++++++++++++++++++++----- 15 files changed, 584 insertions(+), 209 deletions(-) create mode 100644 common/cmd_df.c (limited to 'cpu') diff --git a/board/amcc/taihu/taihu.c b/board/amcc/taihu/taihu.c index eedde597b81..891b4d92498 100644 --- a/board/amcc/taihu/taihu.c +++ b/board/amcc/taihu/taihu.c @@ -165,16 +165,20 @@ unsigned char spi_read(void) return (unsigned char)gpio_read_in_bit(SPI_DIN_GPIO15); } -void taihu_spi_chipsel(int cs) +int spi_cs_is_valid(unsigned int bus, unsigned int cs) { - gpio_write_bit(SPI_CS_GPIO0, cs); + return bus == 0 && cs == 0; } -spi_chipsel_type spi_chipsel[]= { - taihu_spi_chipsel -}; +void spi_cs_activate(struct spi_slave *slave) +{ + gpio_write_bit(SPI_CS_GPIO0, 1); +} -int spi_chipsel_cnt = sizeof(spi_chipsel) / sizeof(spi_chipsel[0]); +void spi_cs_deactivate(struct spi_slave *slave) +{ + gpio_write_bit(SPI_CS_GPIO0, 0); +} #ifdef CONFIG_PCI static unsigned char int_lines[32] = { diff --git a/board/freescale/mpc8349emds/mpc8349emds.c b/board/freescale/mpc8349emds/mpc8349emds.c index 6c825969d38..e18e68e8cec 100644 --- a/board/freescale/mpc8349emds/mpc8349emds.c +++ b/board/freescale/mpc8349emds/mpc8349emds.c @@ -257,25 +257,24 @@ void sdram_init(void) #define SPI_CS_MASK 0x80000000 -void spi_eeprom_chipsel(int cs) +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs == 0; +} + +void spi_cs_activate(struct spi_slave *slave) { volatile gpio83xx_t *iopd = &((immap_t *)CFG_IMMR)->gpio[0]; - if (cs) - iopd->dat &= ~SPI_CS_MASK; - else - iopd->dat |= SPI_CS_MASK; + iopd->dat &= ~SPI_CS_MASK; } -/* - * The SPI command uses this table of functions for controlling the SPI - * chip selects. - */ -spi_chipsel_type spi_chipsel[] = { - spi_eeprom_chipsel, -}; -int spi_chipsel_cnt = sizeof(spi_chipsel) / sizeof(spi_chipsel[0]); +void spi_cs_deactivate(struct spi_slave *slave) +{ + volatile gpio83xx_t *iopd = &((immap_t *)CFG_IMMR)->gpio[0]; + iopd->dat |= SPI_CS_MASK; +} #endif /* CONFIG_HARD_SPI */ #if defined(CONFIG_OF_BOARD_SETUP) diff --git a/board/sacsng/sacsng.c b/board/sacsng/sacsng.c index 25209e05464..e85a0fc4dbe 100644 --- a/board/sacsng/sacsng.c +++ b/board/sacsng/sacsng.c @@ -842,37 +842,30 @@ void show_boot_progress (int status) #define SPI_ADC_CS_MASK 0x00000800 #define SPI_DAC_CS_MASK 0x00001000 -void spi_adc_chipsel(int cs) +static const u32 cs_mask[] = { + SPI_ADC_CS_MASK, + SPI_DAC_CS_MASK, +}; + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs < sizeof(cs_mask) / sizeof(cs_mask[0]); +} + +void spi_cs_activate(struct spi_slave *slave) { volatile ioport_t *iopd = ioport_addr((immap_t *)CFG_IMMR, 3 /* port D */); - if(cs) - iopd->pdat &= ~SPI_ADC_CS_MASK; /* activate the chip select */ - else - iopd->pdat |= SPI_ADC_CS_MASK; /* deactivate the chip select */ + iopd->pdat &= ~cs_mask[slave->cs]; } -void spi_dac_chipsel(int cs) +void spi_cs_deactivate(struct spi_slave *slave) { volatile ioport_t *iopd = ioport_addr((immap_t *)CFG_IMMR, 3 /* port D */); - if(cs) - iopd->pdat &= ~SPI_DAC_CS_MASK; /* activate the chip select */ - else - iopd->pdat |= SPI_DAC_CS_MASK; /* deactivate the chip select */ + iopd->pdat |= cs_mask[slave->cs]; } -/* - * The SPI command uses this table of functions for controlling the SPI - * chip selects: it calls the appropriate function to control the SPI - * chip selects. - */ -spi_chipsel_type spi_chipsel[] = { - spi_adc_chipsel, - spi_dac_chipsel -}; -int spi_chipsel_cnt = sizeof(spi_chipsel) / sizeof(spi_chipsel[0]); - #endif #endif /* CONFIG_MISC_INIT_R */ diff --git a/board/ssv/adnpesc1/adnpesc1.c b/board/ssv/adnpesc1/adnpesc1.c index 2ec3a728d74..3ee8ba588dc 100644 --- a/board/ssv/adnpesc1/adnpesc1.c +++ b/board/ssv/adnpesc1/adnpesc1.c @@ -69,25 +69,24 @@ long int initdram (int board_type) #define SPI_RTC_CS_MASK 0x00000001 -void spi_rtc_chipsel(int cs) +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs == 0; +} + +void spi_cs_activate(struct spi_slave *slave) { nios_spi_t *spi = (nios_spi_t *)CFG_NIOS_SPIBASE; - if (cs) - spi->slaveselect = SPI_RTC_CS_MASK; /* activate (1) */ - else - spi->slaveselect = 0; /* deactivate (0) */ + spi->slaveselect = SPI_RTC_CS_MASK; /* activate (1) */ } -/* - * The SPI command uses this table of functions for controlling the SPI - * chip selects: it calls the appropriate function to control the SPI - * chip selects. - */ -spi_chipsel_type spi_chipsel[] = { - spi_rtc_chipsel -}; -int spi_chipsel_cnt = sizeof(spi_chipsel) / sizeof(spi_chipsel[0]); +void spi_cs_deactivate(struct spi_slave *slave) +{ + nios_spi_t *spi = (nios_spi_t *)CFG_NIOS_SPIBASE; + + spi->slaveselect = 0; /* deactivate (0) */ +} #endif diff --git a/common/cmd_df.c b/common/cmd_df.c new file mode 100644 index 00000000000..5f650442c01 --- /dev/null +++ b/common/cmd_df.c @@ -0,0 +1,37 @@ +/* + * Command for accessing DataFlash. + * + * Copyright (C) 2008 Atmel Corporation + */ +#include +#include + +static int do_df(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + const char *cmd; + + /* need at least two arguments */ + if (argc < 2) + goto usage; + + cmd = argv[1]; + + if (strcmp(cmd, "init") == 0) { + df_init(0, 0, 1000000); + return 0; + } + + if (strcmp(cmd, "info") == 0) { + df_show_info(); + return 0; + } + +usage: + printf("Usage:\n%s\n", cmdtp->usage); + return 1; +} + +U_BOOT_CMD( + sf, 2, 1, do_serial_flash, + "sf - Serial flash sub-system\n", + "probe [bus:]cs - init flash device on given SPI bus and CS\n") diff --git a/common/cmd_spi.c b/common/cmd_spi.c index 76044221416..40ee7e7dd3c 100644 --- a/common/cmd_spi.c +++ b/common/cmd_spi.c @@ -37,20 +37,20 @@ # define MAX_SPI_BYTES 32 /* Maximum number of bytes we can handle */ #endif -/* - * External table of chip select functions (see the appropriate board - * support for the actual definition of the table). - */ -extern spi_chipsel_type spi_chipsel[]; -extern int spi_chipsel_cnt; +#ifndef CONFIG_DEFAULT_SPI_BUS +# define CONFIG_DEFAULT_SPI_BUS 0 +#endif +#ifndef CONFIG_DEFAULT_SPI_MODE +# define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0 +#endif /* * Values from last command. */ -static int device; -static int bitlen; -static uchar dout[MAX_SPI_BYTES]; -static uchar din[MAX_SPI_BYTES]; +static unsigned int device; +static int bitlen; +static uchar dout[MAX_SPI_BYTES]; +static uchar din[MAX_SPI_BYTES]; /* * SPI read/write @@ -65,6 +65,7 @@ static uchar din[MAX_SPI_BYTES]; int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { + struct spi_slave *slave; char *cp = 0; uchar tmp; int j; @@ -101,19 +102,24 @@ int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } } - if ((device < 0) || (device >= spi_chipsel_cnt)) { - printf("Invalid device %d, giving up.\n", device); - return 1; - } if ((bitlen < 0) || (bitlen > (MAX_SPI_BYTES * 8))) { printf("Invalid bitlen %d, giving up.\n", bitlen); return 1; } - debug ("spi_chipsel[%d] = %08X\n", - device, (uint)spi_chipsel[device]); + /* FIXME: Make these parameters run-time configurable */ + slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, device, 1000000, + CONFIG_DEFAULT_SPI_MODE); + if (!slave) { + printf("Invalid device %d, giving up.\n", device); + return 1; + } + + debug ("spi chipsel = %08X\n", device); - if(spi_xfer(spi_chipsel[device], bitlen, dout, din) != 0) { + spi_claim_bus(slave); + if(spi_xfer(slave, bitlen, dout, din, + SPI_XFER_BEGIN | SPI_XFER_END) != 0) { printf("Error with the SPI transaction.\n"); rcode = 1; } else { @@ -123,6 +129,8 @@ int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } printf("\n"); } + spi_release_bus(slave); + spi_free_slave(slave); return rcode; } diff --git a/common/soft_spi.c b/common/soft_spi.c index e4250616c28..c13165030db 100644 --- a/common/soft_spi.c +++ b/common/soft_spi.c @@ -29,6 +29,8 @@ #if defined(CONFIG_SOFT_SPI) +#include + /*----------------------------------------------------------------------- * Definitions */ @@ -39,6 +41,15 @@ #define PRINTD(fmt,args...) #endif +struct soft_spi_slave { + struct spi_slave slave; + unsigned int mode; +}; + +static inline struct soft_spi_slave *to_soft_spi(struct spi_slave *slave) +{ + return container_of(slave, struct soft_spi_slave, slave); +} /*=====================================================================*/ /* Public Functions */ @@ -56,6 +67,57 @@ void spi_init (void) #endif } +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct soft_spi_slave *ss; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + ss = malloc(sizeof(struct soft_spi_slave)); + if (!ss) + return NULL; + + ss->slave.bus = bus; + ss->slave.cs = cs; + ss->mode = mode; + + /* TODO: Use max_hz to limit the SCK rate */ + + return &ss->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct soft_spi_slave *ss = to_soft_spi(slave); + + free(ss); +} + +int spi_claim_bus(struct spi_slave *slave) +{ +#ifdef CFG_IMMR + volatile immap_t *immr = (immap_t *)CFG_IMMR; +#endif + struct soft_spi_slave *ss = to_soft_spi(slave); + + /* + * Make sure the SPI clock is in idle state as defined for + * this slave. + */ + if (ss->mode & SPI_CPOL) + SPI_SCL(1); + else + SPI_SCL(0); + + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + /* Nothing to do */ +} /*----------------------------------------------------------------------- * SPI transfer @@ -68,50 +130,54 @@ void spi_init (void) * and "din" can point to the same memory location, in which case the * input data overwrites the output data (since both are buffered by * temporary variables, this is OK). - * - * If the chipsel() function is not NULL, it is called with a parameter - * of '1' (chip select active) at the start of the transfer and again with - * a parameter of '0' at the end of the transfer. - * - * If the chipsel() function _is_ NULL, it the responsibility of the - * caller to make the appropriate chip select active before calling - * spi_xfer() and making it inactive after spi_xfer() returns. */ -int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) { #ifdef CFG_IMMR volatile immap_t *immr = (immap_t *)CFG_IMMR; #endif - uchar tmpdin = 0; - uchar tmpdout = 0; - int j; + struct soft_spi_slave *ss = to_soft_spi(slave); + uchar tmpdin = 0; + uchar tmpdout = 0; + const u8 *txd = dout; + u8 *rxd = din; + int cpol = ss->mode & SPI_CPOL; + int cpha = ss->mode & SPI_CPHA; + unsigned int j; - PRINTD("spi_xfer: chipsel %08X dout %08X din %08X bitlen %d\n", - (int)chipsel, *(uint *)dout, *(uint *)din, bitlen); + PRINTD("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", + slave->bus, slave->cs, *(uint *)txd, *(uint *)rxd, bitlen); - if(chipsel != NULL) { - (*chipsel)(1); /* select the target chip */ - } + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); for(j = 0; j < bitlen; j++) { /* * Check if it is time to work on a new byte. */ if((j % 8) == 0) { - tmpdout = *dout++; + tmpdout = *txd++; if(j != 0) { - *din++ = tmpdin; + *rxd++ = tmpdin; } tmpdin = 0; } - SPI_SCL(0); + + if (!cpha) + SPI_SCL(!cpol); SPI_SDA(tmpdout & 0x80); SPI_DELAY; - SPI_SCL(1); + if (cpha) + SPI_SCL(!cpol); + else + SPI_SCL(cpol); + tmpdin <<= 1; + tmpdin |= SPI_READ; + tmpdout <<= 1; SPI_DELAY; - tmpdin <<= 1; - tmpdin |= SPI_READ; - tmpdout <<= 1; + if (cpha) + SPI_SCL(cpol); } /* * If the number of bits isn't a multiple of 8, shift the last @@ -120,14 +186,10 @@ int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) */ if((bitlen % 8) != 0) tmpdin <<= 8 - (bitlen % 8); - *din++ = tmpdin; - - SPI_SCL(0); /* SPI wants the clock left low for idle */ + *rxd++ = tmpdin; - if(chipsel != NULL) { - (*chipsel)(0); /* deselect the target chip */ - - } + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); return(0); } diff --git a/cpu/nios/spi.c b/cpu/nios/spi.c index f37146b7939..6408180147a 100644 --- a/cpu/nios/spi.c +++ b/cpu/nios/spi.c @@ -63,10 +63,10 @@ static char quickhex (int i) return hex_digit[i]; } -static void memdump (void *pv, int num) +static void memdump (const void *pv, int num) { int i; - unsigned char *pc = (unsigned char *) pv; + const unsigned char *pc = (const unsigned char *) pv; for (i = 0; i < num; i++) printf ("%c%c ", quickhex (pc[i] >> 4), quickhex (pc[i] & 0x0f)); @@ -83,26 +83,64 @@ static void memdump (void *pv, int num) #endif /* DEBUG */ +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct spi_slave *slave; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + slave = malloc(sizeof(struct spi_slave)); + if (!slave) + return NULL; + + slave->bus = bus; + slave->cs = cs; + + /* TODO: Add support for different modes and speeds */ + + return slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + +} + /* * SPI transfer: * * See include/spi.h and http://www.altera.com/literature/ds/ds_nios_spi.pdf * for more informations. */ -int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) +int spi_xfer(struct spi_slave *slave, int bitlen, const void *dout, + void *din, unsigned long flags) { + const u8 *txd = dout; + u8 *rxd = din; int j; - DPRINT(("spi_xfer: chipsel %08X dout %08X din %08X bitlen %d\n", - (int)chipsel, *(uint *)dout, *(uint *)din, bitlen)); + DPRINT(("spi_xfer: slave %u:%u dout %08X din %08X bitlen %d\n", + slave->bus, slave->cs, *(uint *)dout, *(uint *)din, bitlen)); - memdump((void*)dout, (bitlen + 7) / 8); + memdump(dout, (bitlen + 7) / 8); - if(chipsel != NULL) { - chipsel(1); /* select the target chip */ - } + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); - if (bitlen > CFG_NIOS_SPIBITS) { /* leave chip select active */ + if (!(flags & SPI_XFER_END) || bitlen > CFG_NIOS_SPIBITS) { + /* leave chip select active */ spi->control |= NIOS_SPI_SSO; } @@ -114,11 +152,11 @@ int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) while ((spi->status & NIOS_SPI_TRDY) == 0) ; - spi->txdata = (unsigned)(dout[j]); + spi->txdata = (unsigned)(txd[j]); while ((spi->status & NIOS_SPI_RRDY) == 0) ; - din[j] = (unsigned char)(spi->rxdata & 0xff); + rxd[j] = (unsigned char)(spi->rxdata & 0xff); #elif (CFG_NIOS_SPIBITS == 16) j++, j++) { @@ -126,15 +164,15 @@ int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) while ((spi->status & NIOS_SPI_TRDY) == 0) ; if ((j+1) < ((bitlen + 7) / 8)) - spi->txdata = (unsigned)((dout[j] << 8) | dout[j+1]); + spi->txdata = (unsigned)((txd[j] << 8) | txd[j+1]); else - spi->txdata = (unsigned)(dout[j] << 8); + spi->txdata = (unsigned)(txd[j] << 8); while ((spi->status & NIOS_SPI_RRDY) == 0) ; - din[j] = (unsigned char)((spi->rxdata >> 8) & 0xff); + rxd[j] = (unsigned char)((spi->rxdata >> 8) & 0xff); if ((j+1) < ((bitlen + 7) / 8)) - din[j+1] = (unsigned char)(spi->rxdata & 0xff); + rxd[j+1] = (unsigned char)(spi->rxdata & 0xff); #else #error "*** unsupported value of CFG_NIOS_SPIBITS ***" @@ -142,15 +180,14 @@ int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) } - if (bitlen > CFG_NIOS_SPIBITS) { + if (bitlen > CFG_NIOS_SPIBITS && (flags & SPI_XFER_END)) { spi->control &= ~NIOS_SPI_SSO; } - if(chipsel != NULL) { - chipsel(0); /* deselect the target chip */ - } + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); - memdump((void*)din, (bitlen + 7) / 8); + memdump(din, (bitlen + 7) / 8); return 0; } diff --git a/drivers/rtc/ds1306.c b/drivers/rtc/ds1306.c index 1c8ac7f2927..29854fc7c4c 100644 --- a/drivers/rtc/ds1306.c +++ b/drivers/rtc/ds1306.c @@ -62,13 +62,6 @@ #define RTC_USER_RAM_BASE 0x20 -/* - * External table of chip select functions (see the appropriate board - * support for the actual definition of the table). - */ -extern spi_chipsel_type spi_chipsel[]; -extern int spi_chipsel_cnt; - static unsigned int bin2bcd (unsigned int n); static unsigned char bcd2bin (unsigned char c); @@ -305,11 +298,29 @@ void rtc_reset (void) static unsigned char rtc_read (unsigned char reg); static void rtc_write (unsigned char reg, unsigned char val); +static struct spi_slave *slave; + /* read clock time from DS1306 and return it in *tmp */ int rtc_get (struct rtc_time *tmp) { unsigned char sec, min, hour, mday, wday, mon, year; + /* + * Assuming Vcc = 2.0V (lowest speed) + * + * REVISIT: If we add an rtc_init() function we can do this + * step just once. + */ + if (!slave) { + slave = spi_setup_slave(0, CFG_SPI_RTC_DEVID, 600000, + SPI_MODE_3 | SPI_CS_HIGH); + if (!slave) + return; + } + + if (spi_claim_bus(slave)) + return; + sec = rtc_read (RTC_SECONDS); min = rtc_read (RTC_MINUTES); hour = rtc_read (RTC_HOURS); @@ -318,6 +329,8 @@ int rtc_get (struct rtc_time *tmp) mon = rtc_read (RTC_MONTH); year = rtc_read (RTC_YEAR); + spi_release_bus(slave); + debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x " "hr: %02x min: %02x sec: %02x\n", year, mon, mday, wday, hour, min, sec); @@ -360,6 +373,17 @@ int rtc_get (struct rtc_time *tmp) /* set clock time from *tmp in DS1306 RTC */ void rtc_set (struct rtc_time *tmp) { + /* Assuming Vcc = 2.0V (lowest speed) */ + if (!slave) { + slave = spi_setup_slave(0, CFG_SPI_RTC_DEVID, 600000, + SPI_MODE_3 | SPI_CS_HIGH); + if (!slave) + return; + } + + if (spi_claim_bus(slave)) + return; + debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); @@ -371,6 +395,8 @@ void rtc_set (struct rtc_time *tmp) rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday)); rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon)); rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000)); + + spi_release_bus(slave); } /* ------------------------------------------------------------------------- */ @@ -378,6 +404,17 @@ void rtc_set (struct rtc_time *tmp) /* reset the DS1306 */ void rtc_reset (void) { + /* Assuming Vcc = 2.0V (lowest speed) */ + if (!slave) { + slave = spi_setup_slave(0, CFG_SPI_RTC_DEVID, 600000, + SPI_MODE_3 | SPI_CS_HIGH); + if (!slave) + return; + } + + if (spi_claim_bus(slave)) + return; + /* clear the control register */ rtc_write (RTC_CONTROL, 0x00); /* 1st step: reset WP */ rtc_write (RTC_CONTROL, 0x00); /* 2nd step: reset 1Hz, AIE1, AIE0 */ @@ -391,22 +428,18 @@ void rtc_reset (void) rtc_write (RTC_HOURS_ALARM1, 0x00); rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00); rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00); + + spi_release_bus(slave); } /* ------------------------------------------------------------------------- */ static unsigned char rtc_read (unsigned char reg) { - unsigned char dout[2]; /* SPI Output Data Bytes */ - unsigned char din[2]; /* SPI Input Data Bytes */ - - dout[0] = reg; + int ret; - if (spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din) != 0) { - return 0; - } else { - return din[1]; - } + ret = spi_w8r8(slave, reg); + return ret < 0 ? 0 : ret; } /* ------------------------------------------------------------------------- */ @@ -419,7 +452,7 @@ static void rtc_write (unsigned char reg, unsigned char val) dout[0] = 0x80 | reg; dout[1] = val; - spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din); + spi_xfer (slave, 16, dout, din, SPI_XFER_BEGIN | SPI_XFER_END); } #endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */ diff --git a/drivers/rtc/mc13783-rtc.c b/drivers/rtc/mc13783-rtc.c index 35b1b8b254d..b6e15014bb6 100644 --- a/drivers/rtc/mc13783-rtc.c +++ b/drivers/rtc/mc13783-rtc.c @@ -24,34 +24,50 @@ #include #include +static struct spi_slave *slave; + int rtc_get(struct rtc_time *rtc) { u32 day1, day2, time; u32 reg; int err, tim, i = 0; - spi_select(1, 0, SPI_MODE_2 | SPI_CS_HIGH); + if (!slave) { + /* FIXME: Verify the max SCK rate */ + slave = spi_setup_slave(1, 0, 1000000, + SPI_MODE_2 | SPI_CS_HIGH); + if (!slave) + return -1; + } + + if (spi_claim_bus(slave)) + return -1; do { reg = 0x2c000000; - err = spi_xfer(0, 32, (uchar *)®, (uchar *)&day1); + err = spi_xfer(slave, 32, (uchar *)®, (uchar *)&day1, + SPI_XFER_BEGIN | SPI_XFER_END); if (err) return err; reg = 0x28000000; - err = spi_xfer(0, 32, (uchar *)®, (uchar *)&time); + err = spi_xfer(slave, 32, (uchar *)®, (uchar *)&time, + SPI_XFER_BEGIN | SPI_XFER_END); if (err) return err; reg = 0x2c000000; - err = spi_xfer(0, 32, (uchar *)®, (uchar *)&day2); + err = spi_xfer(slave, 32, (uchar *)®, (uchar *)&day2, + SPI_XFER_BEGIN | SPI_XFER_END); if (err) return err; } while (day1 != day2 && i++ < 3); + spi_release_bus(slave); + tim = day1 * 86400 + time; to_tm(tim, rtc); @@ -65,16 +81,31 @@ void rtc_set(struct rtc_time *rtc) { u32 time, day, reg; + if (!slave) { + /* FIXME: Verify the max SCK rate */ + slave = spi_setup_slave(1, 0, 1000000, + SPI_MODE_2 | SPI_CS_HIGH); + if (!slave) + return; + } + time = mktime(rtc->tm_year, rtc->tm_mon, rtc->tm_mday, rtc->tm_hour, rtc->tm_min, rtc->tm_sec); day = time / 86400; time %= 86400; + if (spi_claim_bus(slave)) + return; + reg = 0x2c000000 | day | 0x80000000; - spi_xfer(0, 32, (uchar *)®, (uchar *)&day); + spi_xfer(slave, 32, (uchar *)®, (uchar *)&day, + SPI_XFER_BEGIN | SPI_XFER_END); reg = 0x28000000 | time | 0x80000000; - spi_xfer(0, 32, (uchar *)®, (uchar *)&time); + spi_xfer(slave, 32, (uchar *)®, (uchar *)&time, + SPI_XFER_BEGIN | SPI_XFER_END); + + spi_release_bus(slave); } void rtc_reset(void) diff --git a/drivers/spi/mpc8xxx_spi.c b/drivers/spi/mpc8xxx_spi.c index 2fe838c45d5..136fb50052f 100644 --- a/drivers/spi/mpc8xxx_spi.c +++ b/drivers/spi/mpc8xxx_spi.c @@ -24,6 +24,7 @@ #include #if defined(CONFIG_MPC8XXX_SPI) && defined(CONFIG_HARD_SPI) +#include #include #include @@ -37,6 +38,34 @@ #define SPI_TIMEOUT 1000 +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct spi_slave *slave; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + slave = malloc(sizeof(struct spi_slave)); + if (!slave) + return NULL; + + slave->bus = bus; + slave->cs = cs; + + /* + * TODO: Some of the code in spi_init() should probably move + * here, or into spi_claim_bus() below. + */ + + return slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + void spi_init(void) { volatile spi8xxx_t *spi = &((immap_t *) (CFG_IMMR))->spi; @@ -53,7 +82,18 @@ void spi_init(void) spi->com = 0; /* LST bit doesn't do anything, so disregard */ } -int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) { volatile spi8xxx_t *spi = &((immap_t *) (CFG_IMMR))->spi; unsigned int tmpdout, tmpdin, event; @@ -61,11 +101,11 @@ int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) int tm, isRead = 0; unsigned char charSize = 32; - debug("spi_xfer: chipsel %08X dout %08X din %08X bitlen %d\n", - (int)chipsel, *(uint *) dout, *(uint *) din, bitlen); + debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", + slave->bus, slave->cs, *(uint *) dout, *(uint *) din, bitlen); - if (chipsel != NULL) - (*chipsel) (1); /* select the target chip */ + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); spi->event = 0xffffffff; /* Clear all SPI events */ @@ -135,8 +175,8 @@ int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) debug("*** spi_xfer: transfer ended. Value=%08x\n", tmpdin); } - if (chipsel != NULL) - (*chipsel) (0); /* deselect the target chip */ + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); return 0; } diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index c166ec50239..5957ada3a4a 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -61,17 +62,18 @@ static unsigned long spi_bases[] = { 0x53f84000, }; -static unsigned long spi_base; - #endif -spi_chipsel_type spi_chipsel[] = { - (spi_chipsel_type)0, - (spi_chipsel_type)1, - (spi_chipsel_type)2, - (spi_chipsel_type)3, +struct mxc_spi_slave { + struct spi_slave slave; + unsigned long base; + u32 ctrl_reg; }; -int spi_chipsel_cnt = sizeof(spi_chipsel) / sizeof(spi_chipsel[0]); + +static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave) +{ + return container_of(slave, struct mxc_spi_slave, slave); +} static inline u32 reg_read(unsigned long addr) { @@ -83,30 +85,31 @@ static inline void reg_write(unsigned long addr, u32 val) *(volatile unsigned long*)addr = val; } -static u32 spi_xchg_single(u32 data, int bitlen) +static u32 spi_xchg_single(struct spi_slave *slave, u32 data, int bitlen) { - - unsigned int cfg_reg = reg_read(spi_base + MXC_CSPICTRL); + struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave); + unsigned int cfg_reg = reg_read(mxcs->base + MXC_CSPICTRL); if (MXC_CSPICTRL_BITCOUNT(bitlen - 1) != (cfg_reg & MXC_CSPICTRL_BITCOUNT(31))) { cfg_reg = (cfg_reg & ~MXC_CSPICTRL_BITCOUNT(31)) | MXC_CSPICTRL_BITCOUNT(bitlen - 1); - reg_write(spi_base + MXC_CSPICTRL, cfg_reg); + reg_write(mxcs->base + MXC_CSPICTRL, cfg_reg); } - reg_write(spi_base + MXC_CSPITXDATA, data); + reg_write(mxcs->base + MXC_CSPITXDATA, data); cfg_reg |= MXC_CSPICTRL_XCH; - reg_write(spi_base + MXC_CSPICTRL, cfg_reg); + reg_write(mxcs->base + MXC_CSPICTRL, cfg_reg); - while (reg_read(spi_base + MXC_CSPICTRL) & MXC_CSPICTRL_XCH) + while (reg_read(mxcs->base + MXC_CSPICTRL) & MXC_CSPICTRL_XCH) ; - return reg_read(spi_base + MXC_CSPIRXDATA); + return reg_read(mxcs->base + MXC_CSPIRXDATA); } -int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) { int n_blks = (bitlen + 31) / 32; u32 *out_l, *in_l; @@ -117,13 +120,10 @@ int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din) return 1; } - if (!spi_base) - spi_select(CONFIG_MXC_SPI_IFACE, (int)chipsel, SPI_MODE_2 | SPI_CS_HIGH); - for (i = 0, in_l = (u32 *)din, out_l = (u32 *)dout; i < n_blks; i++, in_l++, out_l++, bitlen -= 32) - *in_l = spi_xchg_single(*out_l, bitlen); + *in_l = spi_xchg_single(slave, *out_l, bitlen); return 0; } @@ -132,17 +132,17 @@ void spi_init(void) { } -int spi_select(unsigned int bus, unsigned int dev, unsigned long mode) +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) { unsigned int ctrl_reg; + struct mxc_spi_slave *mxcs; if (bus >= sizeof(spi_bases) / sizeof(spi_bases[0]) || - dev > 3) - return 1; - - spi_base = spi_bases[bus]; + cs > 3) + return NULL; - ctrl_reg = MXC_CSPICTRL_CHIPSELECT(dev) | + ctrl_reg = MXC_CSPICTRL_CHIPSELECT(cs) | MXC_CSPICTRL_BITCOUNT(31) | MXC_CSPICTRL_DATARATE(7) | /* FIXME: calculate data rate */ MXC_CSPICTRL_EN | @@ -155,12 +155,38 @@ int spi_select(unsigned int bus, unsigned int dev, unsigned long mode) if (mode & SPI_CS_HIGH) ctrl_reg |= MXC_CSPICTRL_SSPOL; - reg_write(spi_base + MXC_CSPIRESET, 1); + mxcs = malloc(sizeof(struct mxc_spi_slave)); + if (!mxcs) + return NULL; + + mxcs->slave.bus = bus; + mxcs->slave.cs = cs; + mxcs->base = spi_bases[bus]; + mxcs->ctrl_reg = ctrl_reg; + + return &mxcs->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave); + + reg_write(mxcs->base + MXC_CSPIRESET, 1); udelay(1); - reg_write(spi_base + MXC_CSPICTRL, ctrl_reg); - reg_write(spi_base + MXC_CSPIPERIOD, + reg_write(mxcs->base + MXC_CSPICTRL, mxcs->ctrl_reg); + reg_write(mxcs->base + MXC_CSPIPERIOD, MXC_CSPIPERIOD_32KHZ); - reg_write(spi_base + MXC_CSPIINT, 0); + reg_write(mxcs->base + MXC_CSPIINT, 0); return 0; } + +void spi_release_bus(struct spi_slave *slave) +{ + /* TODO: Shut the controller down */ +} diff --git a/include/configs/imx31_litekit.h b/include/configs/imx31_litekit.h index 4281d73c90b..ec4ed1eeb67 100644 --- a/include/configs/imx31_litekit.h +++ b/include/configs/imx31_litekit.h @@ -65,7 +65,8 @@ #define CONFIG_HARD_SPI 1 #define CONFIG_MXC_SPI 1 -#define CONFIG_MXC_SPI_IFACE 1 +#define CONFIG_DEFAULT_SPI_BUS 1 +#define CONFIG_DEFAULT_SPI_MODE (SPI_MODE_2 | SPI_CS_HIGH) #define CONFIG_RTC_MC13783 1 diff --git a/include/configs/mx31ads.h b/include/configs/mx31ads.h index 2ea48a6da9a..37ba872a439 100644 --- a/include/configs/mx31ads.h +++ b/include/configs/mx31ads.h @@ -62,7 +62,8 @@ #define CONFIG_HARD_SPI 1 #define CONFIG_MXC_SPI 1 -#define CONFIG_MXC_SPI_IFACE 1 /* Default SPI interface number */ +#define CONFIG_DEFAULT_SPI_BUS 1 +#define CONFIG_DEFAULT_SPI_MODE (SPI_MODE_2 | SPI_CS_HIGH) #define CONFIG_RTC_MC13783 1 diff --git a/include/spi.h b/include/spi.h index 3a55a68c4d1..7744c2e36b0 100644 --- a/include/spi.h +++ b/include/spi.h @@ -31,22 +31,87 @@ #define SPI_MODE_1 (0|SPI_CPHA) #define SPI_MODE_2 (SPI_CPOL|0) #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) -#define SPI_CS_HIGH 0x04 /* chipselect active high? */ +#define SPI_CS_HIGH 0x04 /* CS active high */ #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ #define SPI_3WIRE 0x10 /* SI/SO signals shared */ #define SPI_LOOP 0x20 /* loopback mode */ -/* - * The function call pointer type used to drive the chip select. - */ -typedef void (*spi_chipsel_type)(int cs); +/* SPI transfer flags */ +#define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */ +#define SPI_XFER_END 0x02 /* Deassert CS after transfer */ +/*----------------------------------------------------------------------- + * Representation of a SPI slave, i.e. what we're communicating with. + * + * Drivers are expected to extend this with controller-specific data. + * + * bus: ID of the bus that the slave is attached to. + * cs: ID of the chip select connected to the slave. + */ +struct spi_slave { + unsigned int bus; + unsigned int cs; +}; /*----------------------------------------------------------------------- * Initialization, must be called once on start up. + * + * TODO: I don't think we really need this. */ void spi_init(void); +/*----------------------------------------------------------------------- + * Set up communications parameters for a SPI slave. + * + * This must be called once for each slave. Note that this function + * usually doesn't touch any actual hardware, it only initializes the + * contents of spi_slave so that the hardware can be easily + * initialized later. + * + * bus: Bus ID of the slave chip. + * cs: Chip select ID of the slave chip on the specified bus. + * max_hz: Maximum SCK rate in Hz. + * mode: Clock polarity, clock phase and other parameters. + * + * Returns: A spi_slave reference that can be used in subsequent SPI + * calls, or NULL if one or more of the parameters are not supported. + */ +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode); + +/*----------------------------------------------------------------------- + * Free any memory associated with a SPI slave. + * + * slave: The SPI slave + */ +void spi_free_slave(struct spi_slave *slave); + +/*----------------------------------------------------------------------- + * Claim the bus and prepare it for communication with a given slave. + * + * This must be called before doing any transfers with a SPI slave. It + * will enable and initialize any SPI hardware as necessary, and make + * sure that the SCK line is in the correct idle state. It is not + * allowed to claim the same bus for several slaves without releasing + * the bus in between. + * + * slave: The SPI slave + * + * Returns: 0 if the bus was claimed successfully, or a negative value + * if it wasn't. + */ +int spi_claim_bus(struct spi_slave *slave); + +/*----------------------------------------------------------------------- + * Release the SPI bus + * + * This must be called once for every call to spi_claim_bus() after + * all transfers have finished. It may disable any SPI hardware as + * appropriate. + * + * slave: The SPI slave + */ +void spi_release_bus(struct spi_slave *slave); /*----------------------------------------------------------------------- * SPI transfer @@ -60,28 +125,67 @@ void spi_init(void); * input data overwrites the output data (since both are buffered by * temporary variables, this is OK). * - * If the chipsel() function is not NULL, it is called with a parameter - * of '1' (chip select active) at the start of the transfer and again with - * a parameter of '0' at the end of the transfer. - * - * If the chipsel() function _is_ NULL, it the responsibility of the - * caller to make the appropriate chip select active before calling - * spi_xfer() and making it inactive after spi_xfer() returns. - * * spi_xfer() interface: - * chipsel: Routine to call to set/clear the chip select: - * if chipsel is NULL, it is not used. - * if(cs), make the chip select active (typically '0'). - * if(!cs), make the chip select inactive (typically '1'). - * dout: Pointer to a string of bits to send out. The bits are - * held in a byte array and are sent MSB first. - * din: Pointer to a string of bits that will be filled in. - * bitlen: How many bits to write and read. + * slave: The SPI slave which will be sending/receiving the data. + * bitlen: How many bits to write and read. + * dout: Pointer to a string of bits to send out. The bits are + * held in a byte array and are sent MSB first. + * din: Pointer to a string of bits that will be filled in. + * flags: A bitwise combination of SPI_XFER_* flags. * * Returns: 0 on success, not 0 on failure */ -int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din); +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags); + +/*----------------------------------------------------------------------- + * Determine if a SPI chipselect is valid. + * This function is provided by the board if the low-level SPI driver + * needs it to determine if a given chipselect is actually valid. + * + * Returns: 1 if bus:cs identifies a valid chip on this board, 0 + * otherwise. + */ +int spi_cs_is_valid(unsigned int bus, unsigned int cs); + +/*----------------------------------------------------------------------- + * Activate a SPI chipselect. + * This function is provided by the board code when using a driver + * that can't control its chipselects automatically (e.g. + * common/soft_spi.c). When called, it should activate the chip select + * to the device identified by "slave". + */ +void spi_cs_activate(struct spi_slave *slave); + +/*----------------------------------------------------------------------- + * Deactivate a SPI chipselect. + * This function is provided by the board code when using a driver + * that can't control its chipselects automatically (e.g. + * common/soft_spi.c). When called, it should deactivate the chip + * select to the device identified by "slave". + */ +void spi_cs_deactivate(struct spi_slave *slave); + +/*----------------------------------------------------------------------- + * Write 8 bits, then read 8 bits. + * slave: The SPI slave we're communicating with + * byte: Byte to be written + * + * Returns: The value that was read, or a negative value on error. + * + * TODO: This function probably shouldn't be inlined. + */ +static inline int spi_w8r8(struct spi_slave *slave, unsigned char byte) +{ + unsigned char dout[2]; + unsigned char din[2]; + int ret; + + dout[0] = byte; + dout[1] = 0; -int spi_select(unsigned int bus, unsigned int dev, unsigned long mode); + ret = spi_xfer(slave, 16, dout, din, SPI_XFER_BEGIN | SPI_XFER_END); + return ret < 0 ? ret : din[1]; +} #endif /* _SPI_H_ */ -- cgit v1.3.1 From 60445cb5c3eb77ed1a07f2d908eef09174483698 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Fri, 16 May 2008 11:10:32 +0200 Subject: atmel_spi: Driver for the Atmel SPI controller This adds a driver for the SPI controller found on most AT91 and AVR32 chips, implementing the new SPI API. Changed in v4: - Update to new API - Handle zero-length transfers appropriately. The user may send a zero-length SPI transfer with SPI_XFER_END set in order to deactivate the chip select after a series of transfers with chip select active. This is useful e.g. when polling the status register of DataFlash. Signed-off-by: Haavard Skinnemoen --- cpu/at32ap/at32ap700x/gpio.c | 43 +++++ drivers/spi/Makefile | 1 + drivers/spi/atmel_spi.c | 210 ++++++++++++++++++++++ drivers/spi/atmel_spi.h | 95 ++++++++++ include/asm-avr32/arch-at32ap700x/chip-features.h | 1 + include/asm-avr32/arch-at32ap700x/clk.h | 6 + include/asm-avr32/arch-at32ap700x/gpio.h | 4 + 7 files changed, 360 insertions(+) create mode 100644 drivers/spi/atmel_spi.c create mode 100644 drivers/spi/atmel_spi.h (limited to 'cpu') diff --git a/cpu/at32ap/at32ap700x/gpio.c b/cpu/at32ap/at32ap700x/gpio.c index 859124a91f6..3da35d4fe23 100644 --- a/cpu/at32ap/at32ap700x/gpio.c +++ b/cpu/at32ap/at32ap700x/gpio.c @@ -21,8 +21,11 @@ */ #include +#include + #include #include +#include /* * Lots of small functions here. We depend on --gc-sections getting @@ -142,3 +145,43 @@ void gpio_enable_mmci(void) gpio_select_periph_A(GPIO_PIN_PA15, 0); /* DATA3 */ } #endif + +#ifdef AT32AP700x_CHIP_HAS_SPI +void gpio_enable_spi0(unsigned long cs_mask) +{ + u32 pa_mask = 0; + + gpio_select_periph_A(GPIO_PIN_PA0, 0); /* MISO */ + gpio_select_periph_A(GPIO_PIN_PA1, 0); /* MOSI */ + gpio_select_periph_A(GPIO_PIN_PA2, 0); /* SCK */ + + if (cs_mask & (1 << 0)) + pa_mask |= 1 << 3; /* NPCS0 */ + if (cs_mask & (1 << 1)) + pa_mask |= 1 << 4; /* NPCS1 */ + if (cs_mask & (1 << 2)) + pa_mask |= 1 << 5; /* NPCS2 */ + if (cs_mask & (1 << 3)) + pa_mask |= 1 << 20; /* NPCS3 */ + + __raw_writel(pa_mask, PIOA_BASE + 0x00); + __raw_writel(pa_mask, PIOA_BASE + 0x30); + __raw_writel(pa_mask, PIOA_BASE + 0x10); +} + +void gpio_enable_spi1(unsigned long cs_mask) +{ + gpio_select_periph_B(GPIO_PIN_PA0, 0); /* MISO */ + gpio_select_periph_B(GPIO_PIN_PB1, 0); /* MOSI */ + gpio_select_periph_B(GPIO_PIN_PB5, 0); /* SCK */ + + if (cs_mask & (1 << 0)) + gpio_select_periph_B(GPIO_PIN_PB2, 0); /* NPCS0 */ + if (cs_mask & (1 << 1)) + gpio_select_periph_B(GPIO_PIN_PB3, 0); /* NPCS1 */ + if (cs_mask & (1 << 2)) + gpio_select_periph_B(GPIO_PIN_PB4, 0); /* NPCS2 */ + if (cs_mask & (1 << 3)) + gpio_select_periph_A(GPIO_PIN_PA27, 0); /* NPCS3 */ +} +#endif diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index bc8a1041210..e66e0ee092f 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libspi.a COBJS-y += mpc8xxx_spi.o +COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS := $(COBJS-y) diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c new file mode 100644 index 00000000000..317c0b41b6f --- /dev/null +++ b/drivers/spi/atmel_spi.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2007 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 + */ +#include +#include +#include + +#include + +#include +#include + +#include "atmel_spi.h" + +void spi_init() +{ + +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct atmel_spi_slave *as; + unsigned int scbr; + u32 csrx; + void *regs; + + if (cs > 3 || !spi_cs_is_valid(bus, cs)) + return NULL; + + switch (bus) { + case 0: + regs = (void *)SPI0_BASE; + break; +#ifdef SPI1_BASE + case 1: + regs = (void *)SPI1_BASE; + break; +#endif +#ifdef SPI2_BASE + case 2: + regs = (void *)SPI2_BASE; + break; +#endif +#ifdef SPI3_BASE + case 3: + regs = (void *)SPI3_BASE; + break; +#endif + default: + return NULL; + } + + + scbr = (get_spi_clk_rate(bus) + max_hz - 1) / max_hz; + if (scbr > ATMEL_SPI_CSRx_SCBR_MAX) + /* Too low max SCK rate */ + return NULL; + if (scbr < 1) + scbr = 1; + + csrx = ATMEL_SPI_CSRx_SCBR(scbr); + csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8); + if (!(mode & SPI_CPHA)) + csrx |= ATMEL_SPI_CSRx_NCPHA; + if (mode & SPI_CPOL) + csrx |= ATMEL_SPI_CSRx_CPOL; + + as = malloc(sizeof(struct atmel_spi_slave)); + if (!as) + return NULL; + + as->slave.bus = bus; + as->slave.cs = cs; + as->regs = regs; + as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS + | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf); + spi_writel(as, CSR(cs), csrx); + + return &as->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct atmel_spi_slave *as = to_atmel_spi(slave); + + free(as); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + struct atmel_spi_slave *as = to_atmel_spi(slave); + + /* Enable the SPI hardware */ + spi_writel(as, CR, ATMEL_SPI_CR_SPIEN); + + /* + * Select the slave. This should set SCK to the correct + * initial state, etc. + */ + spi_writel(as, MR, as->mr); + + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + struct atmel_spi_slave *as = to_atmel_spi(slave); + + /* Disable the SPI hardware */ + spi_writel(as, CR, ATMEL_SPI_CR_SPIDIS); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct atmel_spi_slave *as = to_atmel_spi(slave); + unsigned int len_tx; + unsigned int len_rx; + unsigned int len; + int ret; + u32 status; + const u8 *txp = dout; + u8 *rxp = din; + u8 value; + + ret = 0; + if (bitlen == 0) + /* Finish any previously submitted transfers */ + goto out; + + /* + * TODO: The controller can do non-multiple-of-8 bit + * transfers, but this driver currently doesn't support it. + * + * It's also not clear how such transfers are supposed to be + * represented as a stream of bytes...this is a limitation of + * the current SPI interface. + */ + if (bitlen % 8) { + /* Errors always terminate an ongoing transfer */ + flags |= SPI_XFER_END; + goto out; + } + + len = bitlen / 8; + + /* + * The controller can do automatic CS control, but it is + * somewhat quirky, and it doesn't really buy us much anyway + * in the context of U-Boot. + */ + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + for (len_tx = 0, len_rx = 0; len_rx < len; ) { + status = spi_readl(as, SR); + + if (status & ATMEL_SPI_SR_OVRES) + return -1; + + if (len_tx < len && (status & ATMEL_SPI_SR_TDRE)) { + if (txp) + value = *txp++; + else + value = 0; + spi_writel(as, TDR, value); + len_tx++; + } + if (status & ATMEL_SPI_SR_RDRF) { + value = spi_readl(as, RDR); + if (rxp) + *rxp++ = value; + len_rx++; + } + } + +out: + if (flags & SPI_XFER_END) { + /* + * Wait until the transfer is completely done before + * we deactivate CS. + */ + do { + status = spi_readl(as, SR); + } while (!(status & ATMEL_SPI_SR_TXEMPTY)); + + spi_cs_deactivate(slave); + } + + return 0; +} diff --git a/drivers/spi/atmel_spi.h b/drivers/spi/atmel_spi.h new file mode 100644 index 00000000000..8b69a6d2159 --- /dev/null +++ b/drivers/spi/atmel_spi.h @@ -0,0 +1,95 @@ +/* + * Register definitions for the Atmel AT32/AT91 SPI Controller + */ + +/* Register offsets */ +#define ATMEL_SPI_CR 0x0000 +#define ATMEL_SPI_MR 0x0004 +#define ATMEL_SPI_RDR 0x0008 +#define ATMEL_SPI_TDR 0x000c +#define ATMEL_SPI_SR 0x0010 +#define ATMEL_SPI_IER 0x0014 +#define ATMEL_SPI_IDR 0x0018 +#define ATMEL_SPI_IMR 0x001c +#define ATMEL_SPI_CSR(x) (0x0030 + 4 * (x)) +#define ATMEL_SPI_VERSION 0x00fc + +/* Bits in CR */ +#define ATMEL_SPI_CR_SPIEN (1 << 0) +#define ATMEL_SPI_CR_SPIDIS (1 << 1) +#define ATMEL_SPI_CR_SWRST (1 << 7) +#define ATMEL_SPI_CR_LASTXFER (1 << 24) + +/* Bits in MR */ +#define ATMEL_SPI_MR_MSTR (1 << 0) +#define ATMEL_SPI_MR_PS (1 << 1) +#define ATMEL_SPI_MR_PCSDEC (1 << 2) +#define ATMEL_SPI_MR_FDIV (1 << 3) +#define ATMEL_SPI_MR_MODFDIS (1 << 4) +#define ATMEL_SPI_MR_LLB (1 << 7) +#define ATMEL_SPI_MR_PCS(x) (((x) & 15) << 16) +#define ATMEL_SPI_MR_DLYBCS(x) ((x) << 24) + +/* Bits in RDR */ +#define ATMEL_SPI_RDR_RD(x) (x) +#define ATMEL_SPI_RDR_PCS(x) ((x) << 16) + +/* Bits in TDR */ +#define ATMEL_SPI_TDR_TD(x) (x) +#define ATMEL_SPI_TDR_PCS(x) ((x) << 16) +#define ATMEL_SPI_TDR_LASTXFER (1 << 24) + +/* Bits in SR/IER/IDR/IMR */ +#define ATMEL_SPI_SR_RDRF (1 << 0) +#define ATMEL_SPI_SR_TDRE (1 << 1) +#define ATMEL_SPI_SR_MODF (1 << 2) +#define ATMEL_SPI_SR_OVRES (1 << 3) +#define ATMEL_SPI_SR_ENDRX (1 << 4) +#define ATMEL_SPI_SR_ENDTX (1 << 5) +#define ATMEL_SPI_SR_RXBUFF (1 << 6) +#define ATMEL_SPI_SR_TXBUFE (1 << 7) +#define ATMEL_SPI_SR_NSSR (1 << 8) +#define ATMEL_SPI_SR_TXEMPTY (1 << 9) +#define ATMEL_SPI_SR_SPIENS (1 << 16) + +/* Bits in CSRx */ +#define ATMEL_SPI_CSRx_CPOL (1 << 0) +#define ATMEL_SPI_CSRx_NCPHA (1 << 1) +#define ATMEL_SPI_CSRx_CSAAT (1 << 3) +#define ATMEL_SPI_CSRx_BITS(x) ((x) << 4) +#define ATMEL_SPI_CSRx_SCBR(x) ((x) << 8) +#define ATMEL_SPI_CSRx_SCBR_MAX 0xff +#define ATMEL_SPI_CSRx_DLYBS(x) ((x) << 16) +#define ATMEL_SPI_CSRx_DLYBCT(x) ((x) << 24) + +/* Bits in VERSION */ +#define ATMEL_SPI_VERSION_REV(x) ((x) << 0) +#define ATMEL_SPI_VERSION_MFN(x) ((x) << 16) + +/* Constants for CSRx:BITS */ +#define ATMEL_SPI_BITS_8 0 +#define ATMEL_SPI_BITS_9 1 +#define ATMEL_SPI_BITS_10 2 +#define ATMEL_SPI_BITS_11 3 +#define ATMEL_SPI_BITS_12 4 +#define ATMEL_SPI_BITS_13 5 +#define ATMEL_SPI_BITS_14 6 +#define ATMEL_SPI_BITS_15 7 +#define ATMEL_SPI_BITS_16 8 + +struct atmel_spi_slave { + struct spi_slave slave; + void *regs; + u32 mr; +}; + +static inline struct atmel_spi_slave *to_atmel_spi(struct spi_slave *slave) +{ + return container_of(slave, struct atmel_spi_slave, slave); +} + +/* Register access macros */ +#define spi_readl(as, reg) \ + readl(as->regs + ATMEL_SPI_##reg) +#define spi_writel(as, reg, value) \ + writel(value, as->regs + ATMEL_SPI_##reg) diff --git a/include/asm-avr32/arch-at32ap700x/chip-features.h b/include/asm-avr32/arch-at32ap700x/chip-features.h index 29b1fd663d0..c47107e2a64 100644 --- a/include/asm-avr32/arch-at32ap700x/chip-features.h +++ b/include/asm-avr32/arch-at32ap700x/chip-features.h @@ -25,6 +25,7 @@ /* Currently, all the AP700x chips have these */ #define AT32AP700x_CHIP_HAS_USART #define AT32AP700x_CHIP_HAS_MMCI +#define AT32AP700x_CHIP_HAS_SPI /* Only AP7000 has ethernet interface */ #ifdef CONFIG_AT32AP7000 diff --git a/include/asm-avr32/arch-at32ap700x/clk.h b/include/asm-avr32/arch-at32ap700x/clk.h index 4a1dd33b56b..a9d8431a66c 100644 --- a/include/asm-avr32/arch-at32ap700x/clk.h +++ b/include/asm-avr32/arch-at32ap700x/clk.h @@ -74,6 +74,12 @@ static inline unsigned long get_mci_clk_rate(void) return get_pbb_clk_rate(); } #endif +#ifdef AT32AP700x_CHIP_HAS_SPI +static inline unsigned long get_spi_clk_rate(unsigned int dev_id) +{ + return get_pba_clk_rate(); +} +#endif extern void clk_init(void); diff --git a/include/asm-avr32/arch-at32ap700x/gpio.h b/include/asm-avr32/arch-at32ap700x/gpio.h index b10a3e4f868..ef20ceaab7c 100644 --- a/include/asm-avr32/arch-at32ap700x/gpio.h +++ b/include/asm-avr32/arch-at32ap700x/gpio.h @@ -216,5 +216,9 @@ void gpio_enable_macb1(void); #ifdef AT32AP700x_CHIP_HAS_MMCI void gpio_enable_mmci(void); #endif +#ifdef AT32AP700x_CHIP_HAS_SPI +void gpio_enable_spi0(unsigned long cs_mask); +void gpio_enable_spi1(unsigned long cs_mask); +#endif #endif /* __ASM_AVR32_ARCH_GPIO_H__ */ -- cgit v1.3.1 From 22f371b63038a4ecab04068877c1089e51a01ba1 Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Wed, 21 May 2008 13:28:30 -0700 Subject: PPC4xx: Simplified post_word_{load, store} This patch simplifies post_word_{load,store} by using the preprocessor to eliminate redundant, copy-and-pasted code. Signed-off-by: Grant Erickson --- cpu/ppc4xx/commproc.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'cpu') diff --git a/cpu/ppc4xx/commproc.c b/cpu/ppc4xx/commproc.c index 22156dd9ded..8b2954c16cc 100644 --- a/cpu/ppc4xx/commproc.c +++ b/cpu/ppc4xx/commproc.c @@ -30,29 +30,25 @@ #if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) -#if defined(CFG_POST_ALT_WORD_ADDR) -void post_word_store (ulong a) -{ - out_be32((void *)CFG_POST_ALT_WORD_ADDR, a); -} +#if defined(CFG_POST_WORD_ADDR) +# define _POST_ADDR ((CFG_OCM_DATA_ADDR) + (CFG_POST_WORD_ADDR)) +#elif defined(CFG_POST_ALT_WORD_ADDR) +# define _POST_ADDR (CFG_POST_ALT_WORD_ADDR) +#endif -ulong post_word_load (void) -{ - return in_be32((void *)CFG_POST_ALT_WORD_ADDR); -} -#else /* CFG_POST_ALT_WORD_ADDR */ void post_word_store (ulong a) { - volatile void *save_addr = (volatile void *)(CFG_OCM_DATA_ADDR + CFG_POST_WORD_ADDR); - *(volatile ulong *) save_addr = a; + volatile void *save_addr = (volatile void *)(_POST_ADDR); + + out_be32(save_addr, a); } ulong post_word_load (void) { - volatile void *save_addr = (volatile void *)(CFG_OCM_DATA_ADDR + CFG_POST_WORD_ADDR); - return *(volatile ulong *) save_addr; + volatile void *save_addr = (volatile void *)(_POST_ADDR); + + return in_be32(save_addr); } -#endif /* CFG_POST_ALT_WORD_ADDR */ #endif /* CONFIG_POST || CONFIG_LOGBUFFER*/ -- cgit v1.3.1