diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/cfi_flash.c | 5 | ||||
-rw-r--r-- | drivers/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/serial/at91rm9200_usart.c | 118 | ||||
-rw-r--r-- | drivers/serial/atmel_usart.c | 4 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/atmel_dataflash_spi.c | 157 | ||||
-rw-r--r-- | drivers/usb/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/atmel_usb.c | 80 | ||||
-rw-r--r-- | drivers/watchdog/Makefile | 46 | ||||
-rw-r--r-- | drivers/watchdog/at91sam9_wdt.c | 79 |
10 files changed, 487 insertions, 5 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 631b969..175d82a 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -1788,13 +1788,10 @@ static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry) /* AT49BV6416(T) list the erase regions in the wrong order. * However, the device ID is identical with the non-broken - * AT49BV642D since u-boot only reads the low byte (they - * differ in the high byte.) So leave out this fixup for now. + * AT49BV642D they differ in the high byte. */ -#if 0 if (info->device_id == 0xd6 || info->device_id == 0xd2) reverse_geometry = !reverse_geometry; -#endif if (reverse_geometry) cfi_reverse_geometry(qry); diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 696d5fb..bb99a34 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libserial.a COBJS-$(CONFIG_ARM_DCC) += arm_dcc.o +COBJS-$(CONFIG_AT91RM9200_USART) += at91rm9200_usart.o COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o COBJS-$(CONFIG_MCFUART) += mcfuart.o COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o diff --git a/drivers/serial/at91rm9200_usart.c b/drivers/serial/at91rm9200_usart.c new file mode 100644 index 0000000..858bde9 --- /dev/null +++ b/drivers/serial/at91rm9200_usart.c @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc <www.lineo.com> + * Bernhard Kuhn <bkuhn@lineo.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if !defined(CONFIG_DBGU) && !defined(CONFIG_USART0) && !defined(CONFIG_USART1) +#error must define one of CONFIG_DBGU or CONFIG_USART0 or CONFIG_USART1 +#endif + +/* ggi thunder */ +#ifdef CONFIG_DBGU +AT91PS_USART us = (AT91PS_USART) AT91C_BASE_DBGU; +#endif +#ifdef CONFIG_USART0 +AT91PS_USART us = (AT91PS_USART) AT91C_BASE_US0; +#endif +#ifdef CONFIG_USART1 +AT91PS_USART us = (AT91PS_USART) AT91C_BASE_US1; +#endif + +void serial_setbrg (void) +{ + int baudrate; + + if ((baudrate = gd->baudrate) <= 0) + baudrate = CONFIG_BAUDRATE; + /* MASTER_CLOCK/(16 * baudrate) */ + us->US_BRGR = (AT91C_MASTER_CLOCK >> 4) / (unsigned)baudrate; +} + +int serial_init (void) +{ + /* make any port initializations specific to this port */ +#ifdef CONFIG_DBGU + *AT91C_PIOA_PDR = AT91C_PA31_DTXD | AT91C_PA30_DRXD; /* PA 31 & 30 */ + *AT91C_PMC_PCER = 1 << AT91C_ID_SYS; /* enable clock */ +#endif +#ifdef CONFIG_USART0 + *AT91C_PIOA_PDR = AT91C_PA17_TXD0 | AT91C_PA18_RXD0; + *AT91C_PMC_PCER |= 1 << AT91C_ID_USART0; /* enable clock */ +#endif +#ifdef CONFIG_USART1 + *AT91C_PIOB_PDR = AT91C_PB21_TXD1 | AT91C_PB20_RXD1; + *AT91C_PMC_PCER |= 1 << AT91C_ID_USART1; /* enable clock */ +#endif + serial_setbrg (); + + us->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX; + us->US_CR = AT91C_US_RXEN | AT91C_US_TXEN; + us->US_MR = + (AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS | + AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT); + us->US_IMR = ~0ul; + return (0); +} + +void serial_exit (void) +{ + us->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX); +} + +void serial_putc (const char c) +{ + if (c == '\n') + serial_putc ('\r'); + while ((us->US_CSR & AT91C_US_TXRDY) == 0); + us->US_THR = c; +} + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +int serial_getc (void) +{ + while ((us->US_CSR & AT91C_US_RXRDY) == 0); + return us->US_RHR; +} + +int serial_tstc (void) +{ + return ((us->US_CSR & AT91C_US_RXRDY) == AT91C_US_RXRDY); +} diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c index f3b146c..f50552a 100644 --- a/drivers/serial/atmel_usart.c +++ b/drivers/serial/atmel_usart.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <common.h> +#include <watchdog.h> #include <asm/io.h> #include <asm/arch/clk.h> @@ -87,7 +88,8 @@ void serial_puts(const char *s) int serial_getc(void) { - while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) ; + while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) + WATCHDOG_RESET(); return usart3_readl(RHR); } diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 6e2c121..1350f3e 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libspi.a +COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o diff --git a/drivers/spi/atmel_dataflash_spi.c b/drivers/spi/atmel_dataflash_spi.c new file mode 100644 index 0000000..3eb252c --- /dev/null +++ b/drivers/spi/atmel_dataflash_spi.c @@ -0,0 +1,157 @@ +/* + * Driver for ATMEL DataFlash support + * Author : Hamid Ikdoumi (Atmel) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/arch/gpio.h> +#include <asm/arch/io.h> +#include <asm/arch/at91_pio.h> +#include <asm/arch/at91_spi.h> + +#include <dataflash.h> + +#define AT91_SPI_PCS0_DATAFLASH_CARD 0xE /* Chip Select 0: NPCS0%1110 */ +#define AT91_SPI_PCS1_DATAFLASH_CARD 0xD /* Chip Select 0: NPCS0%1101 */ +#define AT91_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3: NPCS3%0111 */ + +void AT91F_SpiInit(void) +{ + /* Reset the SPI */ + writel(AT91_SPI_SWRST, AT91_BASE_SPI + AT91_SPI_CR); + + /* Configure SPI in Master Mode with No CS selected !!! */ + writel(AT91_SPI_MSTR | AT91_SPI_MODFDIS | AT91_SPI_PCS, + AT91_BASE_SPI + AT91_SPI_MR); + + /* Configure CS0 */ + writel(AT91_SPI_NCPHA | + (AT91_SPI_DLYBS & DATAFLASH_TCSS) | + (AT91_SPI_DLYBCT & DATAFLASH_TCHS) | + ((AT91_MASTER_CLOCK / AT91_SPI_CLK) << 8), + AT91_BASE_SPI + AT91_SPI_CSR(0)); + +#ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS1 + /* Configure CS1 */ + writel(AT91_SPI_NCPHA | + (AT91_SPI_DLYBS & DATAFLASH_TCSS) | + (AT91_SPI_DLYBCT & DATAFLASH_TCHS) | + ((AT91_MASTER_CLOCK / AT91_SPI_CLK) << 8), + AT91_BASE_SPI + AT91_SPI_CSR(1)); +#endif + +#ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS3 + /* Configure CS3 */ + writel(AT91_SPI_NCPHA | + (AT91_SPI_DLYBS & DATAFLASH_TCSS) | + (AT91_SPI_DLYBCT & DATAFLASH_TCHS) | + ((AT91_MASTER_CLOCK / AT91_SPI_CLK) << 8), + AT91_BASE_SPI + AT91_SPI_CSR(3)); +#endif + + /* SPI_Enable */ + writel(AT91_SPI_SPIEN, AT91_BASE_SPI + AT91_SPI_CR); + + while (!(readl(AT91_BASE_SPI + AT91_SPI_SR) & AT91_SPI_SPIENS)); + + /* + * Add tempo to get SPI in a safe state. + * Should not be needed for new silicon (Rev B) + */ + udelay(500000); + readl(AT91_BASE_SPI + AT91_SPI_SR); + readl(AT91_BASE_SPI + AT91_SPI_RDR); + +} + +void AT91F_SpiEnable(int cs) +{ + unsigned long mode; + + switch (cs) { + case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */ + mode = readl(AT91_BASE_SPI + AT91_SPI_MR); + mode &= 0xFFF0FFFF; + writel(mode | ((AT91_SPI_PCS0_DATAFLASH_CARD<<16) & AT91_SPI_PCS), + AT91_BASE_SPI + AT91_SPI_MR); + break; + case 1: /* Configure SPI CS1 for Serial DataFlash AT45DBxx */ + mode = readl(AT91_BASE_SPI + AT91_SPI_MR); + mode &= 0xFFF0FFFF; + writel(mode | ((AT91_SPI_PCS1_DATAFLASH_CARD<<16) & AT91_SPI_PCS), + AT91_BASE_SPI + AT91_SPI_MR); + break; + case 3: + mode = readl(AT91_BASE_SPI + AT91_SPI_MR); + mode &= 0xFFF0FFFF; + writel(mode | ((AT91_SPI_PCS3_DATAFLASH_CARD<<16) & AT91_SPI_PCS), + AT91_BASE_SPI + AT91_SPI_MR); + break; + } + + /* SPI_Enable */ + writel(AT91_SPI_SPIEN, AT91_BASE_SPI + AT91_SPI_CR); +} + +unsigned int AT91F_SpiWrite1(AT91PS_DataflashDesc pDesc); + +unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc) +{ + unsigned int timeout; + + pDesc->state = BUSY; + + writel(AT91_SPI_TXTDIS + AT91_SPI_RXTDIS, AT91_BASE_SPI + AT91_SPI_PTCR); + + /* Initialize the Transmit and Receive Pointer */ + writel((unsigned int)pDesc->rx_cmd_pt, AT91_BASE_SPI + AT91_SPI_RPR); + writel((unsigned int)pDesc->tx_cmd_pt, AT91_BASE_SPI + AT91_SPI_TPR); + + /* Intialize the Transmit and Receive Counters */ + writel(pDesc->rx_cmd_size, AT91_BASE_SPI + AT91_SPI_RCR); + writel(pDesc->tx_cmd_size, AT91_BASE_SPI + AT91_SPI_TCR); + + if (pDesc->tx_data_size != 0) { + /* Initialize the Next Transmit and Next Receive Pointer */ + writel((unsigned int)pDesc->rx_data_pt, AT91_BASE_SPI + AT91_SPI_RNPR); + writel((unsigned int)pDesc->tx_data_pt, AT91_BASE_SPI + AT91_SPI_TNPR); + + /* Intialize the Next Transmit and Next Receive Counters */ + writel(pDesc->rx_data_size, AT91_BASE_SPI + AT91_SPI_RNCR); + writel(pDesc->tx_data_size, AT91_BASE_SPI + AT91_SPI_TNCR); + } + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked(); + timeout = 0; + + writel(AT91_SPI_TXTEN + AT91_SPI_RXTEN, AT91_BASE_SPI + AT91_SPI_PTCR); + while (!(readl(AT91_BASE_SPI + AT91_SPI_SR) & AT91_SPI_RXBUFF) && + ((timeout = get_timer_masked()) < CONFIG_SYS_SPI_WRITE_TOUT)); + writel(AT91_SPI_TXTDIS + AT91_SPI_RXTDIS, AT91_BASE_SPI + AT91_SPI_PTCR); + pDesc->state = IDLE; + + if (timeout >= CONFIG_SYS_SPI_WRITE_TOUT) { + printf("Error Timeout\n\r"); + return DATAFLASH_ERROR; + } + + return DATAFLASH_OK; +} diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 7ddb72a..5523cbd 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -31,6 +31,7 @@ COBJS-$(CONFIG_USB_OHCI_NEW) += usb_ohci.o COBJS-$(CONFIG_USB_EHCI) += usb_ehci_core.o # host +COBJS-$(CONFIG_USB_ATMEL) += atmel_usb.o COBJS-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o COBJS-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o COBJS-$(CONFIG_USB_S3C64XX) += s3c64xx_usb.o diff --git a/drivers/usb/atmel_usb.c b/drivers/usb/atmel_usb.c new file mode 100644 index 0000000..7c44ad0 --- /dev/null +++ b/drivers/usb/atmel_usb.c @@ -0,0 +1,80 @@ +/* + * (C) Copyright 2006 + * DENX Software Engineering <mk@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) + +#include <asm/arch/hardware.h> +#include <asm/arch/io.h> +#include <asm/arch/at91_pmc.h> + +int usb_cpu_init(void) +{ + +#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ + defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) + /* Enable PLLB */ + at91_sys_write(AT91_CKGR_PLLBR, CONFIG_SYS_AT91_PLLB); + while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB) + ; +#endif + + /* 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; +} + +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 + +#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ + defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) + /* Disable PLLB */ + at91_sys_write(AT91_CKGR_PLLBR, 0); + while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != 0) + ; +#endif + + return 0; +} + +int usb_cpu_init_fail(void) +{ + return usb_cpu_stop(); +} + +#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */ diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile new file mode 100644 index 0000000..200968d --- /dev/null +++ b/drivers/watchdog/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libwatchdog.a + +COBJS-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c new file mode 100644 index 0000000..5bb8b77 --- /dev/null +++ b/drivers/watchdog/at91sam9_wdt.c @@ -0,0 +1,79 @@ +/* + * [origin: Linux kernel drivers/watchdog/at91sam9_wdt.c] + * + * Watchdog driver for Atmel AT91SAM9x processors. + * + * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr + * + * 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. + */ + +/* + * The Watchdog Timer Mode Register can be only written to once. If the + * timeout need to be set from U-Boot, be sure that the bootstrap doesn't + * write to this register. Inform Linux to it too + */ + +#include <common.h> +#include <watchdog.h> +#include <asm/arch/hardware.h> +#include <asm/arch/io.h> +#include <asm/arch/at91_wdt.h> + +/* + * AT91SAM9 watchdog runs a 12bit counter @ 256Hz, + * use this to convert a watchdog + * value from/to milliseconds. + */ +#define ms_to_ticks(t) (((t << 8) / 1000) - 1) +#define ticks_to_ms(t) (((t + 1) * 1000) >> 8) + +/* Hardware timeout in seconds */ +#define WDT_HW_TIMEOUT 2 + +/* + * Set the watchdog time interval in 1/256Hz (write-once) + * Counter is 12 bit. + */ +static int at91_wdt_settimeout(unsigned int timeout) +{ + unsigned int reg; + unsigned int mr; + + /* Check if disabled */ + mr = at91_sys_read(AT91_WDT_MR); + if (mr & AT91_WDT_WDDIS) { + printf("sorry, watchdog is disabled\n"); + return -1; + } + + /* + * All counting occurs at SLOW_CLOCK / 128 = 256 Hz + * + * Since WDV is a 12-bit counter, the maximum period is + * 4096 / 256 = 16 seconds. + */ + reg = AT91_WDT_WDRSTEN /* causes watchdog reset */ + /* | AT91_WDT_WDRPROC causes processor reset only */ + | AT91_WDT_WDDBGHLT /* disabled in debug mode */ + | AT91_WDT_WDD /* restart at any time */ + | (timeout & AT91_WDT_WDV); /* timer value */ + at91_sys_write(AT91_WDT_MR, reg); + + return 0; +} + +void hw_watchdog_reset(void) +{ + at91_sys_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); +} + +void hw_watchdog_init(void) +{ + /* 16 seconds timer, resets enabled */ + at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); +} |