aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r--arch/arm/mach-at91/Kconfig33
-rw-r--r--arch/arm/mach-at91/Makefile3
-rw-r--r--arch/arm/mach-at91/at91cap9.c9
-rw-r--r--arch/arm/mach-at91/at91cap9_devices.c70
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c92
-rw-r--r--arch/arm/mach-at91/at91sam9260.c8
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c159
-rw-r--r--arch/arm/mach-at91/at91sam9261.c8
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c102
-rw-r--r--arch/arm/mach-at91/at91sam9263.c8
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c98
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c171
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c8
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c117
-rw-r--r--arch/arm/mach-at91/board-cam60.c180
-rw-r--r--arch/arm/mach-at91/board-cap9adk.c2
-rw-r--r--arch/arm/mach-at91/board-csb337.c18
-rw-r--r--arch/arm/mach-at91/board-csb637.c30
-rw-r--r--arch/arm/mach-at91/board-ecbat91.c178
-rw-r--r--arch/arm/mach-at91/board-sam9-l9260.c199
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c83
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c83
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c25
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c23
-rwxr-xr-xarch/arm/mach-at91/board-yl-9200.c683
-rw-r--r--arch/arm/mach-at91/pm.c165
26 files changed, 2183 insertions, 372 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 074dcd5d9a7e..0fc07b6db749 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -12,18 +12,28 @@ config ARCH_AT91RM9200
config ARCH_AT91SAM9260
bool "AT91SAM9260 or AT91SAM9XE"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
config ARCH_AT91SAM9261
bool "AT91SAM9261"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
config ARCH_AT91SAM9263
bool "AT91SAM9263"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
config ARCH_AT91CAP9
bool "AT91CAP9"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
config ARCH_AT91X40
bool "AT91x40"
@@ -109,6 +119,13 @@ config MACH_KAFA
help
Select this if you are using Sperry-Sun's KAFA board.
+config MACH_ECBAT91
+ bool "emQbit ECB_AT91 SBC"
+ depends on ARCH_AT91RM9200
+ help
+ Select this if you are using emQbit's ECB_AT91 board.
+ <http://wiki.emqbit.com/free-ecb-at91>
+
endif
# ----------------------------------------------------------
@@ -133,6 +150,20 @@ config MACH_AT91SAM9260EK
Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit
<http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933>
+config MACH_CAM60
+ bool "KwikByte KB9260 (CAM60) board"
+ depends on ARCH_AT91SAM9260
+ help
+ Select this if you are using KwikByte's KB9260 (CAM60) board based on the Atmel AT91SAM9260.
+ <http://www.kwikbyte.com/KB9260.html>
+
+config MACH_SAM9_L9260
+ bool "Olimex SAM9-L9260 board"
+ depends on ARCH_AT91SAM9260
+ help
+ Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260.
+ <http://www.olimex.com/dev/sam9-L9260.html>
+
endif
# ----------------------------------------------------------
@@ -216,7 +247,7 @@ comment "AT91 Board Options"
config MTD_AT91_DATAFLASH_CARD
bool "Enable DataFlash Card support"
- depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK)
+ depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK || MACH_SAM9_L9260 || MACH_ECBAT91)
help
Enable support for the DataFlash card.
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index bf5f293dccf8..8d9bc0153b18 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -29,9 +29,12 @@ obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
obj-$(CONFIG_MACH_KAFA) += board-kafa.o
obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
+obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o
# AT91SAM9260 board-specific support
obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
+obj-$(CONFIG_MACH_CAM60) += board-cam60.o
+obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o
# AT91SAM9261 board-specific support
obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
index 48d27d8000b0..933fa8f55cbc 100644
--- a/arch/arm/mach-at91/at91cap9.c
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -13,12 +13,14 @@
*/
#include <linux/module.h>
+#include <linux/pm.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/at91cap9.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_shdwc.h>
#include "generic.h"
#include "clock.h"
@@ -288,6 +290,12 @@ static void at91cap9_reset(void)
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
}
+static void at91cap9_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+
/* --------------------------------------------------------------------
* AT91CAP9 processor initialization
* -------------------------------------------------------------------- */
@@ -298,6 +306,7 @@ void __init at91cap9_initialize(unsigned long main_clock)
iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc));
at91_arch_reset = at91cap9_reset;
+ pm_power_off = at91cap9_poweroff;
at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
/* Init clock subsystem */
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
index c50fad9cd143..f1a80d74a4b6 100644
--- a/arch/arm/mach-at91/at91cap9_devices.c
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -16,15 +16,15 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
+#include <linux/i2c-gpio.h>
#include <video/atmel_lcdc.h>
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91cap9.h>
-#include <asm/arch/at91sam926x_mc.h>
#include <asm/arch/at91cap9_matrix.h>
+#include <asm/arch/at91sam9_smc.h>
#include "generic.h"
@@ -283,10 +283,15 @@ static struct at91_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3
static struct resource nand_resources[] = {
- {
+ [0] = {
.start = NAND_BASE,
.end = NAND_BASE + SZ_256M - 1,
.flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
}
};
@@ -344,6 +349,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data)
void __init at91_add_device_nand(struct at91_nand_data *data) {}
#endif
+
/* --------------------------------------------------------------------
* TWI (i2c)
* -------------------------------------------------------------------- */
@@ -532,13 +538,59 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_TCB0,
+ .end = AT91CAP9_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_TCB,
+ .end = AT91CAP9_ID_TCB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_tcb_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb_resources,
+ .num_resources = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ /* this chip has one clock and irq for all three TC channels */
+ at91_clock_associate("tcb_clk", &at91cap9_tcb_device.dev, "t0_clk");
+ platform_device_register(&at91cap9_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
* RTT
* -------------------------------------------------------------------- */
+static struct resource rtt_resources[] = {
+ {
+ .start = AT91_BASE_SYS + AT91_RTT,
+ .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
static struct platform_device at91cap9_rtt_device = {
.name = "at91_rtt",
- .id = -1,
- .num_resources = 0,
+ .id = 0,
+ .resource = rtt_resources,
+ .num_resources = ARRAY_SIZE(rtt_resources),
};
static void __init at91_add_device_rtt(void)
@@ -990,7 +1042,7 @@ static inline void configure_usart2_pins(unsigned pins)
at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
}
-static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
@@ -1031,8 +1083,6 @@ void __init at91_set_serial_console(unsigned portnr)
{
if (portnr < ATMEL_MAX_UART)
atmel_default_console_device = at91_uarts[portnr];
- if (!atmel_default_console_device)
- printk(KERN_INFO "AT91: No default serial console defined.\n");
}
void __init at91_add_device_serial(void)
@@ -1043,6 +1093,9 @@ void __init at91_add_device_serial(void)
if (at91_uarts[i])
platform_device_register(at91_uarts[i]);
}
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
}
#else
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
@@ -1060,6 +1113,7 @@ static int __init at91_add_standard_devices(void)
{
at91_add_device_rtt();
at91_add_device_watchdog();
+ at91_add_device_tc();
return 0;
}
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index ef6aeb86e980..de19bee83f75 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -577,6 +577,90 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
/* --------------------------------------------------------------------
+ * Timer/Counter blocks
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb0_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_TCB0,
+ .end = AT91RM9200_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_TC0,
+ .end = AT91RM9200_ID_TC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91RM9200_ID_TC1,
+ .end = AT91RM9200_ID_TC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91RM9200_ID_TC2,
+ .end = AT91RM9200_ID_TC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_tcb0_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb0_resources,
+ .num_resources = ARRAY_SIZE(tcb0_resources),
+};
+
+static struct resource tcb1_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_TCB1,
+ .end = AT91RM9200_BASE_TCB1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_TC3,
+ .end = AT91RM9200_ID_TC3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91RM9200_ID_TC4,
+ .end = AT91RM9200_ID_TC4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91RM9200_ID_TC5,
+ .end = AT91RM9200_ID_TC5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_tcb1_device = {
+ .name = "atmel_tcb",
+ .id = 1,
+ .resource = tcb1_resources,
+ .num_resources = ARRAY_SIZE(tcb1_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ /* this chip has a separate clock and irq for each TC channel */
+ at91_clock_associate("tc0_clk", &at91rm9200_tcb0_device.dev, "t0_clk");
+ at91_clock_associate("tc1_clk", &at91rm9200_tcb0_device.dev, "t1_clk");
+ at91_clock_associate("tc2_clk", &at91rm9200_tcb0_device.dev, "t2_clk");
+ platform_device_register(&at91rm9200_tcb0_device);
+
+ at91_clock_associate("tc3_clk", &at91rm9200_tcb1_device.dev, "t0_clk");
+ at91_clock_associate("tc4_clk", &at91rm9200_tcb1_device.dev, "t1_clk");
+ at91_clock_associate("tc5_clk", &at91rm9200_tcb1_device.dev, "t2_clk");
+ platform_device_register(&at91rm9200_tcb1_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
* RTC
* -------------------------------------------------------------------- */
@@ -1019,7 +1103,7 @@ static inline void configure_usart3_pins(unsigned pins)
at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS3 */
}
-static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */
void __init __deprecated at91_init_serial(struct at91_uart_config *config)
@@ -1110,8 +1194,6 @@ void __init at91_set_serial_console(unsigned portnr)
{
if (portnr < ATMEL_MAX_UART)
atmel_default_console_device = at91_uarts[portnr];
- if (!atmel_default_console_device)
- printk(KERN_INFO "AT91: No default serial console defined.\n");
}
void __init at91_add_device_serial(void)
@@ -1122,6 +1204,9 @@ void __init at91_add_device_serial(void)
if (at91_uarts[i])
platform_device_register(at91_uarts[i]);
}
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
}
#else
void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
@@ -1141,6 +1226,7 @@ static int __init at91_add_standard_devices(void)
{
at91_add_device_rtc();
at91_add_device_watchdog();
+ at91_add_device_tc();
return 0;
}
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 18d06612ce8a..ee26550cdc21 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/pm.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -18,6 +19,7 @@
#include <asm/arch/at91sam9260.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_shdwc.h>
#include "generic.h"
#include "clock.h"
@@ -267,6 +269,11 @@ static void at91sam9260_reset(void)
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
}
+static void at91sam9260_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
/* --------------------------------------------------------------------
* AT91SAM9260 processor initialization
@@ -304,6 +311,7 @@ void __init at91sam9260_initialize(unsigned long main_clock)
iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
at91_arch_reset = at91sam9260_reset;
+ pm_power_off = at91sam9260_poweroff;
at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
| (1 << AT91SAM9260_ID_IRQ2);
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 105f8403860b..393a32aefce5 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -19,8 +19,8 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91sam9260.h>
-#include <asm/arch/at91sam926x_mc.h>
#include <asm/arch/at91sam9260_matrix.h>
+#include <asm/arch/at91sam9_smc.h>
#include "generic.h"
@@ -288,10 +288,15 @@ static struct at91_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3
static struct resource nand_resources[] = {
- {
+ [0] = {
.start = NAND_BASE,
.end = NAND_BASE + SZ_256M - 1,
.flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
}
};
@@ -540,6 +545,90 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
/* --------------------------------------------------------------------
+ * Timer/Counter blocks
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb0_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_TCB0,
+ .end = AT91SAM9260_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_TC0,
+ .end = AT91SAM9260_ID_TC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91SAM9260_ID_TC1,
+ .end = AT91SAM9260_ID_TC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91SAM9260_ID_TC2,
+ .end = AT91SAM9260_ID_TC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_tcb0_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb0_resources,
+ .num_resources = ARRAY_SIZE(tcb0_resources),
+};
+
+static struct resource tcb1_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_TCB1,
+ .end = AT91SAM9260_BASE_TCB1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_TC3,
+ .end = AT91SAM9260_ID_TC3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91SAM9260_ID_TC4,
+ .end = AT91SAM9260_ID_TC4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91SAM9260_ID_TC5,
+ .end = AT91SAM9260_ID_TC5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_tcb1_device = {
+ .name = "atmel_tcb",
+ .id = 1,
+ .resource = tcb1_resources,
+ .num_resources = ARRAY_SIZE(tcb1_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ /* this chip has a separate clock and irq for each TC channel */
+ at91_clock_associate("tc0_clk", &at91sam9260_tcb0_device.dev, "t0_clk");
+ at91_clock_associate("tc1_clk", &at91sam9260_tcb0_device.dev, "t1_clk");
+ at91_clock_associate("tc2_clk", &at91sam9260_tcb0_device.dev, "t2_clk");
+ platform_device_register(&at91sam9260_tcb0_device);
+
+ at91_clock_associate("tc3_clk", &at91sam9260_tcb1_device.dev, "t0_clk");
+ at91_clock_associate("tc4_clk", &at91sam9260_tcb1_device.dev, "t1_clk");
+ at91_clock_associate("tc5_clk", &at91sam9260_tcb1_device.dev, "t2_clk");
+ platform_device_register(&at91sam9260_tcb1_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
* RTT
* -------------------------------------------------------------------- */
@@ -553,7 +642,7 @@ static struct resource rtt_resources[] = {
static struct platform_device at91sam9260_rtt_device = {
.name = "at91_rtt",
- .id = -1,
+ .id = 0,
.resource = rtt_resources,
.num_resources = ARRAY_SIZE(rtt_resources),
};
@@ -962,64 +1051,9 @@ static inline void configure_usart5_pins(void)
at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */
}
-static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */
-void __init __deprecated 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(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
- at91_uarts[i] = &at91sam9260_uart0_device;
- at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart");
- break;
- case 1:
- configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
- at91_uarts[i] = &at91sam9260_uart1_device;
- at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart");
- break;
- case 2:
- configure_usart2_pins(0);
- at91_uarts[i] = &at91sam9260_uart2_device;
- at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart");
- break;
- case 3:
- configure_usart3_pins(0);
- 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_register_uart(unsigned id, unsigned portnr, unsigned pins)
{
struct platform_device *pdev;
@@ -1073,8 +1107,6 @@ void __init at91_set_serial_console(unsigned portnr)
{
if (portnr < ATMEL_MAX_UART)
atmel_default_console_device = at91_uarts[portnr];
- if (!atmel_default_console_device)
- printk(KERN_INFO "AT91: No default serial console defined.\n");
}
void __init at91_add_device_serial(void)
@@ -1085,9 +1117,11 @@ void __init at91_add_device_serial(void)
if (at91_uarts[i])
platform_device_register(at91_uarts[i]);
}
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
}
#else
-void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
void __init at91_set_serial_console(unsigned portnr) {}
void __init at91_add_device_serial(void) {}
@@ -1103,6 +1137,7 @@ static int __init at91_add_standard_devices(void)
{
at91_add_device_rtt();
at91_add_device_watchdog();
+ at91_add_device_tc();
return 0;
}
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 90b87e1877d9..35bf6fd52516 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -11,12 +11,14 @@
*/
#include <linux/module.h>
+#include <linux/pm.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/at91sam9261.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_shdwc.h>
#include "generic.h"
#include "clock.h"
@@ -245,6 +247,11 @@ static void at91sam9261_reset(void)
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
}
+static void at91sam9261_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
/* --------------------------------------------------------------------
* AT91SAM9261 processor initialization
@@ -256,6 +263,7 @@ void __init at91sam9261_initialize(unsigned long main_clock)
iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
at91_arch_reset = at91sam9261_reset;
+ pm_power_off = at91sam9261_poweroff;
at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
| (1 << AT91SAM9261_ID_IRQ2);
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 245641263fce..37cd547855b1 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -24,7 +24,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/at91sam9261.h>
#include <asm/arch/at91sam9261_matrix.h>
-#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9_smc.h>
#include "generic.h"
@@ -548,6 +548,55 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_TCB0,
+ .end = AT91SAM9261_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_TC0,
+ .end = AT91SAM9261_ID_TC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91SAM9261_ID_TC1,
+ .end = AT91SAM9261_ID_TC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91SAM9261_ID_TC2,
+ .end = AT91SAM9261_ID_TC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_tcb_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb_resources,
+ .num_resources = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ /* this chip has a separate clock and irq for each TC channel */
+ at91_clock_associate("tc0_clk", &at91sam9261_tcb_device.dev, "t0_clk");
+ at91_clock_associate("tc1_clk", &at91sam9261_tcb_device.dev, "t1_clk");
+ at91_clock_associate("tc2_clk", &at91sam9261_tcb_device.dev, "t2_clk");
+ platform_device_register(&at91sam9261_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
* RTT
* -------------------------------------------------------------------- */
@@ -561,7 +610,7 @@ static struct resource rtt_resources[] = {
static struct platform_device at91sam9261_rtt_device = {
.name = "at91_rtt",
- .id = -1,
+ .id = 0,
.resource = rtt_resources,
.num_resources = ARRAY_SIZE(rtt_resources),
};
@@ -938,49 +987,9 @@ static inline void configure_usart2_pins(unsigned pins)
at91_set_B_periph(AT91_PIN_PA16, 0); /* CTS2 */
}
-static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */
-void __init __deprecated 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(ATMEL_UART_CTS | ATMEL_UART_RTS);
- at91_uarts[i] = &at91sam9261_uart0_device;
- at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart");
- break;
- case 1:
- configure_usart1_pins(0);
- at91_uarts[i] = &at91sam9261_uart1_device;
- at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart");
- break;
- case 2:
- configure_usart2_pins(0);
- 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_register_uart(unsigned id, unsigned portnr, unsigned pins)
{
struct platform_device *pdev;
@@ -1019,8 +1028,6 @@ void __init at91_set_serial_console(unsigned portnr)
{
if (portnr < ATMEL_MAX_UART)
atmel_default_console_device = at91_uarts[portnr];
- if (!atmel_default_console_device)
- printk(KERN_INFO "AT91: No default serial console defined.\n");
}
void __init at91_add_device_serial(void)
@@ -1031,9 +1038,11 @@ void __init at91_add_device_serial(void)
if (at91_uarts[i])
platform_device_register(at91_uarts[i]);
}
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
}
#else
-void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
void __init at91_set_serial_console(unsigned portnr) {}
void __init at91_add_device_serial(void) {}
@@ -1050,6 +1059,7 @@ static int __init at91_add_standard_devices(void)
{
at91_add_device_rtt();
at91_add_device_watchdog();
+ at91_add_device_tc();
return 0;
}
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index a53ba0f74351..052074a9f2d3 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -11,12 +11,14 @@
*/
#include <linux/module.h>
+#include <linux/pm.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/at91sam9263.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_shdwc.h>
#include "generic.h"
#include "clock.h"
@@ -271,6 +273,11 @@ static void at91sam9263_reset(void)
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
}
+static void at91sam9263_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
/* --------------------------------------------------------------------
* AT91SAM9263 processor initialization
@@ -282,6 +289,7 @@ void __init at91sam9263_initialize(unsigned long main_clock)
iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc));
at91_arch_reset = at91sam9263_reset;
+ pm_power_off = at91sam9263_poweroff;
at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
/* Init clock subsystem */
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 0b12e1adcc8e..b6454c525962 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -22,8 +22,8 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91sam9263.h>
-#include <asm/arch/at91sam926x_mc.h>
#include <asm/arch/at91sam9263_matrix.h>
+#include <asm/arch/at91sam9_smc.h>
#include "generic.h"
@@ -358,10 +358,15 @@ static struct at91_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3
static struct resource nand_resources[] = {
- {
+ [0] = {
.start = NAND_BASE,
.end = NAND_BASE + SZ_256M - 1,
.flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC0,
+ .end = AT91_BASE_SYS + AT91_ECC0 + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
}
};
@@ -783,6 +788,43 @@ void __init at91_add_device_isi(void) {}
/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_TCB0,
+ .end = AT91SAM9263_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_TCB,
+ .end = AT91SAM9263_ID_TCB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_tcb_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb_resources,
+ .num_resources = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ /* this chip has one clock and irq for all three TC channels */
+ at91_clock_associate("tcb_clk", &at91sam9263_tcb_device.dev, "t0_clk");
+ platform_device_register(&at91sam9263_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
* RTT
* -------------------------------------------------------------------- */
@@ -933,9 +975,6 @@ static inline void configure_ssc1_pins(unsigned pins)
}
/*
- * Return the device node so that board init code can use it as the
- * parent for the device node reflecting how it's used on this board.
- *
* SSC controllers are accessed through library code, instead of any
* kind of all-singing/all-dancing driver. For example one could be
* used by a particular I2S audio codec's driver, while another one
@@ -1146,49 +1185,9 @@ static inline void configure_usart2_pins(unsigned pins)
at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
}
-static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */
-void __init __deprecated 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(ATMEL_UART_CTS | ATMEL_UART_RTS);
- at91_uarts[i] = &at91sam9263_uart0_device;
- at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart");
- break;
- case 1:
- configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
- at91_uarts[i] = &at91sam9263_uart1_device;
- at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart");
- break;
- case 2:
- configure_usart2_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
- at91_uarts[i] = &at91sam9263_uart2_device;
- at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart");
- break;
- case 3:
- configure_dbgu_pins();
- at91_uarts[i] = &at91sam9263_dbgu_device;
- at91_clock_associate("mck", &at91sam9263_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_register_uart(unsigned id, unsigned portnr, unsigned pins)
{
struct platform_device *pdev;
@@ -1227,8 +1226,6 @@ void __init at91_set_serial_console(unsigned portnr)
{
if (portnr < ATMEL_MAX_UART)
atmel_default_console_device = at91_uarts[portnr];
- if (!atmel_default_console_device)
- printk(KERN_INFO "AT91: No default serial console defined.\n");
}
void __init at91_add_device_serial(void)
@@ -1239,9 +1236,11 @@ void __init at91_add_device_serial(void)
if (at91_uarts[i])
platform_device_register(at91_uarts[i]);
}
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
}
#else
-void __init at91_init_serial(struct at91_uart_config *config) {}
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
void __init at91_set_serial_console(unsigned portnr) {}
void __init at91_add_device_serial(void) {}
@@ -1257,6 +1256,7 @@ static int __init at91_add_standard_devices(void)
{
at91_add_device_rtt();
at91_add_device_watchdog();
+ at91_add_device_tc();
return 0;
}
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index e38d23770992..5cecbd7de6a6 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -1,23 +1,20 @@
/*
- * linux/arch/arm/mach-at91/at91sam926x_time.c
+ * at91sam926x_time.c - Periodic Interval Timer (PIT) for at91sam926x
*
* Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France
* Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France
+ * Converted to ClockSource/ClockEvents by David Brownell.
*
* 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 <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
#include <asm/mach/time.h>
#include <asm/arch/at91_pit.h>
@@ -26,85 +23,167 @@
#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
+static u32 pit_cycle; /* write-once */
+static u32 pit_cnt; /* access only w/system irq blocked */
+
+
/*
- * 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.
+ * Clocksource: just a monotonic counter of MCK/16 cycles.
+ * We don't care whether or not PIT irqs are enabled.
*/
-static unsigned long at91sam926x_gettimeoffset(void)
+static cycle_t read_pit_clk(void)
{
- unsigned long elapsed;
- unsigned long t = at91_sys_read(AT91_PIT_PIIR);
+ unsigned long flags;
+ u32 elapsed;
+ u32 t;
+
+ raw_local_irq_save(flags);
+ elapsed = pit_cnt;
+ t = at91_sys_read(AT91_PIT_PIIR);
+ raw_local_irq_restore(flags);
+
+ elapsed += PIT_PICNT(t) * pit_cycle;
+ elapsed += PIT_CPIV(t);
+ return elapsed;
+}
+
+static struct clocksource pit_clk = {
+ .name = "pit",
+ .rating = 175,
+ .read = read_pit_clk,
+ .shift = 20,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
- elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t); /* hardware clock cycles */
- return (unsigned long)(elapsed * jiffies_to_usecs(1)) / LATCH;
+/*
+ * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16)
+ */
+static void
+pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+ unsigned long flags;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* update clocksource counter, then enable the IRQ */
+ raw_local_irq_save(flags);
+ pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
+ at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
+ | AT91_PIT_PITIEN);
+ raw_local_irq_restore(flags);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ BUG();
+ /* FALLTHROUGH */
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ /* disable irq, leaving the clocksource active */
+ at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
}
+static struct clock_event_device pit_clkevt = {
+ .name = "pit",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .shift = 32,
+ .rating = 100,
+ .cpumask = CPU_MASK_CPU0,
+ .set_mode = pit_clkevt_mode,
+};
+
+
/*
* IRQ handler for the timer.
*/
-static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id)
+static irqreturn_t at91sam926x_pit_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 */
- /* Get number to ticks performed before interrupt and clear PIT interrupt */
+ /* The PIT interrupt may be disabled, and is shared */
+ if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC)
+ && (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS)) {
+ unsigned nr_ticks;
+
+ /* Get number of ticks performed before irq, and ack it */
nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
do {
- timer_tick();
+ pit_cnt += pit_cycle;
+ pit_clkevt.event_handler(&pit_clkevt);
nr_ticks--;
} while (nr_ticks);
return IRQ_HANDLED;
- } else
- return IRQ_NONE; /* not handled */
+ }
+
+ return IRQ_NONE;
}
-static struct irqaction at91sam926x_timer_irq = {
+static struct irqaction at91sam926x_pit_irq = {
.name = "at91_tick",
.flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .handler = at91sam926x_timer_interrupt
+ .handler = at91sam926x_pit_interrupt
};
-void at91sam926x_timer_reset(void)
+static void at91sam926x_pit_reset(void)
{
- /* Disable timer */
+ /* Disable timer and irqs */
at91_sys_write(AT91_PIT_MR, 0);
- /* Clear any pending interrupts */
- (void) at91_sys_read(AT91_PIT_PIVR);
+ /* Clear any pending interrupts, wait for PIT to stop counting */
+ while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0)
+ cpu_relax();
- /* Set Period Interval timer and enable its interrupt */
- at91_sys_write(AT91_PIT_MR, (LATCH & AT91_PIT_PIV) | AT91_PIT_PITIEN | AT91_PIT_PITEN);
+ /* Start PIT but don't enable IRQ */
+ at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
}
/*
- * Set up timer interrupt.
+ * Set up both clocksource and clockevent support.
*/
-void __init at91sam926x_timer_init(void)
+static void __init at91sam926x_pit_init(void)
{
- /* Initialize and enable the timer */
- at91sam926x_timer_reset();
+ unsigned long pit_rate;
+ unsigned bits;
+
+ /*
+ * Use our actual MCK to figure out how many MCK/16 ticks per
+ * 1/HZ period (instead of a compile-time constant LATCH).
+ */
+ pit_rate = clk_get_rate(clk_get(NULL, "mck")) / 16;
+ pit_cycle = (pit_rate + HZ/2) / HZ;
+ WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0);
- /* Make IRQs happen for the system timer. */
- setup_irq(AT91_ID_SYS, &at91sam926x_timer_irq);
+ /* Initialize and enable the timer */
+ at91sam926x_pit_reset();
+
+ /*
+ * Register clocksource. The high order bits of PIV are unused,
+ * so this isn't a 32-bit counter unless we get clockevent irqs.
+ */
+ pit_clk.mult = clocksource_hz2mult(pit_rate, pit_clk.shift);
+ bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */;
+ pit_clk.mask = CLOCKSOURCE_MASK(bits);
+ clocksource_register(&pit_clk);
+
+ /* Set up irq handler */
+ setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq);
+
+ /* Set up and register clockevents */
+ pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift);
+ clockevents_register_device(&pit_clkevt);
}
-#ifdef CONFIG_PM
-static void at91sam926x_timer_suspend(void)
+static void at91sam926x_pit_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,
+ .init = at91sam926x_pit_init,
+ .suspend = at91sam926x_pit_suspend,
+ .resume = at91sam926x_pit_reset,
};
-
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 4813a35f6cf5..902c79893ec7 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/pm.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -17,6 +18,7 @@
#include <asm/arch/at91sam9rl.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_shdwc.h>
#include "generic.h"
#include "clock.h"
@@ -244,6 +246,11 @@ static void at91sam9rl_reset(void)
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
}
+static void at91sam9rl_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
/* --------------------------------------------------------------------
* AT91SAM9RL processor initialization
@@ -274,6 +281,7 @@ void __init at91sam9rl_initialize(unsigned long main_clock)
iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc));
at91_arch_reset = at91sam9rl_reset;
+ pm_power_off = at91sam9rl_poweroff;
at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
/* Init clock subsystem */
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index f43b5c33e45d..dbb9a5fc2090 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -20,7 +20,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/at91sam9rl.h>
#include <asm/arch/at91sam9rl_matrix.h>
-#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9_smc.h>
#include "generic.h"
@@ -105,10 +105,15 @@ static struct at91_nand_data nand_data;
#define NAND_BASE AT91_CHIPSELECT_3
static struct resource nand_resources[] = {
- {
+ [0] = {
.start = NAND_BASE,
.end = NAND_BASE + SZ_256M - 1,
.flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
}
};
@@ -385,6 +390,55 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_TCB0,
+ .end = AT91SAM9RL_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_TC0,
+ .end = AT91SAM9RL_ID_TC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91SAM9RL_ID_TC1,
+ .end = AT91SAM9RL_ID_TC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91SAM9RL_ID_TC2,
+ .end = AT91SAM9RL_ID_TC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_tcb_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb_resources,
+ .num_resources = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ /* this chip has a separate clock and irq for each TC channel */
+ at91_clock_associate("tc0_clk", &at91sam9rl_tcb_device.dev, "t0_clk");
+ at91_clock_associate("tc1_clk", &at91sam9rl_tcb_device.dev, "t1_clk");
+ at91_clock_associate("tc2_clk", &at91sam9rl_tcb_device.dev, "t2_clk");
+ platform_device_register(&at91sam9rl_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
* RTC
* -------------------------------------------------------------------- */
@@ -418,7 +472,7 @@ static struct resource rtt_resources[] = {
static struct platform_device at91sam9rl_rtt_device = {
.name = "at91_rtt",
- .id = -1,
+ .id = 0,
.resource = rtt_resources,
.num_resources = ARRAY_SIZE(rtt_resources),
};
@@ -539,9 +593,6 @@ static inline void configure_ssc1_pins(unsigned pins)
}
/*
- * Return the device node so that board init code can use it as the
- * parent for the device node reflecting how it's used on this board.
- *
* SSC controllers are accessed through library code, instead of any
* kind of all-singing/all-dancing driver. For example one could be
* used by a particular I2S audio codec's driver, while another one
@@ -802,54 +853,9 @@ static inline void configure_usart3_pins(unsigned pins)
at91_set_B_periph(AT91_PIN_PD3, 0); /* CTS3 */
}
-static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */
-void __init __deprecated 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(ATMEL_UART_CTS | ATMEL_UART_RTS);
- at91_uarts[i] = &at91sam9rl_uart0_device;
- at91_clock_associate("usart0_clk", &at91sam9rl_uart0_device.dev, "usart");
- break;
- case 1:
- configure_usart1_pins(0);
- at91_uarts[i] = &at91sam9rl_uart1_device;
- at91_clock_associate("usart1_clk", &at91sam9rl_uart1_device.dev, "usart");
- break;
- case 2:
- configure_usart2_pins(0);
- at91_uarts[i] = &at91sam9rl_uart2_device;
- at91_clock_associate("usart2_clk", &at91sam9rl_uart2_device.dev, "usart");
- break;
- case 3:
- configure_usart3_pins(0);
- at91_uarts[i] = &at91sam9rl_uart3_device;
- at91_clock_associate("usart3_clk", &at91sam9rl_uart3_device.dev, "usart");
- break;
- case 4:
- configure_dbgu_pins();
- at91_uarts[i] = &at91sam9rl_dbgu_device;
- at91_clock_associate("mck", &at91sam9rl_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_register_uart(unsigned id, unsigned portnr, unsigned pins)
{
struct platform_device *pdev;
@@ -893,8 +899,6 @@ void __init at91_set_serial_console(unsigned portnr)
{
if (portnr < ATMEL_MAX_UART)
atmel_default_console_device = at91_uarts[portnr];
- if (!atmel_default_console_device)
- printk(KERN_INFO "AT91: No default serial console defined.\n");
}
void __init at91_add_device_serial(void)
@@ -905,9 +909,11 @@ void __init at91_add_device_serial(void)
if (at91_uarts[i])
platform_device_register(at91_uarts[i]);
}
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
}
#else
-void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
void __init at91_set_serial_console(unsigned portnr) {}
void __init at91_add_device_serial(void) {}
@@ -925,6 +931,7 @@ static int __init at91_add_standard_devices(void)
at91_add_device_rtc();
at91_add_device_rtt();
at91_add_device_watchdog();
+ at91_add_device_tc();
return 0;
}
diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c
new file mode 100644
index 000000000000..b22a1a004055
--- /dev/null
+++ b/arch/arm/mach-at91/board-cam60.c
@@ -0,0 +1,180 @@
+/*
+ * KwikByte CAM60 (KB9260)
+ *
+ * based on board-sam9260ek.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 <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+
+static void __init cam60_map_io(void)
+{
+ /* Initialize processor: 10 MHz crystal */
+ at91sam9260_initialize(10000000);
+
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init cam60_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host
+ */
+static struct at91_usbh_data __initdata cam60_usbh_data = {
+ .ports = 1,
+};
+
+
+/*
+ * SPI devices.
+ */
+#if defined(CONFIG_MTD_DATAFLASH)
+static struct mtd_partition __initdata cam60_spi_partitions[] = {
+ {
+ .name = "BOOT1",
+ .offset = 0,
+ .size = 4 * 1056,
+ },
+ {
+ .name = "BOOT2",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 256 * 1056,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 2222 * 1056,
+ },
+ {
+ .name = "file system",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data __initdata cam60_spi_flash_platform_data = {
+ .name = "spi_flash",
+ .parts = cam60_spi_partitions,
+ .nr_parts = ARRAY_SIZE(cam60_spi_partitions)
+};
+#endif
+
+static struct spi_board_info cam60_spi_devices[] = {
+#if defined(CONFIG_MTD_DATAFLASH)
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ .platform_data = &cam60_spi_flash_platform_data
+ },
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct __initdata at91_eth_data cam60_macb_data = {
+ .phy_irq_pin = AT91_PIN_PB5,
+ .is_rmii = 0,
+};
+
+
+/*
+ * NAND Flash
+ */
+static struct mtd_partition __initdata cam60_nand_partition[] = {
+ {
+ .name = "nand_fs",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(cam60_nand_partition);
+ return cam60_nand_partition;
+}
+
+static struct at91_nand_data __initdata cam60_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ // .det_pin = ... not there
+ .rdy_pin = AT91_PIN_PA9,
+ .enable_pin = AT91_PIN_PA7,
+ .partition_info = nand_partitions,
+};
+
+
+static void __init cam60_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* SPI */
+ at91_add_device_spi(cam60_spi_devices, ARRAY_SIZE(cam60_spi_devices));
+ /* Ethernet */
+ at91_add_device_eth(&cam60_macb_data);
+ /* USB Host */
+ /* enable USB power supply circuit */
+ at91_set_gpio_output(AT91_PIN_PB18, 1);
+ at91_add_device_usbh(&cam60_usbh_data);
+ /* NAND */
+ at91_add_device_nand(&cam60_nand_data);
+}
+
+MACHINE_START(CAM60, "KwikByte CAM60")
+ /* Maintainer: KwikByte */
+ .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 = cam60_map_io,
+ .init_irq = cam60_init_irq,
+ .init_machine = cam60_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
index 185437131541..e5512d1ff217 100644
--- a/arch/arm/mach-at91/board-cap9adk.c
+++ b/arch/arm/mach-at91/board-cap9adk.c
@@ -45,7 +45,7 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91cap9_matrix.h>
-#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9_smc.h>
#include "generic.h"
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index 0e2a11fc5bbd..26fea4dcc3a0 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -43,17 +43,6 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata csb337_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init csb337_map_io(void)
{
/* Initialize processor: 3.6864 MHz crystal */
@@ -62,8 +51,11 @@ static void __init csb337_map_io(void)
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
- /* Setup the serial ports and console */
- at91_init_serial(&csb337_uart_config);
+ /* DBGU on ttyS0 */
+ at91_register_uart(0, 0, 0);
+
+ /* make console=ttyS0 the default */
+ at91_set_serial_console(0);
}
static void __init csb337_init_irq(void)
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
index c5c721d27f42..419fd19b620b 100644
--- a/arch/arm/mach-at91/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -40,27 +40,16 @@
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata csb637_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init csb637_map_io(void)
{
/* Initialize processor: 3.6864 MHz crystal */
at91rm9200_initialize(3686400, AT91RM9200_BGA);
- /* Setup the LEDs */
- at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
+ /* DBGU on ttyS0 */
+ at91_register_uart(0, 0, 0);
- /* Setup the serial ports and console */
- at91_init_serial(&csb637_uart_config);
+ /* make console=ttyS0 the default */
+ at91_set_serial_console(0);
}
static void __init csb637_init_irq(void)
@@ -118,8 +107,19 @@ static struct platform_device csb_flash = {
.num_resources = ARRAY_SIZE(csb_flash_resources),
};
+static struct gpio_led csb_leds[] = {
+ { /* "d1", red */
+ .name = "d1",
+ .gpio = AT91_PIN_PB2,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+};
+
static void __init csb637_board_init(void)
{
+ /* LED(s) */
+ at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds));
/* Serial */
at91_add_device_serial();
/* Ethernet */
diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c
new file mode 100644
index 000000000000..e77fad443835
--- /dev/null
+++ b/arch/arm/mach-at91/board-ecbat91.c
@@ -0,0 +1,178 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-ecbat91.c
+ * Copyright (C) 2007 emQbit.com.
+ *
+ * We started from board-dk.c, which is 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.
+ *
+ * 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 <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+
+static void __init ecb_at91map_io(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx & Tx only) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ecb_at91init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata ecb_at91eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 0,
+};
+
+static struct at91_usbh_data __initdata ecb_at91usbh_data = {
+ .ports = 1,
+};
+
+static struct at91_mmc_data __initdata ecb_at91mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+};
+
+
+#if defined(CONFIG_MTD_DATAFLASH)
+static struct mtd_partition __initdata my_flash0_partitions[] =
+{
+ { /* 0x8400 */
+ .name = "Darrell-loader",
+ .offset = 0,
+ .size = 12* 1056,
+ },
+ {
+ .name = "U-boot",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 110 * 1056,
+ },
+ { /* 1336 (167 blocks) pages * 1056 bytes = 0x158700 bytes */
+ .name = "UBoot-env",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 8 * 1056,
+ },
+ { /* 1336 (167 blocks) pages * 1056 bytes = 0x158700 bytes */
+ .name = "Kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 1534 * 1056,
+ },
+ { /* 190200 - jffs2 root filesystem */
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL, /* 26 sectors */
+ }
+};
+
+static struct flash_platform_data __initdata my_flash0_platform = {
+ .name = "Removable flash card",
+ .parts = my_flash0_partitions,
+ .nr_parts = ARRAY_SIZE(my_flash0_partitions)
+};
+
+#endif
+
+static struct spi_board_info __initdata ecb_at91spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+#if defined(CONFIG_MTD_DATAFLASH)
+ .platform_data = &my_flash0_platform,
+#endif
+ },
+ { /* 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 ecb_at91board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+
+ /* Ethernet */
+ at91_add_device_eth(&ecb_at91eth_data);
+
+ /* USB Host */
+ at91_add_device_usbh(&ecb_at91usbh_data);
+
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+
+ /* MMC */
+ at91_add_device_mmc(0, &ecb_at91mmc_data);
+
+ /* SPI */
+ at91_add_device_spi(ecb_at91spi_devices, ARRAY_SIZE(ecb_at91spi_devices));
+}
+
+MACHINE_START(ECBAT91, "emQbit's ECB_AT91")
+ /* Maintainer: emQbit.com */
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91rm9200_timer,
+ .map_io = ecb_at91map_io,
+ .init_irq = ecb_at91init_irq,
+ .init_machine = ecb_at91board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c
new file mode 100644
index 000000000000..8f76af5e219a
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9-l9260.c
@@ -0,0 +1,199 @@
+/*
+ * linux/arch/arm/mach-at91/board-sam9-l9260.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ * Copyright (C) 2007 Olimex Ltd
+ *
+ * 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 <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+#include "generic.h"
+
+
+static void __init ek_map_io(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PA9, AT91_PIN_PA6);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+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
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA7,
+ .is_rmii = 0,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Bootloader Area",
+ .offset = 0,
+ .size = 10 * 1024 * 1024,
+ },
+ {
+ .name = "User Area",
+ .offset = 10 * 1024 * 1024,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init 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 = AT91_PIN_PC8,
+ .wp_pin = AT91_PIN_PC4,
+// .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(0, &ek_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+}
+
+MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260")
+ /* Maintainer: Olimex */
+ .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
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index b343a6c28120..4d1d9c777084 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -25,6 +25,8 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
+#include <linux/clk.h>
#include <asm/hardware.h>
#include <asm/setup.h>
@@ -37,29 +39,28 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
-#include <asm/arch/at91sam926x_mc.h>
#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);
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init ek_init_irq(void)
@@ -85,6 +86,35 @@ static struct at91_udc_data __initdata ek_udc_data = {
/*
+ * Audio
+ */
+static struct at73c213_board_info at73c213_data = {
+ .ssc_id = 0,
+ .shortname = "AT91SAM9260-EK external DAC",
+};
+
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+static void __init at73c213_set_clk(struct at73c213_board_info *info)
+{
+ struct clk *pck0;
+ struct clk *plla;
+
+ pck0 = clk_get(NULL, "pck0");
+ plla = clk_get(NULL, "plla");
+
+ /* AT73C213 MCK Clock */
+ at91_set_B_periph(AT91_PIN_PC1, 0); /* PCK0 */
+
+ clk_set_parent(pck0, plla);
+ clk_put(plla);
+
+ info->dac_clk = pck0;
+}
+#else
+static void __init at73c213_set_clk(struct at73c213_board_info *info) {}
+#endif
+
+/*
* SPI devices.
*/
static struct spi_board_info ek_spi_devices[] = {
@@ -110,6 +140,8 @@ static struct spi_board_info ek_spi_devices[] = {
.chip_select = 0,
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 1,
+ .mode = SPI_MODE_1,
+ .platform_data = &at73c213_data,
},
#endif
};
@@ -172,6 +204,24 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
// .vcc_pin = ... not connected
};
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "bottom" led, green, userled1 to be defined */
+ .name = "ds5",
+ .gpio = AT91_PIN_PA6,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "power" led, yellow */
+ .name = "ds1",
+ .gpio = AT91_PIN_PA9,
+ .default_trigger = "heartbeat",
+ }
+};
+
static void __init ek_board_init(void)
{
/* Serial */
@@ -190,6 +240,11 @@ static void __init ek_board_init(void)
at91_add_device_mmc(0, &ek_mmc_data);
/* I2C */
at91_add_device_i2c(NULL, 0);
+ /* SSC (to AT73C213) */
+ at73c213_set_clk(&at73c213_data);
+ at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
}
MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 0ce38dfa6ebe..08382c0df221 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -26,6 +26,8 @@
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
+#include <linux/spi/at73c213.h>
+#include <linux/clk.h>
#include <linux/dm9000.h>
#include <linux/fb.h>
#include <linux/gpio_keys.h>
@@ -44,22 +46,11 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
-#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9_smc.h>
#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 */
@@ -68,8 +59,11 @@ static void __init ek_map_io(void)
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14);
- /* Setup the serial ports and console */
- at91_init_serial(&ek_uart_config);
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init ek_init_irq(void)
@@ -239,6 +233,35 @@ static void __init ek_add_device_ts(void) {}
#endif
/*
+ * Audio
+ */
+static struct at73c213_board_info at73c213_data = {
+ .ssc_id = 1,
+ .shortname = "AT91SAM9261-EK external DAC",
+};
+
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+static void __init at73c213_set_clk(struct at73c213_board_info *info)
+{
+ struct clk *pck2;
+ struct clk *plla;
+
+ pck2 = clk_get(NULL, "pck2");
+ plla = clk_get(NULL, "plla");
+
+ /* AT73C213 MCK Clock */
+ at91_set_B_periph(AT91_PIN_PB31, 0); /* PCK2 */
+
+ clk_set_parent(pck2, plla);
+ clk_put(plla);
+
+ info->dac_clk = pck2;
+}
+#else
+static void __init at73c213_set_clk(struct at73c213_board_info *info) {}
+#endif
+
+/*
* SPI devices
*/
static struct spi_board_info ek_spi_devices[] = {
@@ -256,6 +279,7 @@ static struct spi_board_info ek_spi_devices[] = {
.bus_num = 0,
.platform_data = &ads_info,
.irq = AT91SAM9261_ID_IRQ0,
+ .controller_data = (void *) AT91_PIN_PA28, /* CS pin */
},
#endif
#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
@@ -271,6 +295,9 @@ static struct spi_board_info ek_spi_devices[] = {
.chip_select = 3,
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 0,
+ .mode = SPI_MODE_1,
+ .platform_data = &at73c213_data,
+ .controller_data = (void*) AT91_PIN_PA29, /* default for CS3 is PA6, but it must be PA29 */
},
#endif
};
@@ -460,6 +487,29 @@ static void __init ek_add_device_buttons(void)
static void __init ek_add_device_buttons(void) {}
#endif
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "bottom" led, green, userled1 to be defined */
+ .name = "ds7",
+ .gpio = AT91_PIN_PA14,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "top" led, green, userled2 to be defined */
+ .name = "ds8",
+ .gpio = AT91_PIN_PA13,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "power" led, yellow */
+ .name = "ds1",
+ .gpio = AT91_PIN_PA23,
+ .default_trigger = "heartbeat",
+ }
+};
+
static void __init ek_board_init(void)
{
/* Serial */
@@ -481,6 +531,9 @@ static void __init ek_board_init(void)
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
/* Touchscreen */
ek_add_device_ts();
+ /* SSC (to AT73C213) */
+ at73c213_set_clk(&at73c213_data);
+ at91_add_device_ssc(AT91SAM9261_ID_SSC1, ATMEL_SSC_TX);
#else
/* MMC */
at91_add_device_mmc(0, &ek_mmc_data);
@@ -489,6 +542,8 @@ static void __init ek_board_init(void)
at91_add_device_lcdc(&ek_lcdc_data);
/* Push Buttons */
ek_add_device_buttons();
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
}
MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index bf103b24c937..b4cd5d0ed597 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -43,29 +43,24 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
-#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9_smc.h>
#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 = 2,
- .tty_map = { 3, 0, -1, -1, } /* ttyS0, ..., ttyS3 */
-};
-
static void __init ek_map_io(void)
{
/* Initialize processor: 16.367 MHz crystal */
at91sam9263_initialize(16367660);
- /* Setup the serial ports and console */
- at91_init_serial(&ek_uart_config);
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init ek_init_irq(void)
@@ -341,7 +336,7 @@ static struct gpio_led ek_leds[] = {
.name = "ds3",
.gpio = AT91_PIN_PB7,
.default_trigger = "heartbeat",
- },
+ }
};
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index bc0546d7245f..ffc0597aee8d 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -29,29 +29,24 @@
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
-#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9_smc.h>
#include "generic.h"
-/*
- * Serial port configuration.
- * 0 .. 3 = USART0 .. USART3
- * 4 = DBGU
- */
-static struct at91_uart_config __initdata ek_uart_config = {
- .console_tty = 0, /* ttyS0 */
- .nr_tty = 2,
- .tty_map = { 4, 0, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-};
-
static void __init ek_map_io(void)
{
/* Initialize processor: 12.000 MHz crystal */
at91sam9rl_initialize(12000000);
- /* Setup the serial ports and console */
- at91_init_serial(&ek_uart_config);
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9RL_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
}
static void __init ek_init_irq(void)
diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c
new file mode 100755
index 000000000000..b5717108991d
--- /dev/null
+++ b/arch/arm/mach-at91/board-yl-9200.c
@@ -0,0 +1,683 @@
+/*
+ * linux/arch/arm/mach-at91/board-yl-9200.c
+ *
+ * Adapted from:
+ *various board files in
+ * /arch/arm/mach-at91
+ * modifications to convert to YL-9200 platform
+ * Copyright (C) 2007 S.Birtles
+ *
+ * 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 <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+/*#include <linux/can_bus/candata.h>*/
+#include <linux/spi/ads7846.h>
+#include <linux/mtd/physmap.h>
+
+/*#include <sound/gpio_sounder.h>*/
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91rm9200_mc.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include "generic.h"
+#include <asm/arch/at91_pio.h>
+
+#define YL_9200_FLASH_BASE AT91_CHIPSELECT_0
+#define YL_9200_FLASH_SIZE 0x800000
+
+/*
+ * Serial port configuration.
+ * 0 .. 3 = USART0 .. USART3
+ * 4 = DBGU
+ *atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
+ *atmel_usart.1: ttyS1 at MMIO 0xfffc0000 (irq = 6) is a ATMEL_SERIAL
+ *atmel_usart.2: ttyS2 at MMIO 0xfffc4000 (irq = 7) is a ATMEL_SERIAL
+ *atmel_usart.3: ttyS3 at MMIO 0xfffc8000 (irq = 8) is a ATMEL_SERIAL
+ *atmel_usart.4: ttyS4 at MMIO 0xfffcc000 (irq = 9) is a ATMEL_SERIAL
+ * on the YL-9200 we are sitting at the following
+ *ttyS0 at MMIO 0xfefff200 (irq = 1) is a AT91_SERIAL
+ *ttyS1 at MMIO 0xfefc4000 (irq = 7) is a AT91_SERIAL
+ */
+
+/* extern void __init yl_9200_add_device_sounder(struct gpio_sounder *sounders, int nr);*/
+
+static struct at91_uart_config __initdata yl_9200_uart_config = {
+ .console_tty = 0, /* ttyS0 */
+ .nr_tty = 3,
+ .tty_map = { 4, 1, 0, -1, -1 } /* ttyS0, ..., ttyS4 */
+};
+
+static void __init yl_9200_map_io(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ /*Also initialises register clocks & gpio*/
+ at91rm9200_initialize(18432000, AT91RM9200_PQFP); /*we have a 3 bank system*/
+
+ /* Setup the serial ports and console */
+ at91_init_serial(&yl_9200_uart_config);
+
+ /* Setup the LEDs D2=PB17,D3=PB16 */
+ at91_init_leds(AT91_PIN_PB16,AT91_PIN_PB17); /*cpu-led,timer-led*/
+}
+
+static void __init yl_9200_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata yl_9200_eth_data = {
+ .phy_irq_pin = AT91_PIN_PB28,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata yl_9200_usbh_data = {
+ .ports = 1, /* this should be 1 not 2 for the Yl9200*/
+};
+
+static struct at91_udc_data __initdata yl_9200_udc_data = {
+/*on sheet 7 Schemitic rev 1.0*/
+ .pullup_pin = AT91_PIN_PC4,
+ .vbus_pin= AT91_PIN_PC5,
+ .pullup_active_low = 1, /*ACTIVE LOW!! due to PNP transistor on page 7*/
+
+};
+/*
+static struct at91_cf_data __initdata yl_9200_cf_data = {
+TODO S.BIRTLES
+ .det_pin = AT91_PIN_xxx,
+ .rst_pin = AT91_PIN_xxx,
+ .irq_pin = ... not connected
+ .vcc_pin = ... always powered
+
+};
+*/
+static struct at91_mmc_data __initdata yl_9200_mmc_data = {
+ .det_pin = AT91_PIN_PB9, /*THIS LOOKS CORRECT SHEET7*/
+/* .wp_pin = ... not connected SHEET7*/
+ .slot_b = 0,
+ .wire4 = 1,
+
+};
+
+/* --------------------------------------------------------------------
+ * Touch screen
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PB11); /* Touchscreen PENIRQ */
+}
+
+static void __init at91_init_device_ts(void)
+{
+/*IMPORTANT NOTE THE SPI INTERFACE IS ALREADY CONFIGURED BY XXX_DEVICES.C
+THAT IS TO SAY THAT MISO,MOSI,SPCK AND CS are already configured
+we only need to enable the other datapins which are:
+PB10/RK1 BUSY
+*/
+/* Touchscreen BUSY signal , pin,use pullup ( TODO not currently used in the ADS7843/6.c driver)*/
+at91_set_gpio_input(AT91_PIN_PB10, 1);
+}
+
+#else
+static void __init at91_init_device_ts(void) {}
+#endif
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+/* for a 8" touch screen*/
+ //.x_plate_ohms = 603, //= 450, S.Birtles TODO
+ //.y_plate_ohms = 332, //= 250, S.Birtles TODO
+/*for a 10.4" touch screen*/
+ //.x_plate_ohms =611,
+ //.y_plate_ohms =325,
+
+ .x_plate_ohms = 576,
+ .y_plate_ohms = 366,
+ //
+ .pressure_max = 15000, /*generally nonsense on the 7843*/
+ /*number of times to send query to chip in a given run 0 equals one time (do not set to 0!! ,there is a bug in ADS 7846 code)*/
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
+
+/*static struct canbus_platform_data can_info = {
+ .model = 2510,
+};
+*/
+
+static struct spi_board_info yl_9200_spi_devices[] = {
+/*this sticks it at:
+ /sys/devices/platform/atmel_spi.0/spi0.0
+ /sys/bus/platform/devices/
+Documentation/spi IIRC*/
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ /*(this IS correct 04-NOV-2007)*/
+ {
+ .modalias = "ads7846", /* because the driver is called ads7846*/
+ .chip_select = 0, /*THIS MUST BE AN INDEX INTO AN ARRAY OF pins */
+/*this is ONLY TO BE USED if chipselect above is not used, it passes a pin directly for the chip select*/
+ /*.controller_data =AT91_PIN_PA3 ,*/
+ .max_speed_hz = 5000*26, /*(4700 * 26)-125000 * 26, (max sample rate @ 3V) * (cmd + data + overhead) */
+ .bus_num = 0,
+ .platform_data = &ads_info,
+ .irq = AT91_PIN_PB11,
+ },
+#endif
+/*we need to put our CAN driver data here!!*/
+/*THIS IS ALL DUMMY DATA*/
+/* {
+ .modalias = "mcp2510", //DUMMY for MCP2510 chip
+ .chip_select = 1,*/ /*THIS MUST BE AN INDEX INTO AN ARRAY OF pins */
+ /*this is ONLY TO BE USED if chipselect above is not used, it passes a pin directly for the chip select */
+ /* .controller_data =AT91_PIN_PA4 ,
+ .max_speed_hz = 25000 * 26,
+ .bus_num = 0,
+ .platform_data = &can_info,
+ .irq = AT91_PIN_PC0,
+ },
+ */
+ //max SPI chip needs to go here
+};
+
+static struct mtd_partition __initdata yl_9200_nand_partition[] = {
+ {
+ .name = "AT91 NAND partition 1, boot",
+ .offset = 0,
+ .size = 1 * SZ_256K
+ },
+ {
+ .name = "AT91 NAND partition 2, kernel",
+ .offset = 1 * SZ_256K,
+ .size = 2 * SZ_1M - 1 * SZ_256K
+ },
+ {
+ .name = "AT91 NAND partition 3, filesystem",
+ .offset = 2 * SZ_1M,
+ .size = 14 * SZ_1M
+ },
+ {
+ .name = "AT91 NAND partition 4, storage",
+ .offset = 16 * SZ_1M,
+ .size = 16 * SZ_1M
+ },
+ {
+ .name = "AT91 NAND partition 5, ext-fs",
+ .offset = 32 * SZ_1M,
+ .size = 32 * SZ_1M
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(yl_9200_nand_partition);
+ return yl_9200_nand_partition;
+}
+
+static struct at91_nand_data __initdata yl_9200_nand_data = {
+ .ale= 6,
+ .cle= 7,
+ /*.det_pin = AT91_PIN_PCxx,*/ /*we don't have a det pin because NandFlash is fixed to board*/
+ .rdy_pin = AT91_PIN_PC14, /*R/!B Sheet10*/
+ .enable_pin = AT91_PIN_PC15, /*!CE Sheet10 */
+ .partition_info = nand_partitions,
+};
+
+
+
+/*
+TODO S.Birtles
+potentially a problem with the size above
+physmap platform flash device: 00800000 at 10000000
+physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank
+NOR chip too large to fit in mapping. Attempting to cope...
+ Intel/Sharp Extended Query Table at 0x0031
+Using buffer write method
+cfi_cmdset_0001: Erase suspend on write enabled
+Reducing visibility of 16384KiB chip to 8192KiB
+*/
+
+static struct mtd_partition yl_9200_flash_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },{
+ .name = "Kernel",
+ .size = 0x001C0000,
+ .offset = 0x00040000,
+ },{
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00200000
+ }
+
+};
+
+static struct physmap_flash_data yl_9200_flash_data = {
+ .width = 2,
+ .parts = yl_9200_flash_partitions,
+ .nr_parts = ARRAY_SIZE(yl_9200_flash_partitions),
+};
+
+static struct resource yl_9200_flash_resources[] = {
+{
+ .start = YL_9200_FLASH_BASE,
+ .end = YL_9200_FLASH_BASE + YL_9200_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device yl_9200_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &yl_9200_flash_data,
+ },
+ .resource = yl_9200_flash_resources,
+ .num_resources = ARRAY_SIZE(yl_9200_flash_resources),
+};
+
+
+static struct gpio_led yl_9200_leds[] = {
+/*D2 &D3 are passed directly in via at91_init_leds*/
+ {
+ .name = "led4", /*D4*/
+ .gpio = AT91_PIN_PB15,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ /*.default_trigger = "timer",*/
+ },
+ {
+ .name = "led5", /*D5*/
+ .gpio = AT91_PIN_PB8,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ }
+};
+
+//static struct gpio_sounder yl_9200_sounder[] = {*/
+/*This is a simple speaker attached to a gpo line*/
+
+// {
+// .name = "Speaker", /*LS1*/
+// .gpio = AT91_PIN_PA22,
+// .active_low = 0,
+// .default_trigger = "heartbeat",
+ /*.default_trigger = "timer",*/
+// },
+//};
+
+
+
+static struct i2c_board_info __initdata yl_9200_i2c_devices[] = {
+ {
+ /*TODO*/
+ I2C_BOARD_INFO("CS4334", 0x00),
+ }
+};
+
+
+ /*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button yl_9200_buttons[] = {
+ {
+ .gpio = AT91_PIN_PA24,
+ .code = BTN_2,
+ .desc = "SW2",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB1,
+ .code = BTN_3,
+ .desc = "SW3",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB2,
+ .code = BTN_4,
+ .desc = "SW4",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB6,
+ .code = BTN_5,
+ .desc = "SW5",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+
+};
+
+static struct gpio_keys_platform_data yl_9200_button_data = {
+ .buttons = yl_9200_buttons,
+ .nbuttons = ARRAY_SIZE(yl_9200_buttons),
+};
+
+static struct platform_device yl_9200_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &yl_9200_button_data,
+ }
+};
+
+static void __init yl_9200_add_device_buttons(void)
+{
+ //SW2
+ at91_set_gpio_input(AT91_PIN_PA24, 0);
+ at91_set_deglitch(AT91_PIN_PA24, 1);
+
+ //SW3
+ at91_set_gpio_input(AT91_PIN_PB1, 0);
+ at91_set_deglitch(AT91_PIN_PB1, 1);
+ //SW4
+ at91_set_gpio_input(AT91_PIN_PB2, 0);
+ at91_set_deglitch(AT91_PIN_PB2, 1);
+
+ //SW5
+ at91_set_gpio_input(AT91_PIN_PB6, 0);
+ at91_set_deglitch(AT91_PIN_PB6, 1);
+
+
+ at91_set_gpio_output(AT91_PIN_PB7, 1); /* #TURN BUTTONS ON, SHEET 5 of schematics */
+ platform_device_register(&yl_9200_button_device);
+}
+#else
+static void __init yl_9200_add_device_buttons(void) {}
+#endif
+
+#if defined(CONFIG_FB_S1D135XX) || defined(CONFIG_FB_S1D13XXX_MODULE)
+#include <video/s1d13xxxfb.h>
+
+/* EPSON S1D13806 FB (discontinued chip)*/
+/* EPSON S1D13506 FB */
+
+#define AT91_FB_REG_BASE 0x80000000L
+#define AT91_FB_REG_SIZE 0x200
+#define AT91_FB_VMEM_BASE 0x80200000L
+#define AT91_FB_VMEM_SIZE 0x200000L
+
+/*#define S1D_DISPLAY_WIDTH 640*/
+/*#define S1D_DISPLAY_HEIGHT 480*/
+
+
+static void __init yl_9200_init_video(void)
+{
+ at91_sys_write(AT91_PIOC + PIO_ASR,AT91_PIN_PC6);
+ at91_sys_write(AT91_PIOC + PIO_BSR,0);
+ at91_sys_write(AT91_PIOC + PIO_ASR,AT91_PIN_PC6);
+
+ at91_sys_write( AT91_SMC_CSR(2),
+ AT91_SMC_NWS_(0x4) |
+ AT91_SMC_WSEN |
+ AT91_SMC_TDF_(0x100) |
+ AT91_SMC_DBW
+ );
+
+
+
+}
+
+
+static struct s1d13xxxfb_regval yl_9200_s1dfb_initregs[] =
+{
+ {S1DREG_MISC, 0x00}, /* Miscellaneous Register*/
+ {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/
+ {S1DREG_GPIO_CNF0, 0x00}, /* General IO Pins Configuration Register*/
+ {S1DREG_GPIO_CTL0, 0x00}, /* General IO Pins Control Register*/
+ {S1DREG_CLK_CNF, 0x11}, /* Memory Clock Configuration Register*/
+ {S1DREG_LCD_CLK_CNF, 0x10}, /* LCD Pixel Clock Configuration Register*/
+ {S1DREG_CRT_CLK_CNF, 0x12}, /* CRT/TV Pixel Clock Configuration Register*/
+ {S1DREG_MPLUG_CLK_CNF, 0x01}, /* MediaPlug Clock Configuration Register*/
+ {S1DREG_CPU2MEM_WST_SEL, 0x02}, /* CPU To Memory Wait State Select Register*/
+ {S1DREG_MEM_CNF, 0x00}, /* Memory Configuration Register*/
+ {S1DREG_SDRAM_REF_RATE, 0x04}, /* DRAM Refresh Rate Register, MCLK source*/
+ {S1DREG_SDRAM_TC0, 0x12}, /* DRAM Timings Control Register 0*/
+ {S1DREG_SDRAM_TC1, 0x02}, /* DRAM Timings Control Register 1*/
+ {S1DREG_PANEL_TYPE, 0x25}, /* Panel Type Register*/
+ {S1DREG_MOD_RATE, 0x00}, /* MOD Rate Register*/
+ {S1DREG_LCD_DISP_HWIDTH, 0x4F}, /* LCD Horizontal Display Width Register*/
+ {S1DREG_LCD_NDISP_HPER, 0x13}, /* LCD Horizontal Non-Display Period Register*/
+ {S1DREG_TFT_FPLINE_START, 0x01}, /* TFT FPLINE Start Position Register*/
+ {S1DREG_TFT_FPLINE_PWIDTH, 0x0c}, /* TFT FPLINE Pulse Width Register*/
+ {S1DREG_LCD_DISP_VHEIGHT0, 0xDF}, /* LCD Vertical Display Height Register 0*/
+ {S1DREG_LCD_DISP_VHEIGHT1, 0x01}, /* LCD Vertical Display Height Register 1*/
+ {S1DREG_LCD_NDISP_VPER, 0x2c}, /* LCD Vertical Non-Display Period Register*/
+ {S1DREG_TFT_FPFRAME_START, 0x0a}, /* TFT FPFRAME Start Position Register*/
+ {S1DREG_TFT_FPFRAME_PWIDTH, 0x02}, /* TFT FPFRAME Pulse Width Register*/
+ {S1DREG_LCD_DISP_MODE, 0x05}, /* LCD Display Mode Register*/
+ {S1DREG_LCD_MISC, 0x01}, /* LCD Miscellaneous Register*/
+ {S1DREG_LCD_DISP_START0, 0x00}, /* LCD Display Start Address Register 0*/
+ {S1DREG_LCD_DISP_START1, 0x00}, /* LCD Display Start Address Register 1*/
+ {S1DREG_LCD_DISP_START2, 0x00}, /* LCD Display Start Address Register 2*/
+ {S1DREG_LCD_MEM_OFF0, 0x80}, /* LCD Memory Address Offset Register 0*/
+ {S1DREG_LCD_MEM_OFF1, 0x02}, /* LCD Memory Address Offset Register 1*/
+ {S1DREG_LCD_PIX_PAN, 0x03}, /* LCD Pixel Panning Register*/
+ {S1DREG_LCD_DISP_FIFO_HTC, 0x00}, /* LCD Display FIFO High Threshold Control Register*/
+ {S1DREG_LCD_DISP_FIFO_LTC, 0x00}, /* LCD Display FIFO Low Threshold Control Register*/
+ {S1DREG_CRT_DISP_HWIDTH, 0x4F}, /* CRT/TV Horizontal Display Width Register*/
+ {S1DREG_CRT_NDISP_HPER, 0x13}, /* CRT/TV Horizontal Non-Display Period Register*/
+ {S1DREG_CRT_HRTC_START, 0x01}, /* CRT/TV HRTC Start Position Register*/
+ {S1DREG_CRT_HRTC_PWIDTH, 0x0B}, /* CRT/TV HRTC Pulse Width Register*/
+ {S1DREG_CRT_DISP_VHEIGHT0, 0xDF}, /* CRT/TV Vertical Display Height Register 0*/
+ {S1DREG_CRT_DISP_VHEIGHT1, 0x01}, /* CRT/TV Vertical Display Height Register 1*/
+ {S1DREG_CRT_NDISP_VPER, 0x2B}, /* CRT/TV Vertical Non-Display Period Register*/
+ {S1DREG_CRT_VRTC_START, 0x09}, /* CRT/TV VRTC Start Position Register*/
+ {S1DREG_CRT_VRTC_PWIDTH, 0x01}, /* CRT/TV VRTC Pulse Width Register*/
+ {S1DREG_TV_OUT_CTL, 0x18}, /* TV Output Control Register */
+ {S1DREG_CRT_DISP_MODE, 0x05}, /* CRT/TV Display Mode Register, 16BPP*/
+ {S1DREG_CRT_DISP_START0, 0x00}, /* CRT/TV Display Start Address Register 0*/
+ {S1DREG_CRT_DISP_START1, 0x00}, /* CRT/TV Display Start Address Register 1*/
+ {S1DREG_CRT_DISP_START2, 0x00}, /* CRT/TV Display Start Address Register 2*/
+ {S1DREG_CRT_MEM_OFF0, 0x80}, /* CRT/TV Memory Address Offset Register 0*/
+ {S1DREG_CRT_MEM_OFF1, 0x02}, /* CRT/TV Memory Address Offset Register 1*/
+ {S1DREG_CRT_PIX_PAN, 0x00}, /* CRT/TV Pixel Panning Register*/
+ {S1DREG_CRT_DISP_FIFO_HTC, 0x00}, /* CRT/TV Display FIFO High Threshold Control Register*/
+ {S1DREG_CRT_DISP_FIFO_LTC, 0x00}, /* CRT/TV Display FIFO Low Threshold Control Register*/
+ {S1DREG_LCD_CUR_CTL, 0x00}, /* LCD Ink/Cursor Control Register*/
+ {S1DREG_LCD_CUR_START, 0x01}, /* LCD Ink/Cursor Start Address Register*/
+ {S1DREG_LCD_CUR_XPOS0, 0x00}, /* LCD Cursor X Position Register 0*/
+ {S1DREG_LCD_CUR_XPOS1, 0x00}, /* LCD Cursor X Position Register 1*/
+ {S1DREG_LCD_CUR_YPOS0, 0x00}, /* LCD Cursor Y Position Register 0*/
+ {S1DREG_LCD_CUR_YPOS1, 0x00}, /* LCD Cursor Y Position Register 1*/
+ {S1DREG_LCD_CUR_BCTL0, 0x00}, /* LCD Ink/Cursor Blue Color 0 Register*/
+ {S1DREG_LCD_CUR_GCTL0, 0x00}, /* LCD Ink/Cursor Green Color 0 Register*/
+ {S1DREG_LCD_CUR_RCTL0, 0x00}, /* LCD Ink/Cursor Red Color 0 Register*/
+ {S1DREG_LCD_CUR_BCTL1, 0x1F}, /* LCD Ink/Cursor Blue Color 1 Register*/
+ {S1DREG_LCD_CUR_GCTL1, 0x3F}, /* LCD Ink/Cursor Green Color 1 Register*/
+ {S1DREG_LCD_CUR_RCTL1, 0x1F}, /* LCD Ink/Cursor Red Color 1 Register*/
+ {S1DREG_LCD_CUR_FIFO_HTC, 0x00}, /* LCD Ink/Cursor FIFO Threshold Register*/
+ {S1DREG_CRT_CUR_CTL, 0x00}, /* CRT/TV Ink/Cursor Control Register*/
+ {S1DREG_CRT_CUR_START, 0x01}, /* CRT/TV Ink/Cursor Start Address Register*/
+ {S1DREG_CRT_CUR_XPOS0, 0x00}, /* CRT/TV Cursor X Position Register 0*/
+ {S1DREG_CRT_CUR_XPOS1, 0x00}, /* CRT/TV Cursor X Position Register 1*/
+ {S1DREG_CRT_CUR_YPOS0, 0x00}, /* CRT/TV Cursor Y Position Register 0*/
+ {S1DREG_CRT_CUR_YPOS1, 0x00}, /* CRT/TV Cursor Y Position Register 1*/
+ {S1DREG_CRT_CUR_BCTL0, 0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register*/
+ {S1DREG_CRT_CUR_GCTL0, 0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register*/
+ {S1DREG_CRT_CUR_RCTL0, 0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register*/
+ {S1DREG_CRT_CUR_BCTL1, 0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register*/
+ {S1DREG_CRT_CUR_GCTL1, 0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register*/
+ {S1DREG_CRT_CUR_RCTL1, 0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register*/
+ {S1DREG_CRT_CUR_FIFO_HTC, 0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register*/
+ {S1DREG_BBLT_CTL0, 0x00}, /* BitBlt Control Register 0*/
+ {S1DREG_BBLT_CTL1, 0x01}, /* BitBlt Control Register 1*/
+ {S1DREG_BBLT_CC_EXP, 0x00}, /* BitBlt ROP Code/Color Expansion Register*/
+ {S1DREG_BBLT_OP, 0x00}, /* BitBlt Operation Register*/
+ {S1DREG_BBLT_SRC_START0, 0x00}, /* BitBlt Source Start Address Register 0*/
+ {S1DREG_BBLT_SRC_START1, 0x00}, /* BitBlt Source Start Address Register 1*/
+ {S1DREG_BBLT_SRC_START2, 0x00}, /* BitBlt Source Start Address Register 2*/
+ {S1DREG_BBLT_DST_START0, 0x00}, /* BitBlt Destination Start Address Register 0*/
+ {S1DREG_BBLT_DST_START1, 0x00}, /* BitBlt Destination Start Address Register 1*/
+ {S1DREG_BBLT_DST_START2, 0x00}, /* BitBlt Destination Start Address Register 2*/
+ {S1DREG_BBLT_MEM_OFF0, 0x00}, /* BitBlt Memory Address Offset Register 0*/
+ {S1DREG_BBLT_MEM_OFF1, 0x00}, /* BitBlt Memory Address Offset Register 1*/
+ {S1DREG_BBLT_WIDTH0, 0x00}, /* BitBlt Width Register 0*/
+ {S1DREG_BBLT_WIDTH1, 0x00}, /* BitBlt Width Register 1*/
+ {S1DREG_BBLT_HEIGHT0, 0x00}, /* BitBlt Height Register 0*/
+ {S1DREG_BBLT_HEIGHT1, 0x00}, /* BitBlt Height Register 1*/
+ {S1DREG_BBLT_BGC0, 0x00}, /* BitBlt Background Color Register 0*/
+ {S1DREG_BBLT_BGC1, 0x00}, /* BitBlt Background Color Register 1*/
+ {S1DREG_BBLT_FGC0, 0x00}, /* BitBlt Foreground Color Register 0*/
+ {S1DREG_BBLT_FGC1, 0x00}, /* BitBlt Foreground Color Register 1*/
+ {S1DREG_LKUP_MODE, 0x00}, /* Look-Up Table Mode Register*/
+ {S1DREG_LKUP_ADDR, 0x00}, /* Look-Up Table Address Register*/
+ {S1DREG_PS_CNF, 0x00}, /* Power Save Configuration Register*/
+ {S1DREG_PS_STATUS, 0x00}, /* Power Save Status Register*/
+ {S1DREG_CPU2MEM_WDOGT, 0x00}, /* CPU-to-Memory Access Watchdog Timer Register*/
+ {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/
+};
+
+static u64 s1dfb_dmamask = 0xffffffffUL;
+
+static struct s1d13xxxfb_pdata yl_9200_s1dfb_pdata = {
+ .initregs = yl_9200_s1dfb_initregs,
+ .initregssize = ARRAY_SIZE(yl_9200_s1dfb_initregs),
+ .platform_init_video = yl_9200_init_video,
+};
+
+static struct resource yl_9200_s1dfb_resource[] = {
+ [0] = { /* video mem */
+ .name = "s1d13xxxfb memory",
+ /* .name = "s1d13806 memory",*/
+ .start = AT91_FB_VMEM_BASE,
+ .end = AT91_FB_VMEM_BASE + AT91_FB_VMEM_SIZE -1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* video registers */
+ .name = "s1d13xxxfb registers",
+ /* .name = "s1d13806 registers",*/
+ .start = AT91_FB_REG_BASE,
+ .end = AT91_FB_REG_BASE + AT91_FB_REG_SIZE -1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device yl_9200_s1dfb_device = {
+ /*TODO S.Birtles , really we need the chip revision in here as well*/
+ .name = "s1d13806fb",
+ /* .name = "s1d13506fb",*/
+ .id = -1,
+ .dev = {
+ /*TODO theres a waring here!!*/
+ /*WARNING: vmlinux.o(.data+0x2dbc): Section mismatch: reference to .init.text: (between 'yl_9200_s1dfb_pdata' and 's1dfb_dmamask')*/
+ .dma_mask = &s1dfb_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &yl_9200_s1dfb_pdata,
+ },
+ .resource = yl_9200_s1dfb_resource,
+ .num_resources = ARRAY_SIZE(yl_9200_s1dfb_resource),
+};
+
+void __init yl_9200_add_device_video(void)
+{
+ platform_device_register(&yl_9200_s1dfb_device);
+}
+#else
+ void __init yl_9200_add_device_video(void) {}
+#endif
+
+/*this is not called first , yl_9200_map_io is called first*/
+static void __init yl_9200_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&yl_9200_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&yl_9200_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&yl_9200_udc_data);
+ /* pullup_pin it is actually active low, but this is not needed, driver sets it up */
+ /*at91_set_multi_drive(yl_9200_udc_data.pullup_pin, 0);*/
+
+ /* Compact Flash */
+ /*at91_add_device_cf(&yl_9200_cf_data);*/
+
+ /* I2C */
+ at91_add_device_i2c(yl_9200_i2c_devices, ARRAY_SIZE(yl_9200_i2c_devices));
+ /* SPI */
+ /*TODO YL9200 we have 2 spi interfaces touch screen & CAN*/
+ /* AT91_PIN_PA5, AT91_PIN_PA6 , are used on the max 485 NOT SPI*/
+
+ /*touch screen and CAN*/
+ at91_add_device_spi(yl_9200_spi_devices, ARRAY_SIZE(yl_9200_spi_devices));
+
+ /*Basically the TS uses PB11 & PB10 , PB11 is configured by the SPI system BP10 IS NOT USED!!*/
+ /* we need this incase the board is running without a touch screen*/
+ #if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ at91_init_device_ts(); /*init the touch screen device*/
+ #endif
+ /* DataFlash card */
+ at91_add_device_mmc(0, &yl_9200_mmc_data);
+ /* NAND */
+ at91_add_device_nand(&yl_9200_nand_data);
+ /* NOR Flash */
+ platform_device_register(&yl_9200_flash);
+ /* LEDs. Note!! this does not include the led's we passed for the processor status */
+ at91_gpio_leds(yl_9200_leds, ARRAY_SIZE(yl_9200_leds));
+ /* VGA */
+ /*this is self registered by including the s1d13xxx chip in the kernel build*/
+ yl_9200_add_device_video();
+ /* Push Buttons */
+ yl_9200_add_device_buttons();
+ /*TODO fixup the Sounder */
+// yl_9200_add_device_sounder(yl_9200_sounder,ARRAY_SIZE(yl_9200_sounder));
+
+}
+
+MACHINE_START(YL9200, "uCdragon YL-9200")
+ /* Maintainer: S.Birtles*/
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91rm9200_timer,
+ .map_io = yl_9200_map_io,
+ .init_irq = yl_9200_init_irq,
+ .init_machine = yl_9200_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index a67defd50438..39733b6992aa 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -26,12 +26,135 @@
#include <asm/mach-types.h>
#include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91rm9200_mc.h>
#include <asm/arch/gpio.h>
#include <asm/arch/cpu.h>
#include "generic.h"
+#ifdef CONFIG_ARCH_AT91RM9200
+#include <asm/arch/at91rm9200_mc.h>
+
+/*
+ * The AT91RM9200 goes into self-refresh mode with this command, and will
+ * terminate self-refresh automatically on the next SDRAM access.
+ */
+#define sdram_selfrefresh_enable() at91_sys_write(AT91_SDRAMC_SRR, 1)
+#define sdram_selfrefresh_disable() do {} while (0)
+
+#elif defined(CONFIG_ARCH_AT91CAP9)
+#include <asm/arch/at91cap9_ddrsdr.h>
+
+static u32 saved_lpr;
+
+static inline void sdram_selfrefresh_enable(void)
+{
+ u32 lpr;
+
+ saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR);
+
+ lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
+ at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
+}
+
+#define sdram_selfrefresh_disable() at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr)
+
+#else
+#include <asm/arch/at91sam9_sdramc.h>
+
+static u32 saved_lpr;
+
+static inline void sdram_selfrefresh_enable(void)
+{
+ u32 lpr;
+
+ saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
+
+ lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
+ at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
+}
+
+#define sdram_selfrefresh_disable() at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+
+/*
+ * FIXME: The AT91SAM9263 has a second EBI controller which may have
+ * additional SDRAM. pm_slowclock.S will require a similar fix.
+ */
+
+#endif
+
+
+/*
+ * Show the reason for the previous system reset.
+ */
+#if defined(AT91_SHDWC)
+
+#include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_shdwc.h>
+
+static void __init show_reset_status(void)
+{
+ static char reset[] __initdata = "reset";
+
+ static char general[] __initdata = "general";
+ static char wakeup[] __initdata = "wakeup";
+ static char watchdog[] __initdata = "watchdog";
+ static char software[] __initdata = "software";
+ static char user[] __initdata = "user";
+ static char unknown[] __initdata = "unknown";
+
+ static char signal[] __initdata = "signal";
+ static char rtc[] __initdata = "rtc";
+ static char rtt[] __initdata = "rtt";
+ static char restore[] __initdata = "power-restored";
+
+ char *reason, *r2 = reset;
+ u32 reset_type, wake_type;
+
+ reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
+ wake_type = at91_sys_read(AT91_SHDW_SR);
+
+ switch (reset_type) {
+ case AT91_RSTC_RSTTYP_GENERAL:
+ reason = general;
+ break;
+ case AT91_RSTC_RSTTYP_WAKEUP:
+ /* board-specific code enabled the wakeup sources */
+ reason = wakeup;
+
+ /* "wakeup signal" */
+ if (wake_type & AT91_SHDW_WAKEUP0)
+ r2 = signal;
+ else {
+ r2 = reason;
+ if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */
+ reason = rtt;
+ else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */
+ reason = rtc;
+ else if (wake_type == 0) /* power-restored wakeup */
+ reason = restore;
+ else /* unknown wakeup */
+ reason = unknown;
+ }
+ break;
+ case AT91_RSTC_RSTTYP_WATCHDOG:
+ reason = watchdog;
+ break;
+ case AT91_RSTC_RSTTYP_SOFTWARE:
+ reason = software;
+ break;
+ case AT91_RSTC_RSTTYP_USER:
+ reason = user;
+ break;
+ default:
+ reason = unknown;
+ break;
+ }
+ pr_info("AT91: Starting after %s %s\n", reason, r2);
+}
+#else
+static void __init show_reset_status(void) {}
+#endif
+
static int at91_pm_valid_state(suspend_state_t state)
{
@@ -125,6 +248,11 @@ EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
static void (*slow_clock)(void);
+#ifdef CONFIG_AT91_SLOW_CLOCK
+extern void at91_slow_clock(void);
+extern u32 at91_slow_clock_sz;
+#endif
+
static int at91_pm_enter(suspend_state_t state)
{
@@ -158,11 +286,14 @@ static int at91_pm_enter(suspend_state_t state)
* turning off the main oscillator; reverse on wakeup.
*/
if (slow_clock) {
+#ifdef CONFIG_AT91_SLOW_CLOCK
+ /* copy slow_clock handler to SRAM, and call it */
+ memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
+#endif
slow_clock();
break;
} else {
- /* DEVELOPMENT ONLY */
- pr_info("AT91: PM - no slow clock mode yet ...\n");
+ pr_info("AT91: PM - no slow clock mode enabled ...\n");
/* FALLTHROUGH leaving master clock alone */
}
@@ -175,13 +306,15 @@ static int at91_pm_enter(suspend_state_t state)
case PM_SUSPEND_STANDBY:
/*
* NOTE: the Wait-for-Interrupt instruction needs to be
- * in icache so the SDRAM stays in self-refresh mode until
- * the wakeup IRQ occurs.
+ * in icache so no SDRAM accesses are needed until the
+ * wakeup IRQ occurs and self-refresh is terminated.
*/
asm("b 1f; .align 5; 1:");
asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */
- at91_sys_write(AT91_SDRAMC_SRR, 1); /* self-refresh mode */
- /* fall though to next state */
+ sdram_selfrefresh_enable();
+ asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */
+ sdram_selfrefresh_disable();
+ break;
case PM_SUSPEND_ON:
asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */
@@ -196,6 +329,7 @@ static int at91_pm_enter(suspend_state_t state)
at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR));
error:
+ sdram_selfrefresh_disable();
target_state = PM_SUSPEND_ON;
at91_irq_resume();
at91_gpio_resume();
@@ -220,21 +354,20 @@ static struct platform_suspend_ops at91_pm_ops ={
static int __init at91_pm_init(void)
{
- printk("AT91: Power Management\n");
-
-#ifdef CONFIG_AT91_PM_SLOW_CLOCK
- /* REVISIT allocations of SRAM should be dynamically managed.
- * FIQ handlers and other components will want SRAM/TCM too...
- */
- slow_clock = (void *) (AT91_VA_BASE_SRAM + (3 * SZ_4K));
- memcpy(slow_clock, at91rm9200_slow_clock, at91rm9200_slow_clock_sz);
+#ifdef CONFIG_AT91_SLOW_CLOCK
+ slow_clock = (void *) (AT91_IO_VIRT_BASE - at91_slow_clock_sz);
#endif
- /* Disable SDRAM low-power mode. Cannot be used with self-refresh. */
+ pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : ""));
+
+#ifdef CONFIG_ARCH_AT91RM9200
+ /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */
at91_sys_write(AT91_SDRAMC_LPR, 0);
+#endif
suspend_set_ops(&at91_pm_ops);
+ show_reset_status();
return 0;
}
arch_initcall(at91_pm_init);