From 10dd5ce28d78e2440e8fa1135d17e33399d75340 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 23 Nov 2006 11:41:32 +0000 Subject: [ARM] Remove compatibility layer for ARM irqs set_irq_chipdata -> set_irq_chip_data get_irq_chipdata -> get_irq_chip_data do_level_IRQ -> handle_level_irq do_edge_IRQ -> handle_edge_irq do_simple_IRQ -> handle_simple_irq irqdesc -> irq_desc irqchip -> irq_chip Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/gpio.c | 8 ++++---- arch/arm/mach-at91rm9200/irq.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c index 7467d644f0a..cec3862651d 100644 --- a/arch/arm/mach-at91rm9200/gpio.c +++ b/arch/arm/mach-at91rm9200/gpio.c @@ -332,10 +332,10 @@ static struct irq_chip gpio_irqchip = { .set_wake = gpio_irq_set_wake, }; -static void gpio_irq_handler(unsigned irq, struct irqdesc *desc) +static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { unsigned pin; - struct irqdesc *gpio; + struct irq_desc *gpio; void __iomem *pio; u32 isr; @@ -396,7 +396,7 @@ void __init at91_gpio_irq_setup(void) __raw_writel(~0, controller + PIO_IDR); set_irq_data(id, (void *) pin); - set_irq_chipdata(id, controller); + set_irq_chip_data(id, controller); for (i = 0; i < 32; i++, pin++) { /* @@ -404,7 +404,7 @@ void __init at91_gpio_irq_setup(void) * shorter, and the AIC handles interupts sanely. */ set_irq_chip(pin, &gpio_irqchip); - set_irq_handler(pin, do_simple_IRQ); + set_irq_handler(pin, handle_simple_irq); set_irq_flags(pin, IRQF_VALID); } diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c index 3e488117ca9..cab0de9b8fa 100644 --- a/arch/arm/mach-at91rm9200/irq.c +++ b/arch/arm/mach-at91rm9200/irq.c @@ -139,7 +139,7 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); set_irq_chip(i, &at91_aic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ -- cgit v1.2.3 From 20127f6863990e1313178debe8c9cfe32d43b1dc Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 09:33:53 +0100 Subject: [ARM] 3945/1: AT91: Rename devices.c This patch renames the arch/arm/mach-at91rm9200/devices.c file to at91rm9200_devices.c. The file contains AT91RM9200-specific code, so we will need separate files for the SAM9 processors. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 4 +- arch/arm/mach-at91rm9200/at91rm9200_devices.c | 813 ++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/devices.c | 813 -------------------------- 3 files changed, 815 insertions(+), 815 deletions(-) create mode 100644 arch/arm/mach-at91rm9200/at91rm9200_devices.c delete mode 100644 arch/arm/mach-at91rm9200/devices.c (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index c174805c24e..568d8d76cde 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := clock.o irq.o gpio.o devices.o +obj-y := clock.o irq.o gpio.o obj-m := obj-n := obj- := @@ -10,7 +10,7 @@ obj- := obj-$(CONFIG_PM) += pm.o # CPU-specific support -obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o +obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c obj-$(CONFIG_ARCH_AT91SAM9260) += obj-$(CONFIG_ARCH_AT91SAM9261) += diff --git a/arch/arm/mach-at91rm9200/at91rm9200_devices.c b/arch/arm/mach-at91rm9200/at91rm9200_devices.c new file mode 100644 index 00000000000..2b3a23605bf --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91rm9200_devices.c @@ -0,0 +1,813 @@ +/* + * arch/arm/mach-at91rm9200/at91rm9200_devices.c + * + * Copyright (C) 2005 Thibaut VARENE + * Copyright (C) 2005 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include + +#include + +#include +#include +#include + +#include "generic.h" + +#define SZ_512 0x00000200 +#define SZ_256 0x00000100 +#define SZ_16 0x00000010 + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = 0xffffffffUL; +static struct at91_usbh_data usbh_data; + +static struct resource at91_usbh_resources[] = { + [0] = { + .start = AT91RM9200_UHP_BASE, + .end = AT91RM9200_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_UHP, + .end = AT91RM9200_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &usbh_data, + }, + .resource = at91_usbh_resources, + .num_resources = ARRAY_SIZE(at91_usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91rm9200_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource at91_udc_resources[] = { + [0] = { + .start = AT91RM9200_BASE_UDP, + .end = AT91RM9200_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_UDP, + .end = AT91RM9200_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = at91_udc_resources, + .num_resources = ARRAY_SIZE(at91_udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + if (data->pullup_pin) + at91_set_gpio_output(data->pullup_pin, 0); + + udc_data = *data; + platform_device_register(&at91rm9200_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) +static u64 eth_dmamask = 0xffffffffUL; +static struct at91_eth_data eth_data; + +static struct resource at91_eth_resources[] = { + [0] = { + .start = AT91_VA_BASE_EMAC, + .end = AT91_VA_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_EMAC, + .end = AT91RM9200_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_eth_device = { + .name = "at91_ether", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = ð_data, + }, + .resource = at91_eth_resources, + .num_resources = ARRAY_SIZE(at91_eth_resources), +}; + +void __init at91_add_device_eth(struct at91_eth_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */ + at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ + + if (!data->is_rmii) { + at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ + at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */ + at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */ + } + + eth_data = *data; + platform_device_register(&at91rm9200_eth_device); +} +#else +void __init at91_add_device_eth(struct at91_eth_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Compact Flash / PCMCIA + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) +static struct at91_cf_data cf_data; + +static struct resource at91_cf_resources[] = { + [0] = { + .start = AT91_CF_BASE, + /* ties up CS4, CS5 and CS6 */ + .end = AT91_CF_BASE + (0x30000000 - 1), + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, + }, +}; + +static struct platform_device at91rm9200_cf_device = { + .name = "at91_cf", + .id = -1, + .dev = { + .platform_data = &cf_data, + }, + .resource = at91_cf_resources, + .num_resources = ARRAY_SIZE(at91_cf_resources), +}; + +void __init at91_add_device_cf(struct at91_cf_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->irq_pin) { + at91_set_gpio_input(data->irq_pin, 1); + at91_set_deglitch(data->irq_pin, 1); + } + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + + /* outputs, initially off */ + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + at91_set_gpio_output(data->rst_pin, 0); + + /* force poweron defaults for these pins ... */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ + at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ + + cf_data = *data; + platform_device_register(&at91rm9200_cf_device); +} +#else +void __init at91_add_device_cf(struct at91_cf_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91RM9200) || defined(CONFIG_MMC_AT91RM9200_MODULE) +static u64 mmc_dmamask = 0xffffffffUL; +static struct at91_mmc_data mmc_data; + +static struct resource at91_mmc_resources[] = { + [0] = { + .start = AT91RM9200_BASE_MCI, + .end = AT91RM9200_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_MCI, + .end = AT91RM9200_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mmc_data, + }, + .resource = at91_mmc_resources, + .num_resources = ARRAY_SIZE(at91_mmc_resources), +}; + +void __init at91_add_device_mmc(struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA27, 0); + + if (data->is_b) { + /* CMD */ + at91_set_B_periph(AT91_PIN_PA8, 0); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA9, 0); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA10, 0); + at91_set_B_periph(AT91_PIN_PA11, 0); + at91_set_B_periph(AT91_PIN_PA12, 0); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA28, 0); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA29, 0); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PB3, 0); + at91_set_B_periph(AT91_PIN_PB4, 0); + at91_set_B_periph(AT91_PIN_PB5, 0); + } + } + + mmc_data = *data; + platform_device_register(&at91rm9200_mmc_device); +} +#else +void __init at91_add_device_mmc(struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) +static struct at91_nand_data nand_data; + +static struct resource at91_nand_resources[] = { + { + .start = AT91_SMARTMEDIA_BASE, + .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91_nand_device = { + .name = "at91_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = at91_nand_resources, + .num_resources = ARRAY_SIZE(at91_nand_resources), +}; + +void __init at91_add_device_nand(struct at91_nand_data *data) +{ + if (!data) + return; + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ + + nand_data = *data; + platform_device_register(&at91_nand_device); +} +#else +void __init at91_add_device_nand(struct at91_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) +static struct platform_device at91rm9200_twi_device = { + .name = "at91_i2c", + .id = -1, + .num_resources = 0, +}; + +void __init at91_add_device_i2c(void) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA25, 1); + + at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA26, 1); + + platform_device_register(&at91rm9200_twi_device); +} +#else +void __init at91_add_device_i2c(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) +static u64 spi_dmamask = 0xffffffffUL; + +static struct resource at91_spi_resources[] = { + [0] = { + .start = AT91RM9200_BASE_SPI, + .end = AT91RM9200_BASE_SPI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_SPI, + .end = AT91RM9200_ID_SPI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_spi_device = { + .name = "at91_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = at91_spi_resources, + .num_resources = ARRAY_SIZE(at91_spi_resources), +}; + +static const unsigned at91_spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + + at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */ + + /* Enable SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else + cs_pin = at91_spi_standard_cs[devices[i].chip_select]; + +#ifdef CONFIG_SPI_AT91_MANUAL_CS + at91_set_gpio_output(cs_pin, 1); +#else + at91_set_A_periph(cs_pin, 0); +#endif + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + at91_clock_associate("spi0_clk", &at91rm9200_spi_device.dev, "spi"); + platform_device_register(&at91rm9200_spi_device); +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * RTC + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_RTC_DRV_AT91) || defined(CONFIG_RTC_DRV_AT91_MODULE) +static struct platform_device at91rm9200_rtc_device = { + .name = "at91_rtc", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_rtc(void) +{ + platform_device_register(&at91rm9200_rtc_device); +} +#else +static void __init at91_add_device_rtc(void) {} +#endif + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91_WATCHDOG) || defined(CONFIG_AT91_WATCHDOG_MODULE) +static struct platform_device at91rm9200_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91rm9200_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * LEDs + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_LEDS) +u8 at91_leds_cpu; +u8 at91_leds_timer; + +void __init at91_init_leds(u8 cpu_led, u8 timer_led) +{ + at91_leds_cpu = cpu_led; + at91_leds_timer = timer_led; +} +#else +void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static struct platform_device at91rm9200_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .platform_data = &dbgu_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US0, + .end = AT91RM9200_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US0, + .end = AT91RM9200_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91rm9200_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .platform_data = &uart0_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ + + /* + * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. + * We need to drive the pin manually. Default is off (RTS is active low). + */ + at91_set_gpio_output(AT91_PIN_PA21, 1); +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US1, + .end = AT91RM9200_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US1, + .end = AT91RM9200_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91rm9200_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .platform_data = &uart1_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ + at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ + at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ + at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ + at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ + at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US2, + .end = AT91RM9200_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US2, + .end = AT91RM9200_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91rm9200_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .platform_data = &uart2_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ +} + +static struct resource uart3_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US3, + .end = AT91RM9200_BASE_US3 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US3, + .end = AT91RM9200_ID_US3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart3_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91rm9200_uart3_device = { + .name = "atmel_usart", + .id = 4, + .dev = { + .platform_data = &uart3_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart3_resources, + .num_resources = ARRAY_SIZE(uart3_resources), +}; + +static inline void configure_usart3_pins(void) +{ + at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ + at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ +} + +struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_init_serial(struct at91_uart_config *config) +{ + int i; + + /* Fill in list of supported UARTs */ + for (i = 0; i < config->nr_tty; i++) { + switch (config->tty_map[i]) { + case 0: + configure_usart0_pins(); + at91_uarts[i] = &at91rm9200_uart0_device; + at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); + break; + case 1: + configure_usart1_pins(); + at91_uarts[i] = &at91rm9200_uart1_device; + at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); + break; + case 2: + configure_usart2_pins(); + at91_uarts[i] = &at91rm9200_uart2_device; + at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); + break; + case 3: + configure_usart3_pins(); + at91_uarts[i] = &at91rm9200_uart3_device; + at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); + break; + case 4: + configure_dbgu_pins(); + at91_uarts[i] = &at91rm9200_dbgu_device; + at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart"); + break; + default: + continue; + } + at91_uarts[i]->id = i; /* update ID number to mapped ID */ + } + + /* Set serial console device */ + if (config->console_tty < ATMEL_MAX_UART) + atmel_default_console_device = at91_uarts[config->console_tty]; + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } +} +#else +void __init at91_init_serial(struct at91_uart_config *config) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ + +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_rtc(); + at91_add_device_watchdog(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c deleted file mode 100644 index 05982437662..00000000000 --- a/arch/arm/mach-at91rm9200/devices.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - * arch/arm/mach-at91rm9200/devices.c - * - * Copyright (C) 2005 Thibaut VARENE - * Copyright (C) 2005 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ -#include -#include - -#include - -#include -#include -#include - -#include "generic.h" - -#define SZ_512 0x00000200 -#define SZ_256 0x00000100 -#define SZ_16 0x00000010 - -/* -------------------------------------------------------------------- - * USB Host - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = 0xffffffffUL; -static struct at91_usbh_data usbh_data; - -static struct resource at91_usbh_resources[] = { - [0] = { - .start = AT91RM9200_UHP_BASE, - .end = AT91RM9200_UHP_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_UHP, - .end = AT91RM9200_ID_UHP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_usbh_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &usbh_data, - }, - .resource = at91_usbh_resources, - .num_resources = ARRAY_SIZE(at91_usbh_resources), -}; - -void __init at91_add_device_usbh(struct at91_usbh_data *data) -{ - if (!data) - return; - - usbh_data = *data; - platform_device_register(&at91rm9200_usbh_device); -} -#else -void __init at91_add_device_usbh(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB Device (Gadget) - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_USB_GADGET_AT91 -static struct at91_udc_data udc_data; - -static struct resource at91_udc_resources[] = { - [0] = { - .start = AT91RM9200_BASE_UDP, - .end = AT91RM9200_BASE_UDP + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_UDP, - .end = AT91RM9200_ID_UDP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_udc_device = { - .name = "at91_udc", - .id = -1, - .dev = { - .platform_data = &udc_data, - }, - .resource = at91_udc_resources, - .num_resources = ARRAY_SIZE(at91_udc_resources), -}; - -void __init at91_add_device_udc(struct at91_udc_data *data) -{ - if (!data) - return; - - if (data->vbus_pin) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - } - if (data->pullup_pin) - at91_set_gpio_output(data->pullup_pin, 0); - - udc_data = *data; - platform_device_register(&at91rm9200_udc_device); -} -#else -void __init at91_add_device_udc(struct at91_udc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) -static u64 eth_dmamask = 0xffffffffUL; -static struct at91_eth_data eth_data; - -static struct resource at91_eth_resources[] = { - [0] = { - .start = AT91_VA_BASE_EMAC, - .end = AT91_VA_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_EMAC, - .end = AT91RM9200_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_eth_device = { - .name = "at91_ether", - .id = -1, - .dev = { - .dma_mask = ð_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = ð_data, - }, - .resource = at91_eth_resources, - .num_resources = ARRAY_SIZE(at91_eth_resources), -}; - -void __init at91_add_device_eth(struct at91_eth_data *data) -{ - if (!data) - return; - - if (data->phy_irq_pin) { - at91_set_gpio_input(data->phy_irq_pin, 0); - at91_set_deglitch(data->phy_irq_pin, 1); - } - - /* Pins used for MII and RMII */ - at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */ - at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */ - at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */ - at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ - at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ - at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */ - at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */ - at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */ - at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ - at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ - - if (!data->is_rmii) { - at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ - at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ - at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ - at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */ - at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */ - at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */ - at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */ - at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */ - } - - eth_data = *data; - platform_device_register(&at91rm9200_eth_device); -} -#else -void __init at91_add_device_eth(struct at91_eth_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Compact Flash / PCMCIA - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) -static struct at91_cf_data cf_data; - -static struct resource at91_cf_resources[] = { - [0] = { - .start = AT91_CF_BASE, - /* ties up CS4, CS5 and CS6 */ - .end = AT91_CF_BASE + (0x30000000 - 1), - .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, - }, -}; - -static struct platform_device at91rm9200_cf_device = { - .name = "at91_cf", - .id = -1, - .dev = { - .platform_data = &cf_data, - }, - .resource = at91_cf_resources, - .num_resources = ARRAY_SIZE(at91_cf_resources), -}; - -void __init at91_add_device_cf(struct at91_cf_data *data) -{ - if (!data) - return; - - /* input/irq */ - if (data->irq_pin) { - at91_set_gpio_input(data->irq_pin, 1); - at91_set_deglitch(data->irq_pin, 1); - } - at91_set_gpio_input(data->det_pin, 1); - at91_set_deglitch(data->det_pin, 1); - - /* outputs, initially off */ - if (data->vcc_pin) - at91_set_gpio_output(data->vcc_pin, 0); - at91_set_gpio_output(data->rst_pin, 0); - - /* force poweron defaults for these pins ... */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ - at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ - at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ - at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ - - cf_data = *data; - platform_device_register(&at91rm9200_cf_device); -} -#else -void __init at91_add_device_cf(struct at91_cf_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MMC_AT91RM9200) || defined(CONFIG_MMC_AT91RM9200_MODULE) -static u64 mmc_dmamask = 0xffffffffUL; -static struct at91_mmc_data mmc_data; - -static struct resource at91_mmc_resources[] = { - [0] = { - .start = AT91RM9200_BASE_MCI, - .end = AT91RM9200_BASE_MCI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_MCI, - .end = AT91RM9200_ID_MCI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_mmc_device = { - .name = "at91_mci", - .id = -1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &mmc_data, - }, - .resource = at91_mmc_resources, - .num_resources = ARRAY_SIZE(at91_mmc_resources), -}; - -void __init at91_add_device_mmc(struct at91_mmc_data *data) -{ - if (!data) - return; - - /* input/irq */ - if (data->det_pin) { - at91_set_gpio_input(data->det_pin, 1); - at91_set_deglitch(data->det_pin, 1); - } - if (data->wp_pin) - at91_set_gpio_input(data->wp_pin, 1); - - /* CLK */ - at91_set_A_periph(AT91_PIN_PA27, 0); - - if (data->is_b) { - /* CMD */ - at91_set_B_periph(AT91_PIN_PA8, 0); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_B_periph(AT91_PIN_PA9, 0); - if (data->wire4) { - at91_set_B_periph(AT91_PIN_PA10, 0); - at91_set_B_periph(AT91_PIN_PA11, 0); - at91_set_B_periph(AT91_PIN_PA12, 0); - } - } else { - /* CMD */ - at91_set_A_periph(AT91_PIN_PA28, 0); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA29, 0); - if (data->wire4) { - at91_set_B_periph(AT91_PIN_PB3, 0); - at91_set_B_periph(AT91_PIN_PB4, 0); - at91_set_B_periph(AT91_PIN_PB5, 0); - } - } - - mmc_data = *data; - platform_device_register(&at91rm9200_mmc_device); -} -#else -void __init at91_add_device_mmc(struct at91_mmc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; - -static struct resource at91_nand_resources[] = { - { - .start = AT91_SMARTMEDIA_BASE, - .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91_nand_device = { - .name = "at91_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = at91_nand_resources, - .num_resources = ARRAY_SIZE(at91_nand_resources), -}; - -void __init at91_add_device_nand(struct at91_nand_data *data) -{ - if (!data) - return; - - /* enable pin */ - if (data->enable_pin) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (data->rdy_pin) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (data->det_pin) - at91_set_gpio_input(data->det_pin, 1); - - at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ - - nand_data = *data; - platform_device_register(&at91_nand_device); -} -#else -void __init at91_add_device_nand(struct at91_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) -static struct platform_device at91rm9200_twi_device = { - .name = "at91_i2c", - .id = -1, - .num_resources = 0, -}; - -void __init at91_add_device_i2c(void) -{ - /* pins used for TWI interface */ - at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PA25, 1); - - at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PA26, 1); - - platform_device_register(&at91rm9200_twi_device); -} -#else -void __init at91_add_device_i2c(void) {} -#endif - - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) -static u64 spi_dmamask = 0xffffffffUL; - -static struct resource at91_spi_resources[] = { - [0] = { - .start = AT91RM9200_BASE_SPI, - .end = AT91RM9200_BASE_SPI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_SPI, - .end = AT91RM9200_ID_SPI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_spi_device = { - .name = "at91_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .resource = at91_spi_resources, - .num_resources = ARRAY_SIZE(at91_spi_resources), -}; - -static const unsigned at91_spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - - at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */ - at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */ - at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */ - - /* Enable SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else - cs_pin = at91_spi_standard_cs[devices[i].chip_select]; - -#ifdef CONFIG_SPI_AT91_MANUAL_CS - at91_set_gpio_output(cs_pin, 1); -#else - at91_set_A_periph(cs_pin, 0); -#endif - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - at91_clock_associate("spi0_clk", &at91rm9200_spi_device.dev, "spi"); - platform_device_register(&at91rm9200_spi_device); -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * RTC - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_RTC_DRV_AT91) || defined(CONFIG_RTC_DRV_AT91_MODULE) -static struct platform_device at91rm9200_rtc_device = { - .name = "at91_rtc", - .id = -1, - .num_resources = 0, -}; - -static void __init at91_add_device_rtc(void) -{ - platform_device_register(&at91rm9200_rtc_device); -} -#else -static void __init at91_add_device_rtc(void) {} -#endif - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91_WATCHDOG) || defined(CONFIG_AT91_WATCHDOG_MODULE) -static struct platform_device at91rm9200_wdt_device = { - .name = "at91_wdt", - .id = -1, - .num_resources = 0, -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91rm9200_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * LEDs - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_LEDS) -u8 at91_leds_cpu; -u8 at91_leds_timer; - -void __init at91_init_leds(u8 cpu_led, u8 timer_led) -{ - at91_leds_cpu = cpu_led; - at91_leds_timer = timer_led; -} -#else -void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91_ID_SYS, - .end = AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), -}; - -static struct platform_device at91rm9200_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .platform_data = &dbgu_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US0, - .end = AT91RM9200_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_US0, - .end = AT91RM9200_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct platform_device at91rm9200_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .platform_data = &uart0_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ - at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ - - /* - * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. - * We need to drive the pin manually. Default is off (RTS is active low). - */ - at91_set_gpio_output(AT91_PIN_PA21, 1); -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US1, - .end = AT91RM9200_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_US1, - .end = AT91RM9200_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct platform_device at91rm9200_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .platform_data = &uart1_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(void) -{ - at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ - at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ - at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ - at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ - at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ - at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ - at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US2, - .end = AT91RM9200_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_US2, - .end = AT91RM9200_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct platform_device at91rm9200_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .platform_data = &uart2_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ - at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ -} - -static struct resource uart3_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US3, - .end = AT91RM9200_BASE_US3 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_US3, - .end = AT91RM9200_ID_US3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart3_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct platform_device at91rm9200_uart3_device = { - .name = "atmel_usart", - .id = 4, - .dev = { - .platform_data = &uart3_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = uart3_resources, - .num_resources = ARRAY_SIZE(uart3_resources), -}; - -static inline void configure_usart3_pins(void) -{ - at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ - at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ -} - -struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ - -void __init at91_init_serial(struct at91_uart_config *config) -{ - int i; - - /* Fill in list of supported UARTs */ - for (i = 0; i < config->nr_tty; i++) { - switch (config->tty_map[i]) { - case 0: - configure_usart0_pins(); - at91_uarts[i] = &at91rm9200_uart0_device; - at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); - break; - case 1: - configure_usart1_pins(); - at91_uarts[i] = &at91rm9200_uart1_device; - at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); - break; - case 2: - configure_usart2_pins(); - at91_uarts[i] = &at91rm9200_uart2_device; - at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); - break; - case 3: - configure_usart3_pins(); - at91_uarts[i] = &at91rm9200_uart3_device; - at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); - break; - case 4: - configure_dbgu_pins(); - at91_uarts[i] = &at91rm9200_dbgu_device; - at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart"); - break; - default: - continue; - } - at91_uarts[i]->id = i; /* update ID number to mapped ID */ - } - - /* Set serial console device */ - if (config->console_tty < ATMEL_MAX_UART) - atmel_default_console_device = at91_uarts[config->console_tty]; - if (!atmel_default_console_device) - printk(KERN_INFO "AT91: No default serial console defined.\n"); -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } -} -#else -void __init at91_init_serial(struct at91_uart_config *config) {} -void __init at91_add_device_serial(void) {} -#endif - - -/* -------------------------------------------------------------------- */ - -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - at91_add_device_rtc(); - at91_add_device_watchdog(); - return 0; -} - -arch_initcall(at91_add_standard_devices); -- cgit v1.2.3 From 1f4fd0a0d28fabf965815755f1a74ef91dfb5ca6 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 10:01:47 +0100 Subject: [ARM] 3946/1: AT91: at91_arch_reset and at91_extern_irq The external interrupt sources are different on the various AT91 processors. This patch introduces the global 'at91_extern_irq' variable that contains a bitset of the available external interrupt sources. The processor reset mechanism also differs on the various AT91 processors. This patch also adds a global 'at91_arch_reset' callback (from system.h) into the processor-specific code to perform the reset. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200.c | 17 +++++++++++++++++ arch/arm/mach-at91rm9200/generic.h | 3 +++ arch/arm/mach-at91rm9200/irq.c | 14 ++++++++++---- arch/arm/mach-at91rm9200/pm.c | 9 +-------- 4 files changed, 31 insertions(+), 12 deletions(-) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index dcf6136fedf..0422593032f 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "generic.h" @@ -222,6 +223,16 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { } }; +static void at91rm9200_reset(void) +{ + /* + * Perform a hardware reset with the use of the Watchdog timer. + */ + at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); + at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); +} + + /* -------------------------------------------------------------------- * AT91RM9200 processor initialization * -------------------------------------------------------------------- */ @@ -230,6 +241,12 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks /* Map peripherals */ iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); + at91_arch_reset = at91rm9200_reset; + at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) + | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) + | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) + | (1 << AT91RM9200_ID_IRQ6); + /* Init clock subsystem */ at91_clock_init(main_clock); diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h index 694e411e285..fd98e353c5a 100644 --- a/arch/arm/mach-at91rm9200/generic.h +++ b/arch/arm/mach-at91rm9200/generic.h @@ -39,3 +39,6 @@ struct at91_gpio_bank { }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); extern void __init at91_gpio_irq_setup(void); + +extern void (*at91_arch_reset)(void); +extern int at91_extern_irq; diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c index 3e488117ca9..2cea07a34a8 100644 --- a/arch/arm/mach-at91rm9200/irq.c +++ b/arch/arm/mach-at91rm9200/irq.c @@ -47,6 +47,10 @@ static void at91_aic_unmask_irq(unsigned int irq) at91_sys_write(AT91_AIC_IECR, 1 << irq); } +unsigned int at91_extern_irq; + +#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) + static int at91_aic_set_type(unsigned irq, unsigned type) { unsigned int smr, srctype; @@ -59,14 +63,16 @@ static int at91_aic_set_type(unsigned irq, unsigned type) srctype = AT91_AIC_SRCTYPE_RISING; break; case IRQT_LOW: - if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_LOW; + else return -EINVAL; - srctype = AT91_AIC_SRCTYPE_LOW; break; case IRQT_FALLING: - if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_FALLING; + else return -EINVAL; - srctype = AT91_AIC_SRCTYPE_FALLING; break; default: return -EINVAL; diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 32c95d8eaac..5e3b6e306f1 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c @@ -112,7 +112,6 @@ EXPORT_SYMBOL(at91_suspend_entering_slow_clock); static void (*slow_clock)(void); - static int at91_pm_enter(suspend_state_t state) { at91_gpio_suspend(); @@ -123,13 +122,7 @@ static int at91_pm_enter(suspend_state_t state) (at91_sys_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) - | (1 << AT91RM9200_ID_IRQ0) - | (1 << AT91RM9200_ID_IRQ1) - | (1 << AT91RM9200_ID_IRQ2) - | (1 << AT91RM9200_ID_IRQ3) - | (1 << AT91RM9200_ID_IRQ4) - | (1 << AT91RM9200_ID_IRQ5) - | (1 << AT91RM9200_ID_IRQ6)) + | (at91_extern_irq)) & at91_sys_read(AT91_AIC_IMR), state); -- cgit v1.2.3 From 62c1660d908c44663c63ad6c679f6afa1d33c5f6 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 12:27:38 +0100 Subject: [ARM] 3948/1: AT91: Initial support for AT91SAM9261 and AT91SAM9260 This patch adds the initial support for the newer Atmel AT91SAM9261 and AT91SAM9260 processors. The code is based on, and makes use of, the existing AT91RM9200 support. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 6 +- arch/arm/mach-at91rm9200/at91sam9260.c | 294 +++++++++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/at91sam9261.c | 289 ++++++++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/generic.h | 5 + 4 files changed, 591 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-at91rm9200/at91sam9260.c create mode 100644 arch/arm/mach-at91rm9200/at91sam9261.c (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 568d8d76cde..40e89bf459f 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -11,10 +11,10 @@ obj-$(CONFIG_PM) += pm.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c -obj-$(CONFIG_ARCH_AT91SAM9260) += -obj-$(CONFIG_ARCH_AT91SAM9261) += +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o -# AT91RM9200 Board-specific support +# AT91RM9200 board-specific support obj-$(CONFIG_MACH_ONEARM) += board-1arm.o obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o diff --git a/arch/arm/mach-at91rm9200/at91sam9260.c b/arch/arm/mach-at91rm9200/at91sam9260.c new file mode 100644 index 00000000000..203f073a53e --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam9260.c @@ -0,0 +1,294 @@ +/* + * arch/arm/mach-at91rm9200/at91sam9260.c + * + * Copyright (C) 2006 SAN People + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include + +#include +#include +#include +#include + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9260_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, + .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), + .length = AT91SAM9260_SRAM0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE, + .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), + .length = AT91SAM9260_SRAM1_SIZE, + .type = MT_DEVICE, + }, +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk adc_clk = { + .name = "adc_clk", + .pmc_mask = 1 << AT91SAM9260_ID_ADC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91SAM9260_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91SAM9260_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9260_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9260_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91SAM9260_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ether_clk = { + .name = "ether_clk", + .pmc_mask = 1 << AT91SAM9260_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk isi_clk = { + .name = "isi_clk", + .pmc_mask = 1 << AT91SAM9260_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart4_clk = { + .name = "usart4_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US4, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart5_clk = { + .name = "usart5_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US5, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &adc_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi0_clk, + &spi1_clk, + // ssc + // tc0 .. tc2 + &ohci_clk, + ðer_clk, + &isi_clk, + &usart3_clk, + &usart4_clk, + &usart5_clk, + // tc3 .. tc5 + // irq0 .. irq2 +}; + +/* + * The two programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; + +static void __init at91sam9260_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clk_register(&pck0); + clk_register(&pck1); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9260_gpio[] = { + { + .id = AT91SAM9260_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9260_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9260_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + } +}; + +static void at91sam9260_reset(void) +{ +#warning "Implement CPU reset" +} + + +/* -------------------------------------------------------------------- + * AT91SAM9260 processor initialization + * -------------------------------------------------------------------- */ + +void __init at91sam9260_initialize(unsigned long main_clock) +{ + /* Map peripherals */ + iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); + + at91_arch_reset = at91sam9260_reset; + at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) + | (1 << AT91SAM9260_ID_IRQ2); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9260_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9260_gpio, 3); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 0, /* Parallel IO Controller A */ + 0, /* Parallel IO Controller B */ + 0, /* Parallel IO Controller C */ + 0, /* Analog-to-Digital Converter */ + 6, /* USART 0 */ + 6, /* USART 1 */ + 6, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 4, /* USB Device Port */ + 0, /* Two-Wire Interface */ + 6, /* Serial Peripheral Interface 0 */ + 6, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller */ + 0, + 0, + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 3, /* USB Host port */ + 3, /* Ethernet */ + 0, /* Image Sensor Interface */ + 6, /* USART 3 */ + 6, /* USART 4 */ + 6, /* USART 5 */ + 0, /* Timer Counter 3 */ + 0, /* Timer Counter 4 */ + 0, /* Timer Counter 5 */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ +}; + +void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9260_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91rm9200/at91sam9261.c b/arch/arm/mach-at91rm9200/at91sam9261.c new file mode 100644 index 00000000000..5a82f35da2e --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam9261.c @@ -0,0 +1,289 @@ +/* + * arch/arm/mach-at91rm9200/at91sam9261.c + * + * Copyright (C) 2005 SAN People + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include + +#include +#include +#include +#include + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9261_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), + .length = AT91SAM9261_SRAM_SIZE, + .type = MT_DEVICE, + }, +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91SAM9261_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91SAM9261_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91SAM9261_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91SAM9261_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91SAM9261_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi0_clk, + &spi1_clk, + // ssc 0 .. ssc2 + // tc0 .. tc2 + &ohci_clk, + &lcdc_clk, + // irq0 .. irq2 +}; + +/* + * The four programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 2, +}; +static struct clk pck3 = { + .name = "pck3", + .pmc_mask = AT91_PMC_PCK3, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 3, +}; + +/* HClocks */ +static struct clk hck0 = { + .name = "hck0", + .pmc_mask = AT91_PMC_HCK0, + .type = CLK_TYPE_SYSTEM, + .id = 0, +}; +static struct clk hck1 = { + .name = "hck1", + .pmc_mask = AT91_PMC_HCK1, + .type = CLK_TYPE_SYSTEM, + .id = 1, +}; + +static void __init at91sam9261_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); + clk_register(&pck3); + + clk_register(&hck0); + clk_register(&hck1); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9261_gpio[] = { + { + .id = AT91SAM9261_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9261_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9261_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + } +}; + +static void at91sam9261_reset(void) +{ +#warning "Implement CPU reset" +} + + +/* -------------------------------------------------------------------- + * AT91SAM9261 processor initialization + * -------------------------------------------------------------------- */ + +void __init at91sam9261_initialize(unsigned long main_clock) +{ + /* Map peripherals */ + iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); + + at91_arch_reset = at91sam9261_reset; + at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) + | (1 << AT91SAM9261_ID_IRQ2); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9261_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9261_gpio, 3); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 0, /* Parallel IO Controller A */ + 0, /* Parallel IO Controller B */ + 0, /* Parallel IO Controller C */ + 0, + 6, /* USART 0 */ + 6, /* USART 1 */ + 6, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 4, /* USB Device Port */ + 0, /* Two-Wire Interface */ + 6, /* Serial Peripheral Interface 0 */ + 6, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller 0 */ + 5, /* Serial Synchronous Controller 1 */ + 5, /* Serial Synchronous Controller 2 */ + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 3, /* USB Host port */ + 3, /* LCD Controller */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ +}; + +void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9261_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h index fd98e353c5a..8c4d5a77d48 100644 --- a/arch/arm/mach-at91rm9200/generic.h +++ b/arch/arm/mach-at91rm9200/generic.h @@ -10,14 +10,19 @@ /* Processors */ extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks); +extern void __init at91sam9260_initialize(unsigned long main_clock); +extern void __init at91sam9261_initialize(unsigned long main_clock); /* Interrupts */ extern void __init at91rm9200_init_interrupts(unsigned int priority[]); +extern void __init at91sam9260_init_interrupts(unsigned int priority[]); +extern void __init at91sam9261_init_interrupts(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]); /* Timer */ struct sys_timer; extern struct sys_timer at91rm9200_timer; +extern struct sys_timer at91sam926x_timer; /* Clocks */ extern int __init at91_clock_init(unsigned long main_clock); -- cgit v1.2.3 From 55d8baee4a0b4709061104f7a56f53a310de76ac Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 17:16:43 +0100 Subject: [ARM] 3954/1: AT91: Update drivers for new headers This patch updates the drivers (and other files) which include the hardware headers. This fixes the breakage introduced in patches 3950/1 and 3951/1 (those patches were getting big). The AVR32 architecture uses the same serial driver and had its own copy of at91rm9200_pdc.h. Renamed it to at91_pdc.h Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200.c | 3 ++- arch/arm/mach-at91rm9200/at91rm9200_time.c | 2 ++ arch/arm/mach-at91rm9200/clock.c | 1 + arch/arm/mach-at91rm9200/gpio.c | 2 ++ arch/arm/mach-at91rm9200/pm.c | 2 ++ 5 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index 0422593032f..0816a8d2e86 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c @@ -15,8 +15,9 @@ #include #include #include +#include +#include -#include #include "generic.h" #include "clock.h" diff --git a/arch/arm/mach-at91rm9200/at91rm9200_time.c b/arch/arm/mach-at91rm9200/at91rm9200_time.c index 07c9cea8961..8e9c049c8b7 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200_time.c +++ b/arch/arm/mach-at91rm9200/at91rm9200_time.c @@ -30,6 +30,8 @@ #include #include +#include + static unsigned long last_crtr; /* diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c index a43b061a7c8..1e0000ceb34 100644 --- a/arch/arm/mach-at91rm9200/clock.c +++ b/arch/arm/mach-at91rm9200/clock.c @@ -28,6 +28,7 @@ #include #include +#include #include "clock.h" diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c index 7467d644f0a..e76422761db 100644 --- a/arch/arm/mach-at91rm9200/gpio.c +++ b/arch/arm/mach-at91rm9200/gpio.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include "generic.h" diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 5e3b6e306f1..5b775fac1c6 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include "generic.h" -- cgit v1.2.3 From 1a0ed732afdbd4b960a4b93f78fddc71b8076e61 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 09:04:47 +0100 Subject: [ARM] 3949/2: AT91: SAM9 timer driver Add support for the timer on the Atmel AT91SAM9261 and AT91SAM9260 processors. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 4 +- arch/arm/mach-at91rm9200/at91sam926x_time.c | 114 ++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-at91rm9200/at91sam926x_time.c (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 40e89bf459f..b8684ba60ce 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -11,8 +11,8 @@ obj-$(CONFIG_PM) += pm.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o # AT91RM9200 board-specific support obj-$(CONFIG_MACH_ONEARM) += board-1arm.o diff --git a/arch/arm/mach-at91rm9200/at91sam926x_time.c b/arch/arm/mach-at91rm9200/at91sam926x_time.c new file mode 100644 index 00000000000..99df5f6ee42 --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam926x_time.c @@ -0,0 +1,114 @@ +/* + * linux/arch/arm/mach-at91rm9200/at91sam926x_time.c + * + * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France + * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + + +#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV) +#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20) + +/* + * Returns number of microseconds since last timer interrupt. Note that interrupts + * will have been disabled by do_gettimeofday() + * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. + * 'tick' is usecs per jiffy (linux/timex.h). + */ +static unsigned long at91sam926x_gettimeoffset(void) +{ + unsigned long elapsed; + unsigned long t = at91_sys_read(AT91_PIT_PIIR); + + elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t); /* hardware clock cycles */ + + return (unsigned long)(elapsed * 1000000) / LATCH; +} + +/* + * IRQ handler for the timer. + */ +static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id) +{ + volatile long nr_ticks; + + if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) { /* This is a shared interrupt */ + write_seqlock(&xtime_lock); + + /* Get number to ticks performed before interrupt and clear PIT interrupt */ + nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); + do { + timer_tick(); + nr_ticks--; + } while (nr_ticks); + + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; + } else + return IRQ_NONE; /* not handled */ +} + +static struct irqaction at91sam926x_timer_irq = { + .name = "at91_tick", + .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER, + .handler = at91sam926x_timer_interrupt +}; + +void at91sam926x_timer_reset(void) +{ + /* Disable timer */ + at91_sys_write(AT91_PIT_MR, 0); + + /* Clear any pending interrupts */ + (void) at91_sys_read(AT91_PIT_PIVR); + + /* Set Period Interval timer and enable its interrupt */ + at91_sys_write(AT91_PIT_MR, (LATCH & AT91_PIT_PIV) | AT91_PIT_PITIEN | AT91_PIT_PITEN); +} + +/* + * Set up timer interrupt. + */ +void __init at91sam926x_timer_init(void) +{ + /* Initialize and enable the timer */ + at91sam926x_timer_reset(); + + /* Make IRQs happen for the system timer. */ + setup_irq(AT91_ID_SYS, &at91sam926x_timer_irq); +} + +#ifdef CONFIG_PM +static void at91sam926x_timer_suspend(void) +{ + /* Disable timer */ + at91_sys_write(AT91_PIT_MR, 0); +} +#else +#define at91sam926x_timer_suspend NULL +#endif + +struct sys_timer at91sam926x_timer = { + .init = at91sam926x_timer_init, + .offset = at91sam926x_gettimeoffset, + .suspend = at91sam926x_timer_suspend, + .resume = at91sam926x_timer_reset, +}; + -- cgit v1.2.3 From 86ad76bb2db7029343f681359c4b328fd8c36ae8 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 16:45:01 +0100 Subject: [ARM] 3953/1: AT91: SAM9 platform devices This patch includes the pin initialization, resource definition and registration of the platform_devices for the SAM9260 and SAM9261 processors. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 4 +- arch/arm/mach-at91rm9200/at91sam9260_devices.c | 866 +++++++++++++++++++++++++ arch/arm/mach-at91rm9200/at91sam9261_devices.c | 741 +++++++++++++++++++++ 3 files changed, 1609 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-at91rm9200/at91sam9260_devices.c create mode 100644 arch/arm/mach-at91rm9200/at91sam9261_devices.c (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index b8684ba60ce..6093c31e39a 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -11,8 +11,8 @@ obj-$(CONFIG_PM) += pm.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o # AT91RM9200 board-specific support obj-$(CONFIG_MACH_ONEARM) += board-1arm.o diff --git a/arch/arm/mach-at91rm9200/at91sam9260_devices.c b/arch/arm/mach-at91rm9200/at91sam9260_devices.c new file mode 100644 index 00000000000..a6c596dc451 --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam9260_devices.c @@ -0,0 +1,866 @@ +/* + * arch/arm/mach-at91rm9200/at91sam9260_devices.c + * + * Copyright (C) 2006 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. + * + */ +#include +#include + +#include + +#include +#include +#include +#include + +#include "generic.h" + +#define SZ_512 0x00000200 +#define SZ_256 0x00000100 +#define SZ_16 0x00000010 + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = 0xffffffffUL; +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91SAM9260_UHP_BASE, + .end = AT91SAM9260_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_UHP, + .end = AT91SAM9260_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource udc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_UDP, + .end = AT91SAM9260_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_UDP, + .end = AT91SAM9260_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + + /* Pullup pin is handled internally by USB device peripheral */ + + udc_data = *data; + platform_device_register(&at91_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) +static u64 eth_dmamask = 0xffffffffUL; +static struct eth_platform_data eth_data; + +static struct resource eth_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_EMAC, + .end = AT91SAM9260_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_EMAC, + .end = AT91SAM9260_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_eth_device = { + .name = "macb", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = ð_data, + }, + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), +}; + +void __init at91_add_device_eth(struct eth_platform_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PA19, 0); /* ETXCK_EREFCK */ + at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */ + + if (!data->is_rmii) { + at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */ + at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */ + at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */ + } + + eth_data = *data; + platform_device_register(&at91sam9260_eth_device); +} +#else +void __init at91_add_device_eth(struct eth_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = 0xffffffffUL; +static struct at91_mmc_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_MCI, + .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_MCI, + .end = AT91SAM9260_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mmc(struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA8, 0); + + if (data->slot_b) { + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA3, 1); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA6, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } + } + + mmc_data = *data; + platform_device_register(&at91sam9260_mmc_device); +} +#else +void __init at91_add_device_mmc(struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) +static struct at91_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + { + .start = NAND_BASE, + .end = NAND_BASE + SZ_8M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9260_nand_device = { + .name = "at91_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct at91_nand_data *data) +{ + unsigned long csa, mode; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); + + /* set the bus interface characteristics */ + 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)); + + if (data->bus_width_16) + mode = AT91_SMC_DBW_16; + else + mode = AT91_SMC_DBW_8; + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + nand_data = *data; + platform_device_register(&at91sam9260_nand_device); +} +#else +void __init at91_add_device_nand(struct at91_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_TWI, + .end = AT91SAM9260_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_TWI, + .end = AT91SAM9260_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(void) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA23, 1); + + at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA24, 1); + + platform_device_register(&at91sam9260_twi_device); +} +#else +void __init at91_add_device_i2c(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = 0xffffffffUL; + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_SPI0, + .end = AT91SAM9260_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_SPI0, + .end = AT91SAM9260_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PC11, AT91_PIN_PC16, AT91_PIN_PC17 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_SPI1, + .end = AT91SAM9260_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_SPI1, + .end = AT91SAM9260_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + 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); /* SPI1_SPCK */ + + at91_clock_associate("spi0_clk", &at91sam9260_spi0_device.dev, "spi_clk"); + platform_device_register(&at91sam9260_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI1_SPCK */ + + at91_clock_associate("spi1_clk", &at91sam9260_spi1_device.dev, "spi_clk"); + platform_device_register(&at91sam9260_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * LEDs + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_LEDS) +u8 at91_leds_cpu; +u8 at91_leds_timer; + +void __init at91_init_leds(u8 cpu_led, u8 timer_led) +{ + at91_leds_cpu = cpu_led; + at91_leds_timer = timer_led; +} +#else +void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static struct platform_device at91sam9260_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .platform_data = &dbgu_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US0, + .end = AT91SAM9260_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US0, + .end = AT91SAM9260_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .platform_data = &uart0_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ + at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ + at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ + at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ + at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ + at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US1, + .end = AT91SAM9260_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US1, + .end = AT91SAM9260_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .platform_data = &uart1_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US2, + .end = AT91SAM9260_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US2, + .end = AT91SAM9260_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .platform_data = &uart2_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ +} + +static struct resource uart3_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US3, + .end = AT91SAM9260_BASE_US3 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US3, + .end = AT91SAM9260_ID_US3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart3_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart3_device = { + .name = "atmel_usart", + .id = 4, + .dev = { + .platform_data = &uart3_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart3_resources, + .num_resources = ARRAY_SIZE(uart3_resources), +}; + +static inline void configure_usart3_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ +} + +static struct resource uart4_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US4, + .end = AT91SAM9260_BASE_US4 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US4, + .end = AT91SAM9260_ID_US4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart4_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart4_device = { + .name = "atmel_usart", + .id = 5, + .dev = { + .platform_data = &uart4_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart4_resources, + .num_resources = ARRAY_SIZE(uart4_resources), +}; + +static inline void configure_usart4_pins(void) +{ + at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */ + at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */ +} + +static struct resource uart5_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US5, + .end = AT91SAM9260_BASE_US5 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US5, + .end = AT91SAM9260_ID_US5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart5_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart5_device = { + .name = "atmel_usart", + .id = 6, + .dev = { + .platform_data = &uart5_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart5_resources, + .num_resources = ARRAY_SIZE(uart5_resources), +}; + +static inline void configure_usart5_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */ + at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ +} + +struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_init_serial(struct at91_uart_config *config) +{ + int i; + + /* Fill in list of supported UARTs */ + for (i = 0; i < config->nr_tty; i++) { + switch (config->tty_map[i]) { + case 0: + configure_usart0_pins(); + at91_uarts[i] = &at91sam9260_uart0_device; + at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart"); + break; + case 1: + configure_usart1_pins(); + at91_uarts[i] = &at91sam9260_uart1_device; + at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart"); + break; + case 2: + configure_usart2_pins(); + at91_uarts[i] = &at91sam9260_uart2_device; + at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart"); + break; + case 3: + configure_usart3_pins(); + at91_uarts[i] = &at91sam9260_uart3_device; + at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart"); + break; + case 4: + configure_usart4_pins(); + at91_uarts[i] = &at91sam9260_uart4_device; + at91_clock_associate("usart4_clk", &at91sam9260_uart4_device.dev, "usart"); + break; + case 5: + configure_usart5_pins(); + at91_uarts[i] = &at91sam9260_uart5_device; + at91_clock_associate("usart5_clk", &at91sam9260_uart5_device.dev, "usart"); + break; + case 6: + configure_dbgu_pins(); + at91_uarts[i] = &at91sam9260_dbgu_device; + at91_clock_associate("mck", &at91sam9260_dbgu_device.dev, "usart"); + break; + default: + continue; + } + at91_uarts[i]->id = i; /* update ID number to mapped ID */ + } + + /* Set serial console device */ + if (config->console_tty < ATMEL_MAX_UART) + atmel_default_console_device = at91_uarts[config->console_tty]; + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } +} +#else +void __init at91_init_serial(struct at91_uart_config *config) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91rm9200/at91sam9261_devices.c b/arch/arm/mach-at91rm9200/at91sam9261_devices.c new file mode 100644 index 00000000000..ed1d79081b3 --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam9261_devices.c @@ -0,0 +1,741 @@ +/* + * arch/arm/mach-at91rm9200/at91sam9261_devices.c + * + * Copyright (C) 2005 Thibaut VARENE + * Copyright (C) 2005 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "generic.h" + +#define SZ_512 0x00000200 +#define SZ_256 0x00000100 +#define SZ_16 0x00000010 + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = 0xffffffffUL; +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91SAM9261_UHP_BASE, + .end = AT91SAM9261_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_UHP, + .end = AT91SAM9261_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91sam9261_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource udc_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_UDP, + .end = AT91SAM9261_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_UDP, + .end = AT91SAM9261_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + unsigned long x; + + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + + /* Pullup pin is handled internally */ + x = at91_sys_read(AT91_MATRIX_USBPUCR); + at91_sys_write(AT91_MATRIX_USBPUCR, x | AT91_MATRIX_USBPUCR_PUON); + + udc_data = *data; + platform_device_register(&at91sam9261_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = 0xffffffffUL; +static struct at91_mmc_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_MCI, + .end = AT91SAM9261_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_MCI, + .end = AT91SAM9261_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mmc(struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + /* CLK */ + at91_set_B_periph(AT91_PIN_PA2, 0); + + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA6, 1); + } + + mmc_data = *data; + platform_device_register(&at91sam9261_mmc_device); +} +#else +void __init at91_add_device_mmc(struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) +static struct at91_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91_nand_device = { + .name = "at91_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct at91_nand_data *data) +{ + unsigned long csa, mode; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); + + /* set the bus interface characteristics */ + 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)); + + if (data->bus_width_16) + mode = AT91_SMC_DBW_16; + else + mode = AT91_SMC_DBW_8; + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */ + + nand_data = *data; + platform_device_register(&at91_nand_device); +} + +#else +void __init at91_add_device_nand(struct at91_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_TWI, + .end = AT91SAM9261_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_TWI, + .end = AT91SAM9261_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(void) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA7, 1); + + at91_set_A_periph(AT91_PIN_PA8, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA8, 1); + + platform_device_register(&at91sam9261_twi_device); +} +#else +void __init at91_add_device_i2c(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = 0xffffffffUL; + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SPI0, + .end = AT91SAM9261_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SPI0, + .end = AT91SAM9261_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SPI1, + .end = AT91SAM9261_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SPI1, + .end = AT91SAM9261_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB28, AT91_PIN_PA24, AT91_PIN_PA25, AT91_PIN_PA26 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + 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 */ + + at91_clock_associate("spi0_clk", &at91sam9261_spi0_device.dev, "spi_clk"); + platform_device_register(&at91sam9261_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB30, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB31, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* SPI1_SPCK */ + + at91_clock_associate("spi1_clk", &at91sam9261_spi1_device.dev, "spi_clk"); + platform_device_register(&at91sam9261_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_FB_AT91) || defined(CONFIG_FB_AT91_MODULE) +static u64 lcdc_dmamask = 0xffffffffUL; +static struct at91fb_info lcdc_data; + +static struct resource lcdc_resources[] = { + [0] = { + .start = AT91SAM9261_LCDC_BASE, + .end = AT91SAM9261_LCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_LCDC, + .end = AT91SAM9261_ID_LCDC, + .flags = IORESOURCE_IRQ, + }, +#if defined(CONFIG_FB_INTSRAM) + [2] = { + .start = AT91SAM9261_SRAM_BASE, + .end = AT91SAM9261_SRAM_BASE + AT91SAM9261_SRAM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +#endif +}; + +static struct platform_device at91_lcdc_device = { + .name = "at91-fb", + .id = 0, + .dev = { + .dma_mask = &lcdc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &lcdc_data, + }, + .resource = lcdc_resources, + .num_resources = ARRAY_SIZE(lcdc_resources), +}; + +void __init at91_add_device_lcdc(struct at91fb_info *data) +{ + if (!data) { + return; + } + + at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PB10, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PB12, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PB16, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PB17, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PB18, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PB19, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PB20, 0); /* LCDD15 */ + at91_set_B_periph(AT91_PIN_PB23, 0); /* LCDD18 */ + at91_set_B_periph(AT91_PIN_PB24, 0); /* LCDD19 */ + at91_set_B_periph(AT91_PIN_PB25, 0); /* LCDD20 */ + at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ + at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ + at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ + + lcdc_data = *data; + platform_device_register(&at91_lcdc_device); +} +#else +void __init at91_add_device_lcdc(struct at91fb_info *data) {} +#endif + + +/* -------------------------------------------------------------------- + * LEDs + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_LEDS) +u8 at91_leds_cpu; +u8 at91_leds_timer; + +void __init at91_init_leds(u8 cpu_led, u8 timer_led) +{ + at91_leds_cpu = cpu_led; + at91_leds_timer = timer_led; +} +#else +void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static struct platform_device at91sam9261_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .platform_data = &dbgu_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US0, + .end = AT91SAM9261_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US0, + .end = AT91SAM9261_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9261_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .platform_data = &uart0_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(void) +{ + at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US1, + .end = AT91SAM9261_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US1, + .end = AT91SAM9261_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9261_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .platform_data = &uart1_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(void) +{ + at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US2, + .end = AT91SAM9261_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US2, + .end = AT91SAM9261_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9261_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .platform_data = &uart2_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(void) +{ + at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ +} + +struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_init_serial(struct at91_uart_config *config) +{ + int i; + + /* Fill in list of supported UARTs */ + for (i = 0; i < config->nr_tty; i++) { + switch (config->tty_map[i]) { + case 0: + configure_usart0_pins(); + at91_uarts[i] = &at91sam9261_uart0_device; + at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart"); + break; + case 1: + configure_usart1_pins(); + at91_uarts[i] = &at91sam9261_uart1_device; + at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart"); + break; + case 2: + configure_usart2_pins(); + at91_uarts[i] = &at91sam9261_uart2_device; + at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart"); + break; + case 3: + configure_dbgu_pins(); + at91_uarts[i] = &at91sam9261_dbgu_device; + at91_clock_associate("mck", &at91sam9261_dbgu_device.dev, "usart"); + break; + default: + continue; + } + at91_uarts[i]->id = i; /* update ID number to mapped ID */ + } + + /* Set serial console device */ + if (config->console_tty < ATMEL_MAX_UART) + atmel_default_console_device = at91_uarts[config->console_tty]; + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } +} +#else +void __init at91_init_serial(struct at91_uart_config *config) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ + +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + return 0; +} + +arch_initcall(at91_add_standard_devices); -- cgit v1.2.3 From d100f25956e8626afeafbb38558ca8c58df1cb6b Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 10:15:04 +0100 Subject: [ARM] 3955/1: AT91: Clear timer interrupt when resuming Attached is a patch for at91rm9200_time.c which removes the 'BUG: soft lockup detected on CPU#0!' message when exiting suspended states. Patch from Savin Zlobec Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200_time.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/at91rm9200_time.c b/arch/arm/mach-at91rm9200/at91rm9200_time.c index 8e9c049c8b7..b999e192a7e 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200_time.c +++ b/arch/arm/mach-at91rm9200/at91rm9200_time.c @@ -101,6 +101,9 @@ void at91rm9200_timer_reset(void) /* Set Period Interval timer */ at91_sys_write(AT91_ST_PIMR, LATCH); + /* Clear any pending interrupts */ + (void) at91_sys_read(AT91_ST_SR); + /* Enable Period Interval Timer interrupt */ at91_sys_write(AT91_ST_IER, AT91_ST_PITS); } -- cgit v1.2.3 From 330d741b0632960e7853a2cb3b2899e94e696f12 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 10:31:29 +0100 Subject: [ARM] 3956/1: AT91: Carmeva board update This patch updates the Carmeva board support: * Specify the MMC Write-protect and Detection pins. * Add configuration of SPI devices. Patch from Peer Georgi. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/board-carmeva.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91rm9200/board-carmeva.c index 98208740e7c..5cd68e6001e 100644 --- a/arch/arm/mach-at91rm9200/board-carmeva.c +++ b/arch/arm/mach-at91rm9200/board-carmeva.c @@ -65,7 +65,6 @@ static void __init carmeva_init_irq(void) at91rm9200_init_interrupts(NULL); } - static struct at91_eth_data __initdata carmeva_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -91,6 +90,31 @@ static struct at91_udc_data __initdata carmeva_udc_data = { static struct at91_mmc_data __initdata carmeva_mmc_data = { .is_b = 0, .wire4 = 1, + .det_pin = AT91_PIN_PB10, + .wp_pin = AT91_PIN_PC14, +}; + +static struct spi_board_info carmeva_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 10 * 1000 * 1000, + }, + { /* User accessable spi - cs1 (250KHz) */ + .modalias = "spi-cs1", + .chip_select = 1, + .max_speed_hz = 250 * 1000, + }, + { /* User accessable spi - cs2 (1MHz) */ + .modalias = "spi-cs2", + .chip_select = 2, + .max_speed_hz = 1 * 1000 * 1000, + }, + { /* User accessable spi - cs3 (10MHz) */ + .modalias = "spi-cs3", + .chip_select = 3, + .max_speed_hz = 10 * 1000 * 1000, + }, }; static void __init carmeva_board_init(void) @@ -105,10 +129,10 @@ static void __init carmeva_board_init(void) at91_add_device_udc(&carmeva_udc_data); /* I2C */ at91_add_device_i2c(); + /* SPI */ + at91_add_device_spi(carmeva_spi_devices, ARRAY_SIZE(carmeva_spi_devices)); /* Compact Flash */ // at91_add_device_cf(&carmeva_cf_data); - /* SPI */ -// at91_add_device_spi(NULL, 0); /* MMC */ at91_add_device_mmc(&carmeva_mmc_data); } -- cgit v1.2.3 From fcc63716a5ee93ec3d1043890e38753d53313b80 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 10:55:15 +0100 Subject: [ARM] 3957/1: AT91: Physically mapped flash on DK and EK boards This patch converts the old CONFIG_MTD_PHYSMAP_ options to the new physmap API by creating a physmap platform device for the NOR flash found on the Atmel AT91RM9200-DK and AT91RM9200-EK boards. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/board-dk.c | 28 ++++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/board-ek.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index c699f3984d4..314e1f769ea 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ #include #include +#include #include "generic.h" @@ -145,6 +147,30 @@ static struct at91_nand_data __initdata dk_nand_data = { .partition_info = nand_partitions, }; +#define DK_FLASH_BASE AT91_CHIPSELECT_0 +#define DK_FLASH_SIZE 0x200000 + +static struct physmap_flash_data dk_flash_data = { + .width = 2, +}; + +static struct resource dk_flash_resource = { + .start = DK_FLASH_BASE, + .end = DK_FLASH_BASE + DK_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device dk_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &dk_flash_data, + }, + .resource = &dk_flash_resource, + .num_resources = 1, +}; + + static void __init dk_board_init(void) { /* Serial */ @@ -172,6 +198,8 @@ static void __init dk_board_init(void) #endif /* NAND */ at91_add_device_nand(&dk_nand_data); + /* NOR Flash */ + platform_device_register(&dk_flash); /* VGA */ // dk_add_device_video(); } diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index 830eb793217..9fcfa066635 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ #include #include +#include #include "generic.h" @@ -107,6 +109,30 @@ static struct spi_board_info ek_spi_devices[] = { #endif }; +#define EK_FLASH_BASE AT91_CHIPSELECT_0 +#define EK_FLASH_SIZE 0x200000 + +static struct physmap_flash_data ek_flash_data = { + .width = 2, +}; + +static struct resource ek_flash_resource = { + .start = EK_FLASH_BASE, + .end = EK_FLASH_BASE + EK_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ek_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &ek_flash_data, + }, + .resource = &ek_flash_resource, + .num_resources = 1, +}; + + static void __init ek_board_init(void) { /* Serial */ @@ -130,6 +156,8 @@ static void __init ek_board_init(void) at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ at91_add_device_mmc(&ek_mmc_data); #endif + /* NOR Flash */ + platform_device_register(&ek_flash); /* VGA */ // ek_add_device_video(); } -- cgit v1.2.3 From d481f86449ccd66314b700c78b3a79168df80d02 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 11:27:31 +0100 Subject: [ARM] 3959/1: AT91: Support for SAM9 USB and HCK clocks The bits used to select the USB clocks are different on the SAM9's. Add support for the HCK clocks on the AT91SAM9261. Patch from Patrice Vilchez & Nicolas Ferre Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/clock.c | 26 ++++++++++++++++++++++---- arch/arm/mach-at91rm9200/clock.h | 1 + arch/arm/mach-at91rm9200/pm.c | 13 ++++++++++--- 3 files changed, 33 insertions(+), 7 deletions(-) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c index 1e0000ceb34..4dee21fefe5 100644 --- a/arch/arm/mach-at91rm9200/clock.c +++ b/arch/arm/mach-at91rm9200/clock.c @@ -29,6 +29,7 @@ #include #include +#include #include "clock.h" @@ -42,6 +43,7 @@ #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) #define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) +#define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) static LIST_HEAD(clocks); @@ -115,13 +117,11 @@ static void pmc_sys_mode(struct clk *clk, int is_on) static struct clk udpck = { .name = "udpck", .parent = &pllb, - .pmc_mask = AT91_PMC_UDP, .mode = pmc_sys_mode, }; static struct clk uhpck = { .name = "uhpck", .parent = &pllb, - .pmc_mask = AT91_PMC_UHP, .mode = pmc_sys_mode, }; @@ -435,6 +435,12 @@ int __init clk_register(struct clk *clk) clk->mode = pmc_periph_mode; list_add_tail(&clk->node, &clocks); } + else if (clk_is_sys(clk)) { + clk->parent = &mck; + clk->mode = pmc_sys_mode; + + list_add_tail(&clk->node, &clocks); + } #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS else if (clk_is_programmable(clk)) { clk->mode = pmc_sys_mode; @@ -587,9 +593,21 @@ int __init at91_clock_init(unsigned long main_clock) */ at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); - at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP | AT91_PMC_UDP); + if (cpu_is_at91rm9200()) { + uhpck.pmc_mask = AT91RM9200_PMC_UHP; + udpck.pmc_mask = AT91RM9200_PMC_UDP; + at91_sys_write(AT91_PMC_SCDR, AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP); + at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); + } else if (cpu_is_at91sam9260()) { + uhpck.pmc_mask = AT91SAM926x_PMC_UHP; + udpck.pmc_mask = AT91SAM926x_PMC_UDP; + at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP); + } else if (cpu_is_at91sam9261()) { + uhpck.pmc_mask = (AT91SAM926x_PMC_UHP | AT91_PMC_HCK0); + udpck.pmc_mask = AT91SAM926x_PMC_UDP; + at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91_PMC_HCK0 | AT91SAM926x_PMC_UDP); + } at91_sys_write(AT91_CKGR_PLLBR, 0); - at91_sys_write(AT91_PMC_SCER, AT91_PMC_MCKUDP); udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); diff --git a/arch/arm/mach-at91rm9200/clock.h b/arch/arm/mach-at91rm9200/clock.h index 0592e662ab3..b5c7a2eb2d1 100644 --- a/arch/arm/mach-at91rm9200/clock.h +++ b/arch/arm/mach-at91rm9200/clock.h @@ -10,6 +10,7 @@ #define CLK_TYPE_PLL 0x2 #define CLK_TYPE_PROGRAMMABLE 0x4 #define CLK_TYPE_PERIPHERAL 0x8 +#define CLK_TYPE_SYSTEM 0x10 struct clk { diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 5b775fac1c6..67aa5572a3e 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "generic.h" @@ -70,9 +71,15 @@ static int at91_pm_verify_clocks(void) scsr = at91_sys_read(AT91_PMC_SCSR); /* USB must not be using PLLB */ - if ((scsr & (AT91_PMC_UHP | AT91_PMC_UDP)) != 0) { - pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); - return 0; + if (cpu_is_at91rm9200()) { + if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { + pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); + return 0; + } + } else if (cpu_is_at91sam9260()) { +#warning "Check SAM9260 USB clocks" + } else if (cpu_is_at91sam9261()) { +#warning "Check SAM9261 USB clocks" } #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS -- cgit v1.2.3 From 05043d08045271eb5655308371dd285a852ef855 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 11:51:19 +0100 Subject: [ARM] 3960/1: AT91: Final SAM9 intergration patches. This patch includes a number of small changes for integrating the AT91SAM9261 and AT91SAM0260 support. * Can only select support for one AT91 processor at a time. * Remove most of the remaining static memory mapping for the AT91RM9200. * Reserve 1Mb of memory below the IO for mapping the internal SRAM and any custom board-specific devices (ie, FPGA). * The SAM9260 has more serial ports, so increase the maximum to 7. * Define the standard chipselect addresses, and define other addresses relative to those. * CLOCK_TICK_RATE is different on the SAM926x's. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Kconfig | 6 ++++-- arch/arm/mach-at91rm9200/Makefile | 2 +- arch/arm/mach-at91rm9200/at91rm9200.c | 22 +--------------------- 3 files changed, 6 insertions(+), 24 deletions(-) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91rm9200/Kconfig index 2f85e8693b1..8d443264789 100644 --- a/arch/arm/mach-at91rm9200/Kconfig +++ b/arch/arm/mach-at91rm9200/Kconfig @@ -2,7 +2,8 @@ if ARCH_AT91 menu "Atmel AT91 System-on-Chip" -comment "Atmel AT91 Processors" +choice + prompt "Atmel AT91 Processor" config ARCH_AT91RM9200 bool "AT91RM9200" @@ -13,6 +14,8 @@ config ARCH_AT91SAM9260 config ARCH_AT91SAM9261 bool "AT91SAM9261" +endchoice + # ---------------------------------------------------------- if ARCH_AT91RM9200 @@ -33,7 +36,6 @@ config ARCH_AT91RM9200DK Select this if you are using Atmel's AT91RM9200-DK Development board. (Discontinued) - config MACH_AT91RM9200EK bool "Atmel AT91RM9200-EK Evaluation Kit" depends on ARCH_AT91RM9200 diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 6093c31e39a..564ad6e4524 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -10,7 +10,7 @@ obj- := obj-$(CONFIG_PM) += pm.o # CPU-specific support -obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c +obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index 0816a8d2e86..a92e9a495b0 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c @@ -27,33 +27,13 @@ static struct map_desc at91rm9200_io_desc[] __initdata = { .pfn = __phys_to_pfn(AT91_BASE_SYS), .length = SZ_4K, .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_SPI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_SPI), - .length = SZ_16K, - .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_EMAC, .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), .length = SZ_16K, .type = MT_DEVICE, }, { - .virtual = AT91_VA_BASE_TWI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_TWI), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_MCI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_MCI), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_UDP, - .pfn = __phys_to_pfn(AT91RM9200_BASE_UDP), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_SRAM_VIRT_BASE, + .virtual = AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE, .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), .length = AT91RM9200_SRAM_SIZE, .type = MT_DEVICE, -- cgit v1.2.3 From b85a8914033d81077e8276df1956bf3307bb31bd Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 14:37:56 +0100 Subject: [ARM] 3962/1: AT91: Support for Atmel AT91SAM9260-EK board This patch adds support for the Atmel AT91SAM9260-EK board. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 1 + arch/arm/mach-at91rm9200/board-sam9260ek.c | 201 +++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 arch/arm/mach-at91rm9200/board-sam9260ek.c (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 564ad6e4524..cd83c9fb3c7 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o obj-$(CONFIG_MACH_KAFA) += board-kafa.o # AT91SAM9260 board-specific support +obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o # AT91SAM9261 board-specific support diff --git a/arch/arm/mach-at91rm9200/board-sam9260ek.c b/arch/arm/mach-at91rm9200/board-sam9260ek.c new file mode 100644 index 00000000000..ffca9bdec37 --- /dev/null +++ b/arch/arm/mach-at91rm9200/board-sam9260ek.c @@ -0,0 +1,201 @@ +/* + * linux/arch/arm/mach-at91rm9200/board-ek.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + + +/* + * Serial port configuration. + * 0 .. 5 = USART0 .. USART5 + * 6 = DBGU + */ +static struct at91_uart_config __initdata ek_uart_config = { + .console_tty = 0, /* ttyS0 */ + .nr_tty = 3, + .tty_map = { 6, 0, 1, -1, -1, -1, -1 } /* ttyS0, ..., ttyS6 */ +}; + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* Setup the serial ports and console */ + at91_init_serial(&ek_uart_config); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +#if defined(CONFIG_SND_AT73C213) + { /* AT73C213 DAC */ + .modalias = "snd_at73c213", + .chip_select = 0, + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 1, + }, +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct __initdata eth_platform_data ek_macb_data = { + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = 256 * 1024, + }, + { + .name = "Partition 2", + .offset = 256 * 1024, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition *nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 1, + .wire4 = 1, +// .det_pin = ... not connected +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mmc(&ek_mmc_data); +} + +MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") + /* Maintainer: Atmel */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END -- cgit v1.2.3 From 022cbd7376fcdf030fe821636f1c910c45a9356a Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 14:38:59 +0100 Subject: [ARM] 3961/2: AT91: Support for Atmel AT91SAM9261-EK board This patch adds support for the Atmel AT91SAM9261-EK board. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 1 + arch/arm/mach-at91rm9200/board-sam9261ek.c | 259 +++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+) create mode 100644 arch/arm/mach-at91rm9200/board-sam9261ek.c (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index cd83c9fb3c7..cf777007847 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_MACH_KAFA) += board-kafa.o obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o # AT91SAM9261 board-specific support +obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o # LEDs support led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o diff --git a/arch/arm/mach-at91rm9200/board-sam9261ek.c b/arch/arm/mach-at91rm9200/board-sam9261ek.c new file mode 100644 index 00000000000..30b490d8886 --- /dev/null +++ b/arch/arm/mach-at91rm9200/board-sam9261ek.c @@ -0,0 +1,259 @@ +/* + * linux/arch/arm/mach-at91rm9200/board-ek.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + + +/* + * Serial port configuration. + * 0 .. 2 = USART0 .. USART2 + * 3 = DBGU + */ +static struct at91_uart_config __initdata ek_uart_config = { + .console_tty = 0, /* ttyS0 */ + .nr_tty = 1, + .tty_map = { 3, -1, -1, -1 } /* ttyS0, ..., ttyS3 */ +}; + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9261_initialize(18432000); + + /* Setup the serial ports and console */ + at91_init_serial(&ek_uart_config); +} + +static void __init ek_init_irq(void) +{ + at91sam9261_init_interrupts(NULL); +} + + +/* + * DM9000 ethernet device + */ +#if defined(CONFIG_DM9000) +static struct resource at91sam9261_dm9000_resource[] = { + [0] = { + .start = AT91_CHIPSELECT_2, + .end = AT91_CHIPSELECT_2 + 3, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = AT91_CHIPSELECT_2 + 0x44, + .end = AT91_CHIPSELECT_2 + 0xFF, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = AT91_PIN_PC11, + .end = AT91_PIN_PC11, + .flags = IORESOURCE_IRQ + } +}; + +static struct dm9000_plat_data dm9000_platdata = { + .flags = DM9000_PLATF_16BITONLY, +}; + +static struct platform_device at91sam9261_dm9000_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(at91sam9261_dm9000_resource), + .resource = at91sam9261_dm9000_resource, + .dev = { + .platform_data = &dm9000_platdata, + } +}; + +static void __init ek_add_device_dm9000(void) +{ + /* + * Configure Chip-Select 2 on SMC for the DM9000. + * Note: These timings were calculated for MASTER_CLOCK = 100000000 + * according to the DM9000 timings. + */ + 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); + + platform_device_register(&at91sam9261_dm9000_device); +} +#else +static void __init ek_add_device_dm9000(void) {} +#endif /* CONFIG_DM9000 */ + + +/* + * USB Host Port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + + +/* + * USB Device Port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PB29, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .wire4 = 1, +// .det_pin = ... not connected +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = 256 * 1024, + }, + { + .name = "Partition 2", + .offset = 256 * 1024 , + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition *nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 22, + .cle = 21, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC15, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + +/* + * SPI devices + */ +static struct spi_board_info ek_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */ + .modalias = "mtd_dataflash", + .chip_select = 3, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#elif defined(CONFIG_SND_AT73C213) + { /* AT73C213 DAC */ + .modalias = "snd_at73c213", + .chip_select = 3, + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + }, +#endif +}; + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* I2C */ + at91_add_device_i2c(); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* DM9000 ethernet */ + ek_add_device_dm9000(); + + /* spi0 and mmc/sd share the same PIO pins */ +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); +#else + /* MMC */ + at91_add_device_mmc(&ek_mmc_data); +#endif +} + +MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") + /* Maintainer: Atmel */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END -- cgit v1.2.3 From 58a0cd7887cd689ae42540dd12b3b3131abfbe6c Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 14:51:13 +0100 Subject: [ARM] 3963/1: AT91: Update configuration files A number of configuration file changes. These are mainly to replace references to ARCH_AT91RM9200 and ARCH_AT91SAM9261 with the common/generic ARCH_AT91. That way we don't need to mention every specific AT91 processor explicitly. Also adds the configuration option for AT91SAM9260-EK and AT91SAM9261-EK boards. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Kconfig | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91rm9200/Kconfig index 8d443264789..9f11db8af23 100644 --- a/arch/arm/mach-at91rm9200/Kconfig +++ b/arch/arm/mach-at91rm9200/Kconfig @@ -92,6 +92,13 @@ if ARCH_AT91SAM9260 comment "AT91SAM9260 Board Type" +config MACH_AT91SAM9260EK + bool "Atmel AT91SAM9260-EK Evaluation Kit" + depends on ARCH_AT91SAM9260 + help + Select this if you are using Atmel's AT91SAM9260-EK Evaluation Kit. + + endif # ---------------------------------------------------------- @@ -100,8 +107,31 @@ if ARCH_AT91SAM9261 comment "AT91SAM9261 Board Type" +config MACH_AT91SAM9261EK + bool "Atmel AT91SAM9261-EK Evaluation Kit" + depends on ARCH_AT91SAM9261 + help + Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. + + endif +# ---------------------------------------------------------- + +comment "AT91 Board Options" + +config MTD_AT91_DATAFLASH_CARD + bool "Enable DataFlash Card support" + depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK) + help + Enable support for the DataFlash card. + +config MTD_NAND_AT91_BUSWIDTH_16 + bool "Enable 16-bit data bus interface to NAND flash" + depends on (MACH_AT91SAM9261EK || MACH_AT91SAM9260EK) + help + On AT91SAM926x boards both types of NAND flash can be present + (8 and 16 bit data bus width). # ---------------------------------------------------------- -- cgit v1.2.3 From 69c5eccd164200a17b5a24e594b37958d39d2933 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 15:53:20 +0100 Subject: [ARM] 3966/1: AT91: RM9200 device data update This patch contains various updates the at91rm9200_devices.c file: * Consistent naming of resources and platform_devices. * PCMCIA/Compact Flash: Configuration of the memory controller moved out of the driver and into this file. * MMC: Enable the VCC pin (if one is configured) * MMC: Enable the internal pullups on the I/O pins. * NAND: Configuration of the memory controller moved out of the driver and into this file. * Added TWI/I2C resources. * The names of some of the CONFIG_ variables were changed. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200_devices.c | 158 ++++++++++++++++++-------- 1 file changed, 110 insertions(+), 48 deletions(-) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/at91rm9200_devices.c b/arch/arm/mach-at91rm9200/at91rm9200_devices.c index 2b3a23605bf..4641b99db0e 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200_devices.c +++ b/arch/arm/mach-at91rm9200/at91rm9200_devices.c @@ -15,9 +15,10 @@ #include -#include #include #include +#include +#include #include "generic.h" @@ -33,7 +34,7 @@ static u64 ohci_dmamask = 0xffffffffUL; static struct at91_usbh_data usbh_data; -static struct resource at91_usbh_resources[] = { +static struct resource usbh_resources[] = { [0] = { .start = AT91RM9200_UHP_BASE, .end = AT91RM9200_UHP_BASE + SZ_1M - 1, @@ -54,8 +55,8 @@ static struct platform_device at91rm9200_usbh_device = { .coherent_dma_mask = 0xffffffff, .platform_data = &usbh_data, }, - .resource = at91_usbh_resources, - .num_resources = ARRAY_SIZE(at91_usbh_resources), + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), }; void __init at91_add_device_usbh(struct at91_usbh_data *data) @@ -78,7 +79,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} #ifdef CONFIG_USB_GADGET_AT91 static struct at91_udc_data udc_data; -static struct resource at91_udc_resources[] = { +static struct resource udc_resources[] = { [0] = { .start = AT91RM9200_BASE_UDP, .end = AT91RM9200_BASE_UDP + SZ_16K - 1, @@ -97,8 +98,8 @@ static struct platform_device at91rm9200_udc_device = { .dev = { .platform_data = &udc_data, }, - .resource = at91_udc_resources, - .num_resources = ARRAY_SIZE(at91_udc_resources), + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), }; void __init at91_add_device_udc(struct at91_udc_data *data) @@ -129,7 +130,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} static u64 eth_dmamask = 0xffffffffUL; static struct at91_eth_data eth_data; -static struct resource at91_eth_resources[] = { +static struct resource eth_resources[] = { [0] = { .start = AT91_VA_BASE_EMAC, .end = AT91_VA_BASE_EMAC + SZ_16K - 1, @@ -150,8 +151,8 @@ static struct platform_device at91rm9200_eth_device = { .coherent_dma_mask = 0xffffffff, .platform_data = ð_data, }, - .resource = at91_eth_resources, - .num_resources = ARRAY_SIZE(at91_eth_resources), + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), }; void __init at91_add_device_eth(struct at91_eth_data *data) @@ -202,11 +203,13 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {} #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) static struct at91_cf_data cf_data; -static struct resource at91_cf_resources[] = { +#define CF_BASE AT91_CHIPSELECT_4 + +static struct resource cf_resources[] = { [0] = { - .start = AT91_CF_BASE, + .start = CF_BASE, /* ties up CS4, CS5 and CS6 */ - .end = AT91_CF_BASE + (0x30000000 - 1), + .end = CF_BASE + (0x30000000 - 1), .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, }, }; @@ -217,15 +220,38 @@ static struct platform_device at91rm9200_cf_device = { .dev = { .platform_data = &cf_data, }, - .resource = at91_cf_resources, - .num_resources = ARRAY_SIZE(at91_cf_resources), + .resource = cf_resources, + .num_resources = ARRAY_SIZE(cf_resources), }; void __init at91_add_device_cf(struct at91_cf_data *data) { + unsigned int csa; + if (!data) return; + data->chipselect = 4; /* can only use EBI ChipSelect 4 */ + + /* CF takes over CS4, CS5, CS6 */ + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); + + /* + * Static memory controller timing adjustments. + * REVISIT: these timings are in terms of MCK cycles, so + * when MCK changes (cpufreq etc) so must these values... + */ + at91_sys_write(AT91_SMC_CSR(4), + AT91_SMC_ACSS_STD + | AT91_SMC_DBW_16 + | AT91_SMC_BAT + | AT91_SMC_WSEN + | AT91_SMC_NWS_(32) /* wait states */ + | AT91_SMC_RWSETUP_(6) /* setup time */ + | AT91_SMC_RWHOLD_(4) /* hold time */ + ); + /* input/irq */ if (data->irq_pin) { at91_set_gpio_input(data->irq_pin, 1); @@ -245,6 +271,9 @@ void __init at91_add_device_cf(struct at91_cf_data *data) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ + /* nWAIT is _not_ a default setting */ + at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ + cf_data = *data; platform_device_register(&at91rm9200_cf_device); } @@ -257,11 +286,11 @@ void __init at91_add_device_cf(struct at91_cf_data *data) {} * MMC / SD * -------------------------------------------------------------------- */ -#if defined(CONFIG_MMC_AT91RM9200) || defined(CONFIG_MMC_AT91RM9200_MODULE) +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) static u64 mmc_dmamask = 0xffffffffUL; static struct at91_mmc_data mmc_data; -static struct resource at91_mmc_resources[] = { +static struct resource mmc_resources[] = { [0] = { .start = AT91RM9200_BASE_MCI, .end = AT91RM9200_BASE_MCI + SZ_16K - 1, @@ -282,8 +311,8 @@ static struct platform_device at91rm9200_mmc_device = { .coherent_dma_mask = 0xffffffff, .platform_data = &mmc_data, }, - .resource = at91_mmc_resources, - .num_resources = ARRAY_SIZE(at91_mmc_resources), + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), }; void __init at91_add_device_mmc(struct at91_mmc_data *data) @@ -298,31 +327,33 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data) } if (data->wp_pin) at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ at91_set_A_periph(AT91_PIN_PA27, 0); - if (data->is_b) { + if (data->slot_b) { /* CMD */ - at91_set_B_periph(AT91_PIN_PA8, 0); + at91_set_B_periph(AT91_PIN_PA8, 1); /* DAT0, maybe DAT1..DAT3 */ - at91_set_B_periph(AT91_PIN_PA9, 0); + at91_set_B_periph(AT91_PIN_PA9, 1); if (data->wire4) { - at91_set_B_periph(AT91_PIN_PA10, 0); - at91_set_B_periph(AT91_PIN_PA11, 0); - at91_set_B_periph(AT91_PIN_PA12, 0); + at91_set_B_periph(AT91_PIN_PA10, 1); + at91_set_B_periph(AT91_PIN_PA11, 1); + at91_set_B_periph(AT91_PIN_PA12, 1); } } else { /* CMD */ - at91_set_A_periph(AT91_PIN_PA28, 0); + at91_set_A_periph(AT91_PIN_PA28, 1); /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA29, 0); + at91_set_A_periph(AT91_PIN_PA29, 1); if (data->wire4) { - at91_set_B_periph(AT91_PIN_PB3, 0); - at91_set_B_periph(AT91_PIN_PB4, 0); - at91_set_B_periph(AT91_PIN_PB5, 0); + at91_set_B_periph(AT91_PIN_PB3, 1); + at91_set_B_periph(AT91_PIN_PB4, 1); + at91_set_B_periph(AT91_PIN_PB5, 1); } } @@ -341,29 +372,45 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data) {} #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) static struct at91_nand_data nand_data; -static struct resource at91_nand_resources[] = { +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { { - .start = AT91_SMARTMEDIA_BASE, - .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1, + .start = NAND_BASE, + .end = NAND_BASE + SZ_8M - 1, .flags = IORESOURCE_MEM, } }; -static struct platform_device at91_nand_device = { +static struct platform_device at91rm9200_nand_device = { .name = "at91_nand", .id = -1, .dev = { .platform_data = &nand_data, }, - .resource = at91_nand_resources, - .num_resources = ARRAY_SIZE(at91_nand_resources), + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), }; void __init at91_add_device_nand(struct at91_nand_data *data) { + unsigned int csa; + if (!data) return; + /* enable the address range of CS3 */ + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); + + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN + | AT91_SMC_NWS_(5) + | AT91_SMC_TDF_(1) + | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */ + | AT91_SMC_RWHOLD_(1) /* tDH Data Hold Time 20 - ns */ + ); + /* enable pin */ if (data->enable_pin) at91_set_gpio_output(data->enable_pin, 1); @@ -380,7 +427,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ nand_data = *data; - platform_device_register(&at91_nand_device); + platform_device_register(&at91rm9200_nand_device); } #else void __init at91_add_device_nand(struct at91_nand_data *data) {} @@ -392,10 +439,25 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91RM9200_BASE_TWI, + .end = AT91RM9200_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_TWI, + .end = AT91RM9200_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + static struct platform_device at91rm9200_twi_device = { .name = "at91_i2c", .id = -1, - .num_resources = 0, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), }; void __init at91_add_device_i2c(void) @@ -421,7 +483,7 @@ void __init at91_add_device_i2c(void) {} #if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) static u64 spi_dmamask = 0xffffffffUL; -static struct resource at91_spi_resources[] = { +static struct resource spi_resources[] = { [0] = { .start = AT91RM9200_BASE_SPI, .end = AT91RM9200_BASE_SPI + SZ_16K - 1, @@ -438,14 +500,14 @@ static struct platform_device at91rm9200_spi_device = { .name = "at91_spi", .id = 0, .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = 0xffffffff, + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, }, - .resource = at91_spi_resources, - .num_resources = ARRAY_SIZE(at91_spi_resources), + .resource = spi_resources, + .num_resources = ARRAY_SIZE(spi_resources), }; -static const unsigned at91_spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; +static const unsigned spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) { @@ -461,7 +523,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) if (devices[i].controller_data) cs_pin = (unsigned long) devices[i].controller_data; else - cs_pin = at91_spi_standard_cs[devices[i].chip_select]; + cs_pin = spi_standard_cs[devices[i].chip_select]; #ifdef CONFIG_SPI_AT91_MANUAL_CS at91_set_gpio_output(cs_pin, 1); @@ -474,7 +536,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) } spi_register_board_info(devices, nr_devices); - at91_clock_associate("spi0_clk", &at91rm9200_spi_device.dev, "spi"); + at91_clock_associate("spi_clk", &at91rm9200_spi_device.dev, "spi"); platform_device_register(&at91rm9200_spi_device); } #else @@ -486,7 +548,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) * RTC * -------------------------------------------------------------------- */ -#if defined(CONFIG_RTC_DRV_AT91) || defined(CONFIG_RTC_DRV_AT91_MODULE) +#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) static struct platform_device at91rm9200_rtc_device = { .name = "at91_rtc", .id = -1, @@ -506,7 +568,7 @@ static void __init at91_add_device_rtc(void) {} * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91_WATCHDOG) || defined(CONFIG_AT91_WATCHDOG_MODULE) +#if defined(CONFIG_AT91RM9200_WATCHDOG) || defined(CONFIG_AT91RM9200_WATCHDOG_MODULE) static struct platform_device at91rm9200_wdt_device = { .name = "at91_wdt", .id = -1, -- cgit v1.2.3 From c019d49b69237f195b1a31d90facf738a371841f Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Mon, 4 Dec 2006 09:09:08 +0100 Subject: [ARM] 3972/1: AT91: Update board.h Replace the 'is_b' variable with 'slot_b' in at91_mmc_data. Also add the new 'chipselect' variable for CF/PCMCIA and 'bus_width_16' variable for NAND. This (and previous patches) will unfortunately break the current MMC, USB Gadget and PCMCIA drivers. Updates and fixes for those drivers will be submitted to the various subsystem maintainers. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/board-carmeva.c | 2 +- arch/arm/mach-at91rm9200/board-csb337.c | 2 +- arch/arm/mach-at91rm9200/board-dk.c | 2 +- arch/arm/mach-at91rm9200/board-eb9200.c | 2 +- arch/arm/mach-at91rm9200/board-ek.c | 2 +- arch/arm/mach-at91rm9200/board-kb9202.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-at91rm9200') diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91rm9200/board-carmeva.c index 5cd68e6001e..654f0379550 100644 --- a/arch/arm/mach-at91rm9200/board-carmeva.c +++ b/arch/arm/mach-at91rm9200/board-carmeva.c @@ -88,7 +88,7 @@ static struct at91_udc_data __initdata carmeva_udc_data = { // }; static struct at91_mmc_data __initdata carmeva_mmc_data = { - .is_b = 0, + .slot_b = 0, .wire4 = 1, .det_pin = AT91_PIN_PB10, .wp_pin = AT91_PIN_PC14, diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c index 8eeae491ce7..b8bb8052607 100644 --- a/arch/arm/mach-at91rm9200/board-csb337.c +++ b/arch/arm/mach-at91rm9200/board-csb337.c @@ -99,7 +99,7 @@ static struct at91_cf_data __initdata csb337_cf_data = { static struct at91_mmc_data __initdata csb337_mmc_data = { .det_pin = AT91_PIN_PD5, - .is_b = 0, + .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PD6, }; diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index 314e1f769ea..7522bf91bce 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c @@ -95,7 +95,7 @@ static struct at91_cf_data __initdata dk_cf_data = { }; static struct at91_mmc_data __initdata dk_mmc_data = { - .is_b = 0, + .slot_b = 0, .wire4 = 1, }; diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91rm9200/board-eb9200.c index 65e867ba2df..80b72cf7264 100644 --- a/arch/arm/mach-at91rm9200/board-eb9200.c +++ b/arch/arm/mach-at91rm9200/board-eb9200.c @@ -87,7 +87,7 @@ static struct at91_cf_data __initdata eb9200_cf_data = { }; static struct at91_mmc_data __initdata eb9200_mmc_data = { - .is_b = 0, + .slot_b = 0, .wire4 = 1, }; diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index 9fcfa066635..c4fdb415f20 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c @@ -89,7 +89,7 @@ static struct at91_udc_data __initdata ek_udc_data = { static struct at91_mmc_data __initdata ek_mmc_data = { .det_pin = AT91_PIN_PB27, - .is_b = 0, + .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PA17, }; diff --git a/arch/arm/mach-at91rm9200/board-kb9202.c b/arch/arm/mach-at91rm9200/board-kb9202.c index 35a954a44b1..759d8191854 100644 --- a/arch/arm/mach-at91rm9200/board-kb9202.c +++ b/arch/arm/mach-at91rm9200/board-kb9202.c @@ -84,7 +84,7 @@ static struct at91_udc_data __initdata kb9202_udc_data = { static struct at91_mmc_data __initdata kb9202_mmc_data = { .det_pin = AT91_PIN_PB2, - .is_b = 0, + .slot_b = 0, .wire4 = 1, }; -- cgit v1.2.3