summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2009-10-04 01:20:22 +0200
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2009-10-20 15:02:39 +0200
commita08615b2dae45e0ffdf10fad62338cff2fba27e0 (patch)
treea1f0237db785e23eaa7aacbb5caf3fa0a799e168 /arch
parent7ac38053538f45032f8f52e99d5cd3368c06037c (diff)
downloadbarebox-a08615b2dae45e0ffdf10fad62338cff2fba27e0.tar.gz
barebox-a08615b2dae45e0ffdf10fad62338cff2fba27e0.tar.xz
at91sam9: switch to the same api as the kernel
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-at91/Makefile8
-rw-r--r--arch/arm/mach-at91/at91sam9260.c12
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c198
-rw-r--r--arch/arm/mach-at91/at91sam9263.c20
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c133
-rw-r--r--arch/arm/mach-at91/clocksource.c15
-rw-r--r--arch/arm/mach-at91/gpio.c181
-rw-r--r--arch/arm/mach-at91/lowlevel_init.S278
-rw-r--r--arch/arm/mach-at91/sam9_smc.c48
9 files changed, 803 insertions, 90 deletions
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index cec148c2ed..c848919e57 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -1,3 +1,7 @@
obj-y += clocksource.o gpio.o
-obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam9260_devices.o
-obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam9263_devices.o
+
+obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o
+
+# CPU-specific support
+obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam9263_devices.o sam9_smc.o
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 04e954b039..1a6e356482 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -5,14 +5,14 @@
static struct at91_gpio_bank at91sam9260_gpio[] = {
{
- .id = AT91C_ID_PIOA,
- .regbase = (void __iomem *)AT91C_BASE_PIOA,
+ .id = AT91SAM9260_ID_PIOA,
+ .offset = AT91_PIOA,
}, {
- .id = AT91C_ID_PIOB,
- .regbase = (void __iomem *)AT91C_BASE_PIOB,
+ .id = AT91SAM9260_ID_PIOB,
+ .offset = AT91_PIOB,
}, {
- .id = AT91C_ID_PIOC,
- .regbase = (void __iomem *)AT91C_BASE_PIOC,
+ .id = AT91SAM9260_ID_PIOC,
+ .offset = AT91_PIOC,
}
};
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 04f8f4a922..5e321c1e7b 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -13,6 +13,10 @@
#include <asm/armlinux.h>
#include <asm/hardware.h>
#include <asm/arch/board.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91sam9260_matrix.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/io.h>
static struct memory_platform_data sram_pdata = {
.name = "sram0",
@@ -21,7 +25,7 @@ static struct memory_platform_data sram_pdata = {
static struct device_d sdram_dev = {
.name = "mem",
- .map_base = 0x20000000,
+ .map_base = AT91_CHIPSELECT_1,
.platform_data = &sram_pdata,
};
@@ -35,7 +39,7 @@ void at91_add_device_sdram(u32 size)
#if defined(CONFIG_DRIVER_NET_MACB)
static struct device_d macb_dev = {
.name = "macb",
- .map_base = AT91C_BASE_EMACB,
+ .map_base = AT91SAM9260_BASE_EMAC,
.size = 0x1000,
};
@@ -44,6 +48,29 @@ void at91_add_device_eth(struct at91_ether_platform_data *data)
if (!data)
return;
+ /* Pins used for MII and RMII */
+ at91_set_A_periph(AT91_PIN_PA19, 0); /* ETXCK_EREFCK */
+ at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */
+ at91_set_A_periph(AT91_PIN_PA14, 0); /* ERX0 */
+ at91_set_A_periph(AT91_PIN_PA15, 0); /* ERX1 */
+ at91_set_A_periph(AT91_PIN_PA18, 0); /* ERXER */
+ at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXEN */
+ at91_set_A_periph(AT91_PIN_PA12, 0); /* ETX0 */
+ at91_set_A_periph(AT91_PIN_PA13, 0); /* ETX1 */
+ at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */
+ at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */
+
+ if (!(data->flags & AT91SAM_ETHER_RMII)) {
+ at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */
+ at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */
+ at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */
+ at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */
+ at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */
+ at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */
+ }
+
macb_dev.platform_data = data;
register_device(&macb_dev);
}
@@ -54,12 +81,34 @@ void at91_add_device_eth(struct at91_ether_platform_data *data) {}
#if defined(CONFIG_NAND_ATMEL)
static struct device_d nand_dev = {
.name = "atmel_nand",
- .map_base = 0x40000000,
+ .map_base = AT91_CHIPSELECT_3,
.size = 0x10,
};
void at91_add_device_nand(struct atmel_nand_data *data)
{
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_PIOC);
+
nand_dev.platform_data = data;
register_device(&nand_dev);
}
@@ -69,18 +118,155 @@ void at91_add_device_nand(struct atmel_nand_data *data) {}
static struct device_d dbgu_serial_device = {
.name = "atmel_serial",
- .map_base = AT91C_BASE_DBGU,
+ .map_base = AT91_BASE_SYS + AT91_DBGU,
+ .size = 4096,
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */
+}
+
+static struct device_d uart0_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9260_BASE_US0,
+ .size = 4096,
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */
+ if (pins & ATMEL_UART_DTR)
+ at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */
+ if (pins & ATMEL_UART_DSR)
+ at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */
+ if (pins & ATMEL_UART_DCD)
+ at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */
+ if (pins & ATMEL_UART_RI)
+ at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */
+}
+
+static struct device_d uart1_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9260_BASE_US1,
+ .size = 4096,
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */
+}
+
+static struct device_d uart2_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9260_BASE_US2,
+ .size = 4096,
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */
+ at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PA4, 0); /* RTS2 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PA5, 0); /* CTS2 */
+}
+
+static struct device_d uart3_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9260_BASE_US3,
+ .size = 4096,
+};
+
+static inline void configure_usart3_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */
+ at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PC8, 0); /* RTS3 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PC10, 0); /* CTS3 */
+}
+
+static struct device_d uart4_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9260_BASE_US4,
.size = 4096,
};
-void at91_register_uart(unsigned id)
+static inline void configure_usart4_pins(void)
+{
+ at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */
+ at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */
+}
+
+static struct device_d uart5_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9260_BASE_US5,
+ .size = 4096,
+};
+
+static inline void configure_usart5_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */
+ at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */
+}
+
+void at91_register_uart(unsigned id, unsigned pins)
{
switch (id) {
case 0: /* DBGU */
+ configure_dbgu_pins();
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS);
register_device(&dbgu_serial_device);
break;
+ case AT91SAM9260_ID_US0:
+ configure_usart0_pins(pins);
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US0);
+ register_device(&uart0_serial_device);
+ break;
+ case AT91SAM9260_ID_US1:
+ configure_usart1_pins(pins);
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US1);
+ register_device(&uart1_serial_device);
+ break;
+ case AT91SAM9260_ID_US2:
+ configure_usart2_pins(pins);
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US2);
+ register_device(&uart2_serial_device);
+ break;
+ case AT91SAM9260_ID_US3:
+ configure_usart3_pins(pins);
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US3);
+ register_device(&uart3_serial_device);
+ break;
+ case AT91SAM9260_ID_US4:
+ configure_usart4_pins();
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US4);
+ register_device(&uart4_serial_device);
+ break;
+ case AT91SAM9260_ID_US5:
+ configure_usart5_pins();
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US5);
+ register_device(&uart5_serial_device);
+ break;
default:
return;
}
-
}
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 8688b979eb..472b619863 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -5,21 +5,27 @@
static struct at91_gpio_bank at91sam9263_gpio[] = {
{
- .id = AT91C_ID_PIOA,
- .regbase = (void __iomem *)AT91C_BASE_PIOA,
+ .id = AT91SAM9263_ID_PIOA,
+ .offset = AT91_PIOA,
}, {
- .id = AT91C_ID_PIOB,
- .regbase = (void __iomem *)AT91C_BASE_PIOB,
+ .id = AT91SAM9263_ID_PIOB,
+ .offset = AT91_PIOB,
}, {
- .id = AT91C_ID_PIOCDE,
- .regbase = (void __iomem *)AT91C_BASE_PIOC,
+ .id = AT91SAM9263_ID_PIOCDE,
+ .offset = AT91_PIOC,
+ }, {
+ .id = AT91SAM9263_ID_PIOCDE,
+ .offset = AT91_PIOD,
+ }, {
+ .id = AT91SAM9263_ID_PIOCDE,
+ .offset = AT91_PIOE,
}
};
static int at91sam9263_initialize(void)
{
/* Register GPIO subsystem */
- at91_gpio_init(at91sam9263_gpio, 3);
+ at91_gpio_init(at91sam9263_gpio, 5);
return 0;
}
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 4eb71f8482..83b733f58b 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -12,7 +12,11 @@
#include <common.h>
#include <asm/armlinux.h>
#include <asm/hardware.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91sam9263_matrix.h>
#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/io.h>
static struct memory_platform_data ram_pdata = {
.name = "ram0",
@@ -21,7 +25,7 @@ static struct memory_platform_data ram_pdata = {
static struct device_d sdram_dev = {
.name = "mem",
- .map_base = 0x20000000,
+ .map_base = AT91_CHIPSELECT_1,
.platform_data = &ram_pdata,
};
@@ -35,7 +39,7 @@ void at91_add_device_sdram(u32 size)
#if defined(CONFIG_DRIVER_NET_MACB)
static struct device_d macb_dev = {
.name = "macb",
- .map_base = AT91C_BASE_MACB,
+ .map_base = AT91SAM9263_BASE_EMAC,
.size = 0x1000,
};
@@ -44,6 +48,28 @@ void at91_add_device_eth(struct at91_ether_platform_data *data)
if (!data)
return;
+ at91_set_A_periph(AT91_PIN_PE21, 0); /* ETXCK_EREFCK */
+ at91_set_B_periph(AT91_PIN_PC25, 0); /* ERXDV */
+ at91_set_A_periph(AT91_PIN_PE25, 0); /* ERX0 */
+ at91_set_A_periph(AT91_PIN_PE26, 0); /* ERX1 */
+ at91_set_A_periph(AT91_PIN_PE27, 0); /* ERXER */
+ at91_set_A_periph(AT91_PIN_PE28, 0); /* ETXEN */
+ at91_set_A_periph(AT91_PIN_PE23, 0); /* ETX0 */
+ at91_set_A_periph(AT91_PIN_PE24, 0); /* ETX1 */
+ at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */
+ at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */
+
+ if (!(data->flags & AT91SAM_ETHER_RMII)) {
+ at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */
+ at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */
+ at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */
+ at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */
+ at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */
+ at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */
+ }
+
macb_dev.platform_data = data;
register_device(&macb_dev);
}
@@ -54,12 +80,35 @@ void at91_add_device_eth(struct at91_ether_platform_data *data) {}
#if defined(CONFIG_NAND_ATMEL)
static struct device_d nand_dev = {
.name = "atmel_nand",
- .map_base = 0x40000000,
+ .map_base = AT91_CHIPSELECT_3,
.size = 0x10,
};
void at91_add_device_nand(struct atmel_nand_data *data)
{
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
+ at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9263_ID_PIOA |
+ 1 << AT91SAM9263_ID_PIOCDE);
+
nand_dev.platform_data = data;
register_device(&nand_dev);
}
@@ -69,16 +118,90 @@ void at91_add_device_nand(struct atmel_nand_data *data) {}
static struct device_d dbgu_serial_device = {
.name = "atmel_serial",
- .map_base = AT91C_BASE_DBGU,
+ .map_base = (AT91_BASE_SYS + AT91_DBGU),
+ .size = 4096,
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
+}
+
+static struct device_d uart0_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9263_BASE_US0,
+ .size = 4096,
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */
+}
+
+static struct device_d uart1_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9263_BASE_US1,
.size = 4096,
};
-void at91_register_uart(unsigned id)
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
+}
+
+static struct device_d uart2_serial_device = {
+ .name = "atmel_serial",
+ .map_base = AT91SAM9263_BASE_US2,
+ .size = 4096,
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
+ at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
+}
+
+void at91_register_uart(unsigned id, unsigned pins)
{
switch (id) {
case 0: /* DBGU */
+ configure_dbgu_pins();
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS);
register_device(&dbgu_serial_device);
break;
+ case AT91SAM9263_ID_US0:
+ configure_usart0_pins(pins);
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9263_ID_US0);
+ register_device(&uart0_serial_device);
+ break;
+ case AT91SAM9263_ID_US1:
+ configure_usart1_pins(pins);
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9263_ID_US1);
+ register_device(&uart1_serial_device);
+ break;
+ case AT91SAM9263_ID_US2:
+ configure_usart2_pins(pins);
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9263_ID_US2);
+ register_device(&uart2_serial_device);
+ break;
default:
return;
}
diff --git a/arch/arm/mach-at91/clocksource.c b/arch/arm/mach-at91/clocksource.c
index 86a51d584e..d937e49c38 100644
--- a/arch/arm/mach-at91/clocksource.c
+++ b/arch/arm/mach-at91/clocksource.c
@@ -33,11 +33,15 @@
#include <init.h>
#include <clock.h>
#include <asm/hardware.h>
+#include <asm/arch/at91_pit.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_rstc.h>
+#include <asm/arch/io.h>
#include <asm/io.h>
uint64_t at91sam9_clocksource_read(void)
{
- return readl(AT91C_PITC_PIIR);
+ return at91_sys_read(AT91_PIT_PIIR);
}
static struct clocksource cs = {
@@ -52,10 +56,10 @@ static int clocksource_init (void)
* Enable PITC Clock
* The clock is already enabled for system controller in boot
*/
- writel(1 << AT91C_ID_SYS, AT91C_PMC_PCER);
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS);
/* Enable PITC */
- writel(0xfffff | AT91C_PITC_PITEN, AT91C_PITC_PIMR);
+ at91_sys_write(AT91_PIT_MR, 0xfffff | AT91_PIT_PITEN);
cs.mult = clocksource_hz2mult(1000000 * 6, cs.shift);
@@ -71,7 +75,8 @@ core_initcall(clocksource_init);
*/
void reset_cpu (ulong ignored)
{
- writel((0xa5 << 24) | AT91C_RSTC_PROCRST | AT91C_RSTC_PERRST,
- AT91C_RSTC_RCR);
+ at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY |
+ AT91_RSTC_PROCRST |
+ AT91_RSTC_PERRST);
}
EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 09894b7fd0..b479a4f83a 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -24,43 +24,15 @@
#include <common.h>
#include <errno.h>
#include <asm/io.h>
+#include <asm/arch/gpio.h>
#include <gpio.h>
-#define OFS_PIO_PER 0x00 /* Enable Register */
-#define OFS_PIO_PDR 0x04 /* Disable Register */
-#define OFS_PIO_PSR 0x08 /* Status Register */
-#define OFS_PIO_OER 0x10 /* Output Enable Register */
-#define OFS_PIO_ODR 0x14 /* Output Disable Register */
-#define OFS_PIO_OSR 0x18 /* Output Status Register */
-#define OFS_PIO_IFER 0x20 /* Glitch Input Filter Enable */
-#define OFS_PIO_IFDR 0x24 /* Glitch Input Filter Disable */
-#define OFS_PIO_IFSR 0x28 /* Glitch Input Filter Status */
-#define OFS_PIO_SODR 0x30 /* Set Output Data Register */
-#define OFS_PIO_CODR 0x34 /* Clear Output Data Register */
-#define OFS_PIO_ODSR 0x38 /* Output Data Status Register */
-#define OFS_PIO_PDSR 0x3c /* Pin Data Status Register */
-#define OFS_PIO_IER 0x40 /* Interrupt Enable Register */
-#define OFS_PIO_IDR 0x44 /* Interrupt Disable Register */
-#define OFS_PIO_IMR 0x48 /* Interrupt Mask Register */
-#define OFS_PIO_ISR 0x4c /* Interrupt Status Register */
-#define OFS_PIO_MDER 0x50 /* Multi-driver Enable Register */
-#define OFS_PIO_MDDR 0x54 /* Multi-driver Disable Register */
-#define OFS_PIO_MDSR 0x58 /* Multi-driver Status Register */
-#define OFS_PIO_PUDR 0x60 /* Pull-up Disable Register */
-#define OFS_PIO_PUER 0x64 /* Pull-up Enable Register */
-#define OFS_PIO_PUSR 0x68 /* Pull-up Status Register */
-#define OFS_PIO_ASR 0x70 /* Peripheral A Select Register */
-#define OFS_PIO_BSR 0x74 /* Peripheral B Select Register */
-#define OFS_PIO_ABSR 0x78 /* AB Status Register */
-#define OFS_PIO_OWER 0xa0 /* Output Write Enable Register */
-#define OFS_PIO_OWDR 0xa4 /* Output Write Disable Register */
-#define OFS_PIO_OWSR 0xa8 /* Output Write Status Register */
-
static int gpio_banks;
static struct at91_gpio_bank *gpio;
static inline void __iomem *pin_to_controller(unsigned pin)
{
+ pin -= PIN_BASE;
pin /= 32;
if (likely(pin < gpio_banks))
return gpio[pin].regbase;
@@ -70,10 +42,66 @@ static inline void __iomem *pin_to_controller(unsigned pin)
static inline unsigned pin_to_mask(unsigned pin)
{
+ pin -= PIN_BASE;
return 1 << (pin % 32);
}
/*
+ * mux the pin to the "GPIO" peripheral role.
+ */
+int at91_set_GPIO_periph(unsigned pin, int use_pullup)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+ __raw_writel(mask, pio + PIO_PER);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_GPIO_periph);
+
+/*
+ * mux the pin to the "A" internal peripheral role.
+ */
+int at91_set_A_periph(unsigned pin, int use_pullup)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+ __raw_writel(mask, pio + PIO_ASR);
+ __raw_writel(mask, pio + PIO_PDR);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_A_periph);
+
+/*
+ * mux the pin to the "B" internal peripheral role.
+ */
+int at91_set_B_periph(unsigned pin, int use_pullup)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+ __raw_writel(mask, pio + PIO_BSR);
+ __raw_writel(mask, pio + PIO_PDR);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_B_periph);
+
+/*
* mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
* configure it for an input.
*/
@@ -85,10 +113,10 @@ int at91_set_gpio_input(unsigned pin, int use_pullup)
if (!pio)
return -EINVAL;
- writel(mask, pio + OFS_PIO_IDR);
- writel(mask, pio + (use_pullup ? OFS_PIO_PUER : OFS_PIO_PUDR));
- writel(mask, pio + OFS_PIO_ODR);
- writel(mask, pio + OFS_PIO_PER);
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+ __raw_writel(mask, pio + PIO_ODR);
+ __raw_writel(mask, pio + PIO_PER);
return 0;
}
EXPORT_SYMBOL(at91_set_gpio_input);
@@ -105,61 +133,66 @@ int at91_set_gpio_output(unsigned pin, int value)
if (!pio)
return -EINVAL;
- writel(mask, pio + OFS_PIO_IDR);
- writel(mask, pio + OFS_PIO_PUDR);
- writel(mask, pio + (value ? OFS_PIO_SODR : OFS_PIO_CODR));
- writel(mask, pio + OFS_PIO_OER);
- writel(mask, pio + OFS_PIO_PER);
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + PIO_PUDR);
+ __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
+ __raw_writel(mask, pio + PIO_OER);
+ __raw_writel(mask, pio + PIO_PER);
return 0;
}
EXPORT_SYMBOL(at91_set_gpio_output);
-int gpio_direction_input(unsigned pin)
+/*
+ * enable/disable the glitch filter; mostly used with IRQ handling.
+ */
+int at91_set_deglitch(unsigned pin, int is_on)
{
void __iomem *pio = pin_to_controller(pin);
unsigned mask = pin_to_mask(pin);
- if (!pio || !(readl(pio + OFS_PIO_PSR) & mask))
+ if (!pio)
return -EINVAL;
- writel(mask, pio + OFS_PIO_ODR);
+ __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
return 0;
}
-EXPORT_SYMBOL(gpio_direction_input);
+EXPORT_SYMBOL(at91_set_deglitch);
-int gpio_direction_output(unsigned pin, int value)
+/*
+ * enable/disable the multi-driver; This is only valid for output and
+ * allows the output pin to run as an open collector output.
+ */
+int at91_set_multi_drive(unsigned pin, int is_on)
{
void __iomem *pio = pin_to_controller(pin);
unsigned mask = pin_to_mask(pin);
- if (!pio || !(readl(pio + OFS_PIO_PSR) & mask))
+ if (!pio)
return -EINVAL;
- writel(mask, pio + (value ? OFS_PIO_SODR : OFS_PIO_CODR));
- writel(mask, pio + OFS_PIO_OER);
+
+ __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR));
return 0;
}
-EXPORT_SYMBOL(gpio_direction_output);
-
-/*--------------------------------------------------------------------------*/
+EXPORT_SYMBOL(at91_set_multi_drive);
/*
* assuming the pin is muxed as a gpio output, set its value.
*/
-void gpio_set_value(unsigned pin, int value)
+int at91_set_gpio_value(unsigned pin, int value)
{
void __iomem *pio = pin_to_controller(pin);
unsigned mask = pin_to_mask(pin);
if (!pio)
- return;
- writel(mask, pio + (value ? OFS_PIO_SODR : OFS_PIO_CODR));
+ return -EINVAL;
+ __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
+ return 0;
}
-EXPORT_SYMBOL(gpio_set_value);
-
+EXPORT_SYMBOL(at91_set_gpio_value);
/*
* read the pin's value (works even if it's not muxed as a gpio).
*/
-int gpio_get_value(unsigned pin)
+int at91_get_gpio_value(unsigned pin)
{
void __iomem *pio = pin_to_controller(pin);
unsigned mask = pin_to_mask(pin);
@@ -167,10 +200,37 @@ int gpio_get_value(unsigned pin)
if (!pio)
return -EINVAL;
- pdsr = readl(pio + OFS_PIO_PDSR);
+ pdsr = __raw_readl(pio + PIO_PDSR);
return (pdsr & mask) != 0;
}
-EXPORT_SYMBOL(gpio_get_value);
+EXPORT_SYMBOL(at91_get_gpio_value);
+
+int gpio_direction_input(unsigned pin)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
+ return -EINVAL;
+ __raw_writel(mask, pio + PIO_ODR);
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned pin, int value)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
+ return -EINVAL;
+ __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
+ __raw_writel(mask, pio + PIO_OER);
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+/*--------------------------------------------------------------------------*/
int at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
{
@@ -181,7 +241,10 @@ int at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
gpio_banks = nr_banks;
for (i = 0, last = NULL; i < nr_banks; i++, last = data, data++) {
- data->chipbase = i * 32;
+ data->chipbase = PIN_BASE + i * 32;
+ data->regbase = data->offset +
+ (void __iomem *)AT91_BASE_SYS;
+
/* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
if (last && last->id == data->id)
diff --git a/arch/arm/mach-at91/lowlevel_init.S b/arch/arm/mach-at91/lowlevel_init.S
new file mode 100644
index 0000000000..fa6577a6ab
--- /dev/null
+++ b/arch/arm/mach-at91/lowlevel_init.S
@@ -0,0 +1,278 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * Copyright (C) 2008 Ronetix Ilko Iliev (www.ronetix.at)
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <linux/autoconf.h>
+#include <config.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_pio.h>
+#include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_wdt.h>
+#include <asm/arch/at91sam9_matrix.h>
+#include <asm/arch/at91sam9_sdramc.h>
+#include <asm/arch/at91sam9_smc.h>
+
+_TEXT_BASE:
+ .word TEXT_BASE
+
+.globl board_init_lowlevel
+.type board_init_lowlevel,function
+board_init_lowlevel:
+
+ mov r5, pc /* r5 = POS1 + 4 current */
+POS1:
+ ldr r0, =POS1 /* r0 = POS1 compile */
+ ldr r2, _TEXT_BASE
+ sub r0, r0, r2 /* r0 = POS1-_TEXT_BASE (POS1 relative) */
+ sub r5, r5, r0 /* r0 = TEXT_BASE-1 */
+ sub r5, r5, #4 /* r1 = text base - current */
+
+ /* memory control configuration 1 */
+ ldr r0, =SMRDATA
+ ldr r2, =SMRDATA1
+ ldr r1, _TEXT_BASE
+ sub r0, r0, r1
+ sub r2, r2, r1
+ add r0, r0, r5
+ add r2, r2, r5
+0:
+ /* the address */
+ ldr r1, [r0], #4
+ /* the value */
+ ldr r3, [r0], #4
+ str r3, [r1]
+ cmp r2, r0
+ bne 0b
+
+/* ----------------------------------------------------------------------------
+ * PMC Init Step 1.
+ * ----------------------------------------------------------------------------
+ * - Check if the PLL is already initialized
+ * ----------------------------------------------------------------------------
+ */
+ ldr r1, =(AT91_BASE_SYS + AT91_PMC_MCKR)
+ ldr r0, [r1]
+ and r0, r0, #3
+ cmp r0, #0
+ bne PLL_setup_end
+
+/* ---------------------------------------------------------------------------
+ * - Enable the Main Oscillator
+ * ---------------------------------------------------------------------------
+ */
+ ldr r1, =(AT91_BASE_SYS + AT91_CKGR_MOR)
+ ldr r2, =(AT91_BASE_SYS + AT91_PMC_SR)
+ /* Main oscillator Enable register PMC_MOR: */
+ ldr r0, =CONFIG_SYS_MOR_VAL
+ str r0, [r1]
+
+ /* Reading the PMC Status to detect when the Main Oscillator is enabled */
+ mov r4, #AT91_PMC_MOSCS
+MOSCS_Loop:
+ ldr r3, [r2]
+ and r3, r4, r3
+ cmp r3, #AT91_PMC_MOSCS
+ bne MOSCS_Loop
+
+/* ----------------------------------------------------------------------------
+ * PMC Init Step 2.
+ * ----------------------------------------------------------------------------
+ * Setup PLLA
+ * ----------------------------------------------------------------------------
+ */
+ ldr r1, =(AT91_BASE_SYS + AT91_CKGR_PLLAR)
+ ldr r0, =CONFIG_SYS_PLLAR_VAL
+ str r0, [r1]
+
+ /* Reading the PMC Status register to detect when the PLLA is locked */
+ mov r4, #AT91_PMC_LOCKA
+MOSCS_Loop1:
+ ldr r3, [r2]
+ and r3, r4, r3
+ cmp r3, #AT91_PMC_LOCKA
+ bne MOSCS_Loop1
+
+/* ----------------------------------------------------------------------------
+ * PMC Init Step 3.
+ * ----------------------------------------------------------------------------
+ * - Switch on the Main Oscillator
+ * ----------------------------------------------------------------------------
+ */
+ ldr r1, =(AT91_BASE_SYS + AT91_PMC_MCKR)
+
+ /* -Master Clock Controller register PMC_MCKR */
+ ldr r0, =CONFIG_SYS_MCKR1_VAL
+ str r0, [r1]
+
+ /* Reading the PMC Status to detect when the Master clock is ready */
+ mov r4, #AT91_PMC_MCKRDY
+MCKRDY_Loop:
+ ldr r3, [r2]
+ and r3, r4, r3
+ cmp r3, #AT91_PMC_MCKRDY
+ bne MCKRDY_Loop
+
+ ldr r0, =CONFIG_SYS_MCKR2_VAL
+ str r0, [r1]
+
+ /* Reading the PMC Status to detect when the Master clock is ready */
+ mov r4, #AT91_PMC_MCKRDY
+MCKRDY_Loop1:
+ ldr r3, [r2]
+ and r3, r4, r3
+ cmp r3, #AT91_PMC_MCKRDY
+ bne MCKRDY_Loop1
+
+PLL_setup_end:
+
+/* ----------------------------------------------------------------------------
+ * - memory control configuration 2
+ * ----------------------------------------------------------------------------
+ */
+ ldr r0, =(AT91_BASE_SYS + AT91_SDRAMC_TR)
+ ldr r1, [r0]
+ cmp r1, #0
+ bne SDRAM_setup_end
+
+ ldr r0, =SMRDATA1
+ ldr r2, =SMRDATA2
+ ldr r1, _TEXT_BASE
+ sub r0, r0, r1
+ sub r2, r2, r1
+ add r0, r0, r5
+ add r2, r2, r5
+
+2:
+ /* the address */
+ ldr r1, [r0], #4
+ /* the value */
+ ldr r3, [r0], #4
+ str r3, [r1]
+ cmp r2, r0
+ bne 2b
+
+SDRAM_setup_end:
+ /* everything is fine now */
+ mov pc, lr
+
+ .ltorg
+
+SMRDATA:
+ .word (AT91_BASE_SYS + AT91_WDT_MR)
+ .word CONFIG_SYS_WDTC_WDMR_VAL
+
+ /* configure PIOx as EBI0 D[16-31] */
+#if defined(CONFIG_ARCH_AT91SAM9263)
+ .word (AT91_BASE_SYS + AT91_PIOD + PIO_PDR)
+ .word CONFIG_SYS_PIOD_PDR_VAL1
+ .word (AT91_BASE_SYS + AT91_PIOD + PIO_PUDR)
+ .word CONFIG_SYS_PIOD_PPUDR_VAL
+ .word (AT91_BASE_SYS + AT91_PIOD + PIO_ASR)
+ .word CONFIG_SYS_PIOD_PPUDR_VAL
+#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9261)
+ .word (AT91_BASE_SYS + AT91_PIOC + PIO_PDR)
+ .word CONFIG_SYS_PIOC_PDR_VAL1
+ .word (AT91_BASE_SYS + AT91_PIOC + PIO_PUDR)
+ .word CONFIG_SYS_PIOC_PPUDR_VAL
+#endif
+
+#if defined(AT91_MATRIX_EBI0CSA)
+ .word (AT91_BASE_SYS + AT91_MATRIX_EBI0CSA)
+ .word CONFIG_SYS_MATRIX_EBI0CSA_VAL
+#else /* AT91_MATRIX_EBICSA */
+ .word (AT91_BASE_SYS + AT91_MATRIX_EBICSA)
+ .word CONFIG_SYS_MATRIX_EBICSA_VAL
+#endif
+
+ /* flash */
+ .word (AT91_BASE_SYS + AT91_SMC_MODE(0))
+ .word CONFIG_SYS_SMC0_MODE0_VAL
+
+ .word (AT91_BASE_SYS + AT91_SMC_CYCLE(0))
+ .word CONFIG_SYS_SMC0_CYCLE0_VAL
+
+ .word (AT91_BASE_SYS + AT91_SMC_PULSE(0))
+ .word CONFIG_SYS_SMC0_PULSE0_VAL
+
+ .word (AT91_BASE_SYS + AT91_SMC_SETUP(0))
+ .word CONFIG_SYS_SMC0_SETUP0_VAL
+
+SMRDATA1:
+ .word (AT91_BASE_SYS + AT91_SDRAMC_MR)
+ .word CONFIG_SYS_SDRC_MR_VAL1
+ .word (AT91_BASE_SYS + AT91_SDRAMC_TR)
+ .word CONFIG_SYS_SDRC_TR_VAL1
+ .word (AT91_BASE_SYS + AT91_SDRAMC_CR)
+ .word CONFIG_SYS_SDRC_CR_VAL
+ .word (AT91_BASE_SYS + AT91_SDRAMC_MDR)
+ .word CONFIG_SYS_SDRC_MDR_VAL
+ .word (AT91_BASE_SYS + AT91_SDRAMC_MR)
+ .word CONFIG_SYS_SDRC_MR_VAL2
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL1
+ .word (AT91_BASE_SYS + AT91_SDRAMC_MR)
+ .word CONFIG_SYS_SDRC_MR_VAL3
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL2
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL3
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL4
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL5
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL6
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL7
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL8
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL9
+ .word (AT91_BASE_SYS + AT91_SDRAMC_MR)
+ .word CONFIG_SYS_SDRC_MR_VAL4
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL10
+ .word (AT91_BASE_SYS + AT91_SDRAMC_MR)
+ .word CONFIG_SYS_SDRC_MR_VAL5
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL11
+ .word (AT91_BASE_SYS + AT91_SDRAMC_TR)
+ .word CONFIG_SYS_SDRC_TR_VAL2
+ .word AT91_SDRAM_BASE
+ .word CONFIG_SYS_SDRAM_VAL12
+ /* User reset enable*/
+ .word (AT91_BASE_SYS + AT91_RSTC_MR)
+ .word CONFIG_SYS_RSTC_RMR_VAL
+#ifdef CONFIG_SYS_MATRIX_MCFG_REMAP
+ /* MATRIX_MCFG - REMAP all masters */
+ .word (AT91_BASE_SYS + AT91_MATRIX_MCFG0)
+ .word 0x1FF
+#endif
+
+SMRDATA2:
+ .word 0
diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c
new file mode 100644
index 0000000000..f3f885c72b
--- /dev/null
+++ b/arch/arm/mach-at91/sam9_smc.c
@@ -0,0 +1,48 @@
+/*
+ * linux/arch/arm/mach-at91/sam9_smc.c
+ *
+ * Copyright (C) 2008 Andrew Victor
+ *
+ * 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 <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/io.h>
+
+#include <asm/arch/at91sam9_smc.h>
+#include <asm/arch/sam9_smc.h>
+
+void sam9_smc_configure(int cs, struct sam9_smc_config* config)
+{
+ /* Setup register */
+ at91_sys_write(AT91_SMC_SETUP(cs),
+ AT91_SMC_NWESETUP_(config->nwe_setup)
+ | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup)
+ | AT91_SMC_NRDSETUP_(config->nrd_setup)
+ | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup)
+ );
+
+ /* Pulse register */
+ at91_sys_write(AT91_SMC_PULSE(cs),
+ AT91_SMC_NWEPULSE_(config->nwe_pulse)
+ | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse)
+ | AT91_SMC_NRDPULSE_(config->nrd_pulse)
+ | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse)
+ );
+
+ /* Cycle register */
+ at91_sys_write(AT91_SMC_CYCLE(cs),
+ AT91_SMC_NWECYCLE_(config->write_cycle)
+ | AT91_SMC_NRDCYCLE_(config->read_cycle)
+ );
+
+ /* Mode register */
+ at91_sys_write(AT91_SMC_MODE(cs),
+ config->mode
+ | AT91_SMC_TDF_(config->tdf_cycles)
+ );
+}