diff options
Diffstat (limited to 'arch/arm/mach-at91')
46 files changed, 1052 insertions, 122 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index a048b92cb40..5aafb2e2ca7 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -175,6 +175,15 @@ config MACH_SAM9_L9260 Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260. <http://www.olimex.com/dev/sam9-L9260.html> +config MACH_AFEB9260 + bool "Custom afeb9260 board v1" + depends on ARCH_AT91SAM9260 + help + Select this if you are using custom afeb9260 board based on + open hardware design. Select this for revision 1 of the board. + <svn://194.85.238.22/home/users/george/svn/arm9eb> + <http://groups.google.com/group/arm9fpga-evolution-board> + config MACH_USB_A9260 bool "CALAO USB-A9260" depends on ARCH_AT91SAM9260 @@ -314,6 +323,19 @@ config AT91_PROGRAMMABLE_CLOCKS Select this if you need to program one or more of the PCK0..PCK3 programmable clock outputs. +config AT91_SLOW_CLOCK + bool "Suspend-to-RAM disables main oscillator" + depends on SUSPEND + help + Select this if you want Suspend-to-RAM to save the most power + possible (without powering off the CPU) by disabling the PLLs + and main oscillator so that only the 32 KiHz clock is available. + + When only that slow-clock is available, some peripherals lose + functionality. Many can't issue wakeup events unless faster + clocks are available. Some lose their operating state and + need to be completely re-initialized. + config AT91_TIMER_HZ int "Kernel HZ (jiffies per second)" range 32 1024 diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 7d641f97516..cca612d97ca 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_MACH_CAM60) += board-cam60.o obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o +obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o # AT91SAM9261 board-specific support obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o @@ -64,6 +65,7 @@ obj-y += leds.o # Power Management obj-$(CONFIG_PM) += pm.o +obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o ifeq ($(CONFIG_PM_DEBUG),y) CFLAGS_pm.o += -DDEBUG diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index 638948c1677..0fc0adaebd5 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -141,8 +141,8 @@ static struct clk tcb_clk = { .pmc_mask = 1 << AT91CAP9_ID_TCB, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk pwmc_clk = { - .name = "pwmc_clk", +static struct clk pwm_clk = { + .name = "pwm_clk", .pmc_mask = 1 << AT91CAP9_ID_PWMC, .type = CLK_TYPE_PERIPHERAL, }; @@ -207,7 +207,7 @@ static struct clk *periph_clocks[] __initdata = { &ssc1_clk, &ac97_clk, &tcb_clk, - &pwmc_clk, + &pwm_clk, &macb_clk, &aestdes_clk, &adc_clk, diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index abb4aac8fa9..5ebd4273d35 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -719,6 +719,60 @@ static void __init at91_add_device_watchdog(void) {} /* -------------------------------------------------------------------- + * PWM + * --------------------------------------------------------------------*/ + +#if defined(CONFIG_ATMEL_PWM) +static u32 pwm_mask; + +static struct resource pwm_resources[] = { + [0] = { + .start = AT91CAP9_BASE_PWMC, + .end = AT91CAP9_BASE_PWMC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_ID_PWMC, + .end = AT91CAP9_ID_PWMC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91cap9_pwm0_device = { + .name = "atmel_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_mask, + }, + .resource = pwm_resources, + .num_resources = ARRAY_SIZE(pwm_resources), +}; + +void __init at91_add_device_pwm(u32 mask) +{ + if (mask & (1 << AT91_PWM0)) + at91_set_A_periph(AT91_PIN_PB19, 1); /* enable PWM0 */ + + if (mask & (1 << AT91_PWM1)) + at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */ + + if (mask & (1 << AT91_PWM2)) + at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */ + + if (mask & (1 << AT91_PWM3)) + at91_set_B_periph(AT91_PIN_PA11, 1); /* enable PWM3 */ + + pwm_mask = mask; + + platform_device_register(&at91cap9_pwm0_device); +} +#else +void __init at91_add_device_pwm(u32 mask) {} +#endif + + + +/* -------------------------------------------------------------------- * AC97 * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 80bfab5680e..ada4b676910 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -129,8 +129,8 @@ static struct clk tcb_clk = { .pmc_mask = 1 << AT91SAM9263_ID_TCB, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk pwmc_clk = { - .name = "pwmc_clk", +static struct clk pwm_clk = { + .name = "pwm_clk", .pmc_mask = 1 << AT91SAM9263_ID_PWMC, .type = CLK_TYPE_PERIPHERAL, }; @@ -187,7 +187,7 @@ static struct clk *periph_clocks[] __initdata = { &ssc1_clk, &ac97_clk, &tcb_clk, - &pwmc_clk, + &pwm_clk, &macb_clk, &twodge_clk, &udc_clk, diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index c93992f55dc..8b884083f76 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -886,6 +886,59 @@ static void __init at91_add_device_watchdog(void) {} /* -------------------------------------------------------------------- + * PWM + * --------------------------------------------------------------------*/ + +#if defined(CONFIG_ATMEL_PWM) +static u32 pwm_mask; + +static struct resource pwm_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_PWMC, + .end = AT91SAM9263_BASE_PWMC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_ID_PWMC, + .end = AT91SAM9263_ID_PWMC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9263_pwm0_device = { + .name = "atmel_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_mask, + }, + .resource = pwm_resources, + .num_resources = ARRAY_SIZE(pwm_resources), +}; + +void __init at91_add_device_pwm(u32 mask) +{ + if (mask & (1 << AT91_PWM0)) + at91_set_B_periph(AT91_PIN_PB7, 1); /* enable PWM0 */ + + if (mask & (1 << AT91_PWM1)) + at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */ + + if (mask & (1 << AT91_PWM2)) + at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */ + + if (mask & (1 << AT91_PWM3)) + at91_set_B_periph(AT91_PIN_PB29, 1); /* enable PWM3 */ + + pwm_mask = mask; + + platform_device_register(&at91sam9263_pwm0_device); +} +#else +void __init at91_add_device_pwm(u32 mask) {} +#endif + + +/* -------------------------------------------------------------------- * SSC -- Synchronous Serial Controller * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 556bddf35b4..252e954b49f 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -131,8 +131,8 @@ static struct clk tc2_clk = { .pmc_mask = 1 << AT91SAM9RL_ID_TC2, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk pwmc_clk = { - .name = "pwmc_clk", +static struct clk pwm_clk = { + .name = "pwm_clk", .pmc_mask = 1 << AT91SAM9RL_ID_PWMC, .type = CLK_TYPE_PERIPHERAL, }; @@ -180,7 +180,7 @@ static struct clk *periph_clocks[] __initdata = { &tc0_clk, &tc1_clk, &tc2_clk, - &pwmc_clk, + &pwm_clk, &tsc_clk, &dma_clk, &udphs_clk, diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 620886341fb..87deb1e1b52 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -527,6 +527,51 @@ static void __init at91_add_device_tc(void) { } /* -------------------------------------------------------------------- + * Touchscreen + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE) +static u64 tsadcc_dmamask = DMA_BIT_MASK(32); + +static struct resource tsadcc_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_TSC, + .end = AT91SAM9RL_BASE_TSC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_TSC, + .end = AT91SAM9RL_ID_TSC, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device at91sam9rl_tsadcc_device = { + .name = "atmel_tsadcc", + .id = -1, + .dev = { + .dma_mask = &tsadcc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = tsadcc_resources, + .num_resources = ARRAY_SIZE(tsadcc_resources), +}; + +void __init at91_add_device_tsadcc(void) +{ + at91_set_A_periph(AT91_PIN_PA17, 0); /* AD0_XR */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* AD1_XL */ + at91_set_A_periph(AT91_PIN_PA19, 0); /* AD2_YT */ + at91_set_A_periph(AT91_PIN_PA20, 0); /* AD3_TB */ + + platform_device_register(&at91sam9rl_tsadcc_device); +} +#else +void __init at91_add_device_tsadcc(void) {} +#endif + + +/* -------------------------------------------------------------------- * RTC * -------------------------------------------------------------------- */ @@ -592,6 +637,59 @@ static void __init at91_add_device_watchdog(void) {} /* -------------------------------------------------------------------- + * PWM + * --------------------------------------------------------------------*/ + +#if defined(CONFIG_ATMEL_PWM) +static u32 pwm_mask; + +static struct resource pwm_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_PWMC, + .end = AT91SAM9RL_BASE_PWMC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_ID_PWMC, + .end = AT91SAM9RL_ID_PWMC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9rl_pwm0_device = { + .name = "atmel_pwm", + .id = -1, + .dev = { + .platform_data = &pwm_mask, + }, + .resource = pwm_resources, + .num_resources = ARRAY_SIZE(pwm_resources), +}; + +void __init at91_add_device_pwm(u32 mask) +{ + if (mask & (1 << AT91_PWM0)) + at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM0 */ + + if (mask & (1 << AT91_PWM1)) + at91_set_B_periph(AT91_PIN_PB9, 1); /* enable PWM1 */ + + if (mask & (1 << AT91_PWM2)) + at91_set_B_periph(AT91_PIN_PD5, 1); /* enable PWM2 */ + + if (mask & (1 << AT91_PWM3)) + at91_set_B_periph(AT91_PIN_PD8, 1); /* enable PWM3 */ + + pwm_mask = mask; + + platform_device_register(&at91sam9rl_pwm0_device); +} +#else +void __init at91_add_device_pwm(u32 mask) {} +#endif + + +/* -------------------------------------------------------------------- * SSC -- Synchronous Serial Controller * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c index 869b5e28d19..dfff2895f4b 100644 --- a/arch/arm/mach-at91/at91x40_time.c +++ b/arch/arm/mach-at91/at91x40_time.c @@ -23,8 +23,8 @@ #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/time.h> +#include <linux/io.h> #include <mach/hardware.h> -#include <asm/io.h> #include <asm/mach/time.h> #include <mach/at91_tc.h> diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c new file mode 100644 index 00000000000..9c040c78889 --- /dev/null +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -0,0 +1,210 @@ +/* + * linux/arch/arm/mach-at91/board-afeb-9260v1.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * Copyright (C) 2008 Sergey Lapin + * + * A custom board designed as open hardware; PCBs and various information + * is available at http://groups.google.com/group/arm9fpga-evolution-board/ + * Subversion repository: svn://194.85.238.22/home/users/george/svn/arm9eb + * + * 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/clk.h> +#include <linux/dma-mapping.h> + +#include <mach/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 <mach/board.h> +#include <mach/gpio.h> + +#include "generic.h" + + +static void __init afeb9260_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* 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 afeb9260_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata afeb9260_usbh_data = { + .ports = 1, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata afeb9260_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + + +/* + * SPI devices. + */ +static struct spi_board_info afeb9260_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata afeb9260_macb_data = { + .phy_irq_pin = AT91_PIN_PA9, + .is_rmii = 0, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata afeb9260_nand_partition[] = { + { + .name = "bootloader", + .offset = 0, + .size = (640 * SZ_1K), + }, + { + .name = "kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_2M, + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(afeb9260_nand_partition); + return afeb9260_nand_partition; +} + +static struct atmel_nand_data __initdata afeb9260_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, + .bus_width_16 = 0, +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata afeb9260_mmc_data = { + .slot_b = 1, + .wire4 = 1, +}; + + + +static struct i2c_board_info __initdata afeb9260_i2c_devices[] = { + { + I2C_BOARD_INFO("fm3130", 0x68), + I2C_BOARD_INFO("24c64", 0x50), + }, +}; + +static void __init afeb9260_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&afeb9260_usbh_data); + /* USB Device */ + at91_add_device_udc(&afeb9260_udc_data); + /* SPI */ + at91_add_device_spi(afeb9260_spi_devices, + ARRAY_SIZE(afeb9260_spi_devices)); + /* NAND */ + at91_add_device_nand(&afeb9260_nand_data); + /* Ethernet */ + at91_add_device_eth(&afeb9260_macb_data); + + /* Standard function's pin assignments are not + * appropriate for us and generic code provide + * no API to configure these pins any other way */ + at91_set_B_periph(AT91_PIN_PA10, 0); /* ETX2 */ + at91_set_B_periph(AT91_PIN_PA11, 0); /* ETX3 */ + /* MMC */ + at91_add_device_mmc(0, &afeb9260_mmc_data); + /* I2C */ + at91_add_device_i2c(afeb9260_i2c_devices, + ARRAY_SIZE(afeb9260_i2c_devices)); +} + +MACHINE_START(AFEB9260, "Custom afeb9260 board") + /* Maintainer: Sergey Lapin <slapin@ossfans.org> */ + .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 = afeb9260_map_io, + .init_irq = afeb9260_init_irq, + .init_machine = afeb9260_board_init, +MACHINE_END + diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 196199552eb..201b89392dc 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -214,7 +214,7 @@ static struct physmap_flash_data cap9adk_nor_data = { }; #define NOR_BASE AT91_CHIPSELECT_0 -#define NOR_SIZE 0x800000 +#define NOR_SIZE SZ_8M static struct resource nor_flash_resources[] = { { diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c index afa1ff0e957..db1f9544d2e 100644 --- a/arch/arm/mach-at91/board-carmeva.c +++ b/arch/arm/mach-at91/board-carmeva.c @@ -25,7 +25,6 @@ #include <linux/module.h> #include <linux/platform_device.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -34,6 +33,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> @@ -114,6 +114,30 @@ static struct spi_board_info carmeva_spi_devices[] = { }, }; +static struct gpio_led carmeva_leds[] = { + { /* "user led 1", LED9 */ + .name = "led9", + .gpio = AT91_PIN_PA21, + .active_low = 1, + .default_trigger = "heartbeat", + }, + { /* "user led 2", LED10 */ + .name = "led10", + .gpio = AT91_PIN_PA25, + .active_low = 1, + }, + { /* "user led 3", LED11 */ + .name = "led11", + .gpio = AT91_PIN_PA26, + .active_low = 1, + }, + { /* "user led 4", LED12 */ + .name = "led12", + .gpio = AT91_PIN_PA18, + .active_low = 1, + } +}; + static void __init carmeva_board_init(void) { /* Serial */ @@ -132,6 +156,8 @@ static void __init carmeva_board_init(void) // at91_add_device_cf(&carmeva_cf_data); /* MMC */ at91_add_device_mmc(0, &carmeva_mmc_data); + /* LEDs */ + at91_gpio_leds(carmeva_leds, ARRAY_SIZE(carmeva_leds)); } MACHINE_START(CARMEVA, "Carmeva") diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index cb7c9a8fa48..fea2529ebcf 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c @@ -28,7 +28,6 @@ #include <linux/input.h> #include <linux/gpio_keys.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -37,6 +36,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> @@ -114,7 +114,7 @@ static struct spi_board_info csb337_spi_devices[] = { }; #define CSB_FLASH_BASE AT91_CHIPSELECT_0 -#define CSB_FLASH_SIZE 0x800000 +#define CSB_FLASH_SIZE SZ_8M static struct mtd_partition csb_flash_partitions[] = { { @@ -193,11 +193,11 @@ static struct platform_device csb300_button_device = { static void __init csb300_add_device_buttons(void) { - at91_set_gpio_input(AT91_PIN_PB29, 0); /* sw0 */ + at91_set_gpio_input(AT91_PIN_PB29, 1); /* sw0 */ at91_set_deglitch(AT91_PIN_PB29, 1); - at91_set_gpio_input(AT91_PIN_PB28, 0); /* sw1 */ + at91_set_gpio_input(AT91_PIN_PB28, 1); /* sw1 */ at91_set_deglitch(AT91_PIN_PB28, 1); - at91_set_gpio_input(AT91_PIN_PA21, 0); /* sw2 */ + at91_set_gpio_input(AT91_PIN_PA21, 1); /* sw2 */ at91_set_deglitch(AT91_PIN_PA21, 1); platform_device_register(&csb300_button_device); @@ -224,7 +224,7 @@ static struct gpio_led csb_leds[] = { .gpio = AT91_PIN_PB0, .active_low = 1, .default_trigger = "ide-disk", - }, + } }; diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c index 8db8bd8babd..cfa3f04b220 100644 --- a/arch/arm/mach-at91/board-csb637.c +++ b/arch/arm/mach-at91/board-csb637.c @@ -25,7 +25,6 @@ #include <linux/platform_device.h> #include <linux/mtd/physmap.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -34,6 +33,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> @@ -72,7 +72,7 @@ static struct at91_udc_data __initdata csb637_udc_data = { }; #define CSB_FLASH_BASE AT91_CHIPSELECT_0 -#define CSB_FLASH_SIZE 0x1000000 +#define CSB_FLASH_SIZE SZ_16M static struct mtd_partition csb_flash_partitions[] = { { diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c index 43e1aa7ecef..0fd0f5bc77e 100644 --- a/arch/arm/mach-at91/board-dk.c +++ b/arch/arm/mach-at91/board-dk.c @@ -29,7 +29,6 @@ #include <linux/spi/spi.h> #include <linux/mtd/physmap.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -38,6 +37,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91rm9200_mc.h> @@ -157,7 +157,7 @@ static struct atmel_nand_data __initdata dk_nand_data = { }; #define DK_FLASH_BASE AT91_CHIPSELECT_0 -#define DK_FLASH_SIZE 0x200000 +#define DK_FLASH_SIZE SZ_2M static struct physmap_flash_data dk_flash_data = { .width = 2, diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index bfeee8a2af2..1d69908617f 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c @@ -86,7 +86,7 @@ static struct mtd_partition __initdata my_flash0_partitions[] = { /* 0x8400 */ .name = "Darrell-loader", .offset = 0, - .size = 12* 1056, + .size = 12 * 1056, }, { .name = "U-boot", diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c index 60626e7a349..4cdfaac8e59 100644 --- a/arch/arm/mach-at91/board-ek.c +++ b/arch/arm/mach-at91/board-ek.c @@ -29,7 +29,6 @@ #include <linux/spi/spi.h> #include <linux/mtd/physmap.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -38,6 +37,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91rm9200_mc.h> @@ -116,7 +116,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = { }; #define EK_FLASH_BASE AT91_CHIPSELECT_0 -#define EK_FLASH_SIZE 0x200000 +#define EK_FLASH_SIZE SZ_2M static struct physmap_flash_data ek_flash_data = { .width = 2, diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index dbc912d633c..859727e7ea3 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c @@ -105,7 +105,7 @@ static struct at91_mmc_data __initdata picotux200_mmc_data = { // }; #define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0 -#define PICOTUX200_FLASH_SIZE 0x400000 +#define PICOTUX200_FLASH_SIZE SZ_4M static struct physmap_flash_data picotux200_flash_data = { .width = 2, diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 4c28413426c..cfb4571a2e2 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -30,7 +30,6 @@ #include <linux/input.h> #include <linux/clk.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -39,6 +38,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91_shdwc.h> @@ -119,18 +119,18 @@ static struct at91_eth_data __initdata ek_macb_data = { static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Uboot & Kernel", - .offset = 0x00000000, - .size = 16 * 1024 * 1024, + .offset = 0, + .size = SZ_16M, }, { .name = "Root FS", - .offset = 0x01000000, - .size = 120 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, }, { .name = "FS", - .offset = 0x08800000, - .size = 120 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, }, }; diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index e4910cb26c1..99bb4cc23a0 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -126,11 +126,11 @@ static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Bootloader Area", .offset = 0, - .size = 10 * 1024 * 1024, + .size = 10 * SZ_1M, }, { .name = "User Area", - .offset = 10 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, .size = MTDPART_SIZ_FULL, }, }; diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index cb20e70b3b0..b49eb6e4918 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -27,8 +27,10 @@ #include <linux/spi/spi.h> #include <linux/spi/at73c213.h> #include <linux/clk.h> +#include <linux/i2c/at24.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -37,6 +39,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> @@ -163,11 +166,11 @@ static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Partition 1", .offset = 0, - .size = 256 * 1024, + .size = SZ_256K, }, { .name = "Partition 2", - .offset = 256 * 1024, + .offset = MTDPART_OFS_NXTBLK, .size = MTDPART_SIZ_FULL, }, }; @@ -222,6 +225,73 @@ static struct gpio_led ek_leds[] = { } }; +/* + * I2C devices + */ +static struct at24_platform_data at24c512 = { + .byte_len = SZ_512K / 8, + .page_size = 128, + .flags = AT24_FLAG_ADDR16, +}; + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + .platform_data = &at24c512, + }, + /* more devices can be added using expansion connectors */ +}; + + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { + .gpio = AT91_PIN_PA30, + .code = BTN_3, + .desc = "Button 3", + .active_low = 1, + .wakeup = 1, + }, + { + .gpio = AT91_PIN_PA31, + .code = BTN_4, + .desc = "Button 4", + .active_low = 1, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data ek_button_data = { + .buttons = ek_buttons, + .nbuttons = ARRAY_SIZE(ek_buttons), +}; + +static struct platform_device ek_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ek_button_data, + } +}; + +static void __init ek_add_device_buttons(void) +{ + at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */ + at91_set_deglitch(AT91_PIN_PA30, 1); + at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */ + at91_set_deglitch(AT91_PIN_PA31, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + + static void __init ek_board_init(void) { /* Serial */ @@ -239,12 +309,14 @@ static void __init ek_board_init(void) /* MMC */ at91_add_device_mmc(0, &ek_mmc_data); /* I2C */ - at91_add_device_i2c(NULL, 0); + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); /* 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)); + /* Push Buttons */ + ek_add_device_buttons(); } 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 1a9963b811c..4977409d4fc 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -35,7 +35,6 @@ #include <video/atmel_lcdc.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -44,6 +43,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91sam9_smc.h> @@ -168,11 +168,11 @@ static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Partition 1", .offset = 0, - .size = 256 * 1024, + .size = SZ_256K, }, { .name = "Partition 2", - .offset = 256 * 1024 , + .offset = MTDPART_OFS_NXTBLK, .size = MTDPART_SIZ_FULL, }, }; @@ -435,24 +435,28 @@ static struct gpio_keys_button ek_buttons[] = { .code = BTN_0, .desc = "Button 0", .active_low = 1, + .wakeup = 1, }, { .gpio = AT91_PIN_PA26, .code = BTN_1, .desc = "Button 1", .active_low = 1, + .wakeup = 1, }, { .gpio = AT91_PIN_PA25, .code = BTN_2, .desc = "Button 2", .active_low = 1, + .wakeup = 1, }, { .gpio = AT91_PIN_PA24, .code = BTN_3, .desc = "Button 3", .active_low = 1, + .wakeup = 1, } }; @@ -472,13 +476,13 @@ static struct platform_device ek_button_device = { static void __init ek_add_device_buttons(void) { - at91_set_gpio_input(AT91_PIN_PA27, 0); /* btn0 */ + at91_set_gpio_input(AT91_PIN_PA27, 1); /* btn0 */ at91_set_deglitch(AT91_PIN_PA27, 1); - at91_set_gpio_input(AT91_PIN_PA26, 0); /* btn1 */ + at91_set_gpio_input(AT91_PIN_PA26, 1); /* btn1 */ at91_set_deglitch(AT91_PIN_PA26, 1); - at91_set_gpio_input(AT91_PIN_PA25, 0); /* btn2 */ + at91_set_gpio_input(AT91_PIN_PA25, 1); /* btn2 */ at91_set_deglitch(AT91_PIN_PA25, 1); - at91_set_gpio_input(AT91_PIN_PA24, 0); /* btn3 */ + at91_set_gpio_input(AT91_PIN_PA24, 1); /* btn3 */ at91_set_deglitch(AT91_PIN_PA24, 1); platform_device_register(&ek_button_device); diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index b1d11960a73..8354015c6a2 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -26,13 +26,14 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> +#include <linux/i2c/at24.h> #include <linux/fb.h> #include <linux/gpio_keys.h> #include <linux/input.h> +#include <linux/leds.h> #include <video/atmel_lcdc.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -41,6 +42,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91sam9_smc.h> @@ -172,11 +174,11 @@ static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Partition 1", .offset = 0, - .size = 64 * 1024 * 1024, + .size = SZ_64M, }, { .name = "Partition 2", - .offset = 64 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, .size = MTDPART_SIZ_FULL, }, }; @@ -203,12 +205,30 @@ static struct atmel_nand_data __initdata ek_nand_data = { /* + * I2C devices + */ +static struct at24_platform_data at24c512 = { + .byte_len = SZ_512K / 8, + .page_size = 128, + .flags = AT24_FLAG_ADDR16, +}; + + +static struct i2c_board_info __initdata ek_i2c_devices[] = { + { + I2C_BOARD_INFO("24c512", 0x50), + .platform_data = &at24c512, + }, + /* more devices can be added using expansion connectors */ +}; + +/* * LCD Controller */ #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) static struct fb_videomode at91_tft_vga_modes[] = { { - .name = "TX09D50VM1CCA @ 60", + .name = "TX09D50VM1CCA @ 60", .refresh = 60, .xres = 240, .yres = 320, .pixclock = KHZ2PICOS(4965), @@ -224,7 +244,7 @@ static struct fb_videomode at91_tft_vga_modes[] = { static struct fb_monspecs at91fb_default_monspecs = { .manufacturer = "HIT", - .monitor = "TX09D70VM1CCA", + .monitor = "TX09D70VM1CCA", .modedb = at91_tft_vga_modes, .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), @@ -235,7 +255,7 @@ static struct fb_monspecs at91fb_default_monspecs = { }; #define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ - | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_DISTYPE_TFT \ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) static void at91_lcdc_power_control(int on) @@ -277,7 +297,7 @@ static struct gpio_keys_button ek_buttons[] = { .active_low = 1, .desc = "right_click", .wakeup = 1, - }, + } }; static struct gpio_keys_platform_data ek_button_data = { @@ -296,9 +316,9 @@ static struct platform_device ek_button_device = { static void __init ek_add_device_buttons(void) { - at91_set_GPIO_periph(AT91_PIN_PC5, 0); /* left button */ + at91_set_GPIO_periph(AT91_PIN_PC5, 1); /* left button */ at91_set_deglitch(AT91_PIN_PC5, 1); - at91_set_GPIO_periph(AT91_PIN_PC4, 0); /* right button */ + at91_set_GPIO_periph(AT91_PIN_PC4, 1); /* right button */ at91_set_deglitch(AT91_PIN_PC4, 1); platform_device_register(&ek_button_device); @@ -320,25 +340,32 @@ static struct atmel_ac97_data ek_ac97_data = { * LEDs ... these could all be PWM-driven, for variable brightness */ static struct gpio_led ek_leds[] = { - { /* "left" led, green, userled1, pwm1 */ - .name = "ds1", - .gpio = AT91_PIN_PB8, - .active_low = 1, - .default_trigger = "mmc0", - }, - { /* "right" led, green, userled2, pwm2 */ + { /* "right" led, green, userled2 (could be driven by pwm2) */ .name = "ds2", .gpio = AT91_PIN_PC29, .active_low = 1, .default_trigger = "nand-disk", }, - { /* "power" led, yellow, pwm0 */ + { /* "power" led, yellow (could be driven by pwm0) */ .name = "ds3", .gpio = AT91_PIN_PB7, .default_trigger = "heartbeat", } }; +/* + * PWM Leds + */ +static struct gpio_led ek_pwm_led[] = { + /* For now only DS1 is PWM-driven (by pwm1) */ + { + .name = "ds1", + .gpio = 1, /* is PWM channel number */ + .active_low = 1, + .default_trigger = "none", + } +}; + static void __init ek_board_init(void) { @@ -360,7 +387,7 @@ static void __init ek_board_init(void) /* NAND */ at91_add_device_nand(&ek_nand_data); /* I2C */ - at91_add_device_i2c(NULL, 0); + at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); /* LCD Controller */ at91_add_device_lcdc(&ek_lcdc_data); /* Push Buttons */ @@ -369,6 +396,7 @@ static void __init ek_board_init(void) at91_add_device_ac97(&ek_ac97_data); /* LEDs */ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); } MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index d4eba5c0ce0..b588ead14d6 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -122,16 +122,16 @@ static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Bootstrap", .offset = 0, - .size = 4 * 1024 * 1024, + .size = 4 * SZ_1M, }, { .name = "Partition 1", - .offset = 4 * 1024 * 1024, - .size = 60 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, + .size = 60 * SZ_1M, }, { .name = "Partition 2", - .offset = 64 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, .size = MTDPART_SIZ_FULL, }, }; diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index c6dce49c388..27085186430 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -18,7 +18,6 @@ #include <video/atmel_lcdc.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -27,6 +26,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91sam9_smc.h> @@ -81,11 +81,11 @@ static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Partition 1", .offset = 0, - .size = 256 * 1024, + .size = SZ_256K, }, { .name = "Partition 2", - .offset = 256 * 1024 , + .offset = MTDPART_OFS_NXTBLK, .size = MTDPART_SIZ_FULL, }, }; @@ -195,6 +195,8 @@ static void __init ek_board_init(void) at91_add_device_mmc(0, &ek_mmc_data); /* LCD Controller */ at91_add_device_lcdc(&ek_lcdc_data); + /* Touch Screen Controller */ + at91_add_device_tsadcc(); } MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c index f9d0b65da40..7c350357333 100644 --- a/arch/arm/mach-at91/board-usb-a9260.c +++ b/arch/arm/mach-at91/board-usb-a9260.c @@ -30,7 +30,6 @@ #include <linux/input.h> #include <linux/clk.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -39,6 +38,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91_shdwc.h> @@ -93,18 +93,18 @@ static struct at91_eth_data __initdata ek_macb_data = { static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Uboot & Kernel", - .offset = 0x00000000, - .size = 16 * 1024 * 1024, + .offset = 0, + .size = SZ_16M, }, { .name = "Root FS", - .offset = 0x01000000, - .size = 120 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, }, { .name = "FS", - .offset = 0x08800000, - .size = 120 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, } }; diff --git a/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c index 673e5c27214..391b566c457 100644 --- a/arch/arm/mach-at91/board-usb-a9263.c +++ b/arch/arm/mach-at91/board-usb-a9263.c @@ -29,7 +29,6 @@ #include <linux/gpio_keys.h> #include <linux/input.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -38,6 +37,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91_shdwc.h> @@ -106,18 +106,18 @@ static struct at91_eth_data __initdata ek_macb_data = { static struct mtd_partition __initdata ek_nand_partition[] = { { .name = "Linux Kernel", - .offset = 0x00000000, - .size = 16 * 1024 * 1024, + .offset = 0, + .size = SZ_16M, }, { .name = "Root FS", - .offset = 0x01000000, - .size = 120 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, }, { .name = "FS", - .offset = 0x08800000, - .size = 120 * 1024 * 1024, + .offset = MTDPART_OFS_NXTBLK, + .size = 120 * SZ_1M, } }; diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index 36b380aad00..e22bf051f83 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -33,7 +33,6 @@ #include <linux/gpio_keys.h> #include <linux/input.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/irq.h> @@ -42,6 +41,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <mach/hardware.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/at91rm9200_mc.h> @@ -150,27 +150,27 @@ static struct mtd_partition __initdata yl9200_nand_partition[] = { { .name = "AT91 NAND partition 1, boot", .offset = 0, - .size = 1 * SZ_256K + .size = SZ_256K }, { .name = "AT91 NAND partition 2, kernel", - .offset = 1 * SZ_256K, - .size = 2 * SZ_1M - 1 * SZ_256K + .offset = MTDPART_OFS_NXTBLK, + .size = (2 * SZ_1M) - SZ_256K }, { .name = "AT91 NAND partition 3, filesystem", - .offset = 2 * SZ_1M, + .offset = MTDPART_OFS_NXTBLK, .size = 14 * SZ_1M }, { .name = "AT91 NAND partition 4, storage", - .offset = 16 * SZ_1M, - .size = 16 * SZ_1M + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_16M }, { .name = "AT91 NAND partition 5, ext-fs", - .offset = 32 * SZ_1M, - .size = 32 * SZ_1M + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_32M } }; @@ -193,24 +193,24 @@ static struct atmel_nand_data __initdata yl9200_nand_data = { * NOR Flash */ #define YL9200_FLASH_BASE AT91_CHIPSELECT_0 -#define YL9200_FLASH_SIZE 0x1000000 +#define YL9200_FLASH_SIZE SZ_16M static struct mtd_partition yl9200_flash_partitions[] = { { .name = "Bootloader", - .size = 0x00040000, .offset = 0, + .size = SZ_256K, .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { .name = "Kernel", - .size = 0x001C0000, - .offset = 0x00040000, + .offset = MTDPART_OFS_NXTBLK, + .size = (2 * SZ_1M) - SZ_256K }, { .name = "Filesystem", - .size = MTDPART_SIZ_FULL, - .offset = 0x00200000 + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL } }; @@ -390,10 +390,6 @@ static struct spi_board_info yl9200_spi_devices[] = { #if defined(CONFIG_FB_S1D135XX) || defined(CONFIG_FB_S1D13XXX_MODULE) #include <video/s1d13xxxfb.h> -#define AT91_FB_REG_BASE 0x80000000L -#define AT91_FB_REG_SIZE 0x200 -#define AT91_FB_VMEM_BASE 0x80200000L -#define AT91_FB_VMEM_SIZE 0x200000L static void __init yl9200_init_video(void) { @@ -516,29 +512,33 @@ static struct s1d13xxxfb_regval yl9200_s1dfb_initregs[] = {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/ }; -static u64 s1dfb_dmamask = DMA_BIT_MASK(32); - static struct s1d13xxxfb_pdata yl9200_s1dfb_pdata = { .initregs = yl9200_s1dfb_initregs, .initregssize = ARRAY_SIZE(yl9200_s1dfb_initregs), .platform_init_video = yl9200_init_video, }; +#define YL9200_FB_REG_BASE AT91_CHIPSELECT_7 +#define YL9200_FB_VMEM_BASE YL9200_FB_REG_BASE + SZ_2M +#define YL9200_FB_VMEM_SIZE SZ_2M + static struct resource yl9200_s1dfb_resource[] = { [0] = { /* video mem */ .name = "s1d13xxxfb memory", - .start = AT91_FB_VMEM_BASE, - .end = AT91_FB_VMEM_BASE + AT91_FB_VMEM_SIZE -1, + .start = YL9200_FB_VMEM_BASE, + .end = YL9200_FB_VMEM_BASE + YL9200_FB_VMEM_SIZE -1, .flags = IORESOURCE_MEM, }, [1] = { /* video registers */ .name = "s1d13xxxfb registers", - .start = AT91_FB_REG_BASE, - .end = AT91_FB_REG_BASE + AT91_FB_REG_SIZE -1, + .start = YL9200_FB_REG_BASE, + .end = YL9200_FB_REG_BASE + SZ_512 -1, .flags = IORESOURCE_MEM, }, }; +static u64 s1dfb_dmamask = DMA_BIT_MASK(32); + static struct platform_device yl9200_s1dfb_device = { .name = "s1d13806fb", .id = -1, diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index f5c2847161f..e4345106ee5 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -22,8 +22,7 @@ #include <linux/spinlock.h> #include <linux/delay.h> #include <linux/clk.h> - -#include <asm/io.h> +#include <linux/io.h> #include <mach/hardware.h> #include <mach/at91_pmc.h> diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 8392d5b517f..7e5ebb5bdd1 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -18,8 +18,8 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/io.h> -#include <asm/io.h> #include <mach/hardware.h> #include <mach/at91_pio.h> #include <mach/gpio.h> @@ -404,7 +404,6 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) } pin = bank->chipbase; - gpio = &irq_desc[pin]; while (isr) { if (isr & 1) { @@ -417,7 +416,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) gpio_irq_mask(pin); } else - desc_handle_irq(pin, gpio); + generic_handle_irq(pin); } pin++; gpio++; diff --git a/arch/arm/mach-at91/include/mach/at91_pit.h b/arch/arm/mach-at91/include/mach/at91_pit.h index 0448ac36ead..974d0bd05b5 100644 --- a/arch/arm/mach-at91/include/mach/at91_pit.h +++ b/arch/arm/mach-at91/include/mach/at91_pit.h @@ -1,6 +1,9 @@ /* * arch/arm/mach-at91/include/mach/at91_pit.h * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * * Periodic Interval Timer (PIT) - System peripherals regsters. * Based on AT91SAM9261 datasheet revision D. * diff --git a/arch/arm/mach-at91/include/mach/at91_rstc.h b/arch/arm/mach-at91/include/mach/at91_rstc.h index 7cd1b39aaa4..cbd2bf052c1 100644 --- a/arch/arm/mach-at91/include/mach/at91_rstc.h +++ b/arch/arm/mach-at91/include/mach/at91_rstc.h @@ -1,6 +1,9 @@ /* * arch/arm/mach-at91/include/mach/at91_rstc.h * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * * Reset Controller (RSTC) - System peripherals regsters. * Based on AT91SAM9261 datasheet revision D. * diff --git a/arch/arm/mach-at91/include/mach/at91_rtt.h b/arch/arm/mach-at91/include/mach/at91_rtt.h index 71782e5d215..7ec75de8bbb 100644 --- a/arch/arm/mach-at91/include/mach/at91_rtt.h +++ b/arch/arm/mach-at91/include/mach/at91_rtt.h @@ -1,6 +1,9 @@ /* * arch/arm/mach-at91/include/mach/at91_rtt.h * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * * Real-time Timer (RTT) - System peripherals regsters. * Based on AT91SAM9261 datasheet revision D. * diff --git a/arch/arm/mach-at91/include/mach/at91_shdwc.h b/arch/arm/mach-at91/include/mach/at91_shdwc.h index 60be5ae624f..c4ce07e8a8f 100644 --- a/arch/arm/mach-at91/include/mach/at91_shdwc.h +++ b/arch/arm/mach-at91/include/mach/at91_shdwc.h @@ -1,6 +1,9 @@ /* * arch/arm/mach-at91/include/mach/at91_shdwc.h * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * * Shutdown Controller (SHDWC) - System peripherals regsters. * Based on AT91SAM9261 datasheet revision D. * diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h index 973b4526a98..fecc2e9f0ca 100644 --- a/arch/arm/mach-at91/include/mach/at91_wdt.h +++ b/arch/arm/mach-at91/include/mach/at91_wdt.h @@ -1,6 +1,9 @@ /* * arch/arm/mach-at91/include/mach/at91_wdt.h * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * * Watchdog Timer (WDT) - System peripherals regsters. * Based on AT91SAM9261 datasheet revision D. * diff --git a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h index bca878f3bd8..1499b1cbffd 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h +++ b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h @@ -1,6 +1,8 @@ /* * arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h * + * (C) 2008 Andrew Victor + * * DDR/SDR Controller (DDRSDRC) - System peripherals registers. * Based on AT91CAP9 datasheet revision B. * diff --git a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h index f027de5df95..020f02ed921 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h @@ -1,6 +1,8 @@ /* * arch/arm/mach-at91/include/mach/at91sam9260_matrix.h * + * Copyright (C) 2007 Atmel Corporation. + * * Memory Controllers (MATRIX, EBI) - System peripherals registers. * Based on AT91SAM9260 datasheet revision B. * diff --git a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h index db62b1f1830..69c6501915d 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h @@ -1,6 +1,8 @@ /* * arch/arm/mach-at91/include/mach/at91sam9261_matrix.h * + * Copyright (C) 2007 Atmel Corporation. + * * Memory Controllers (MATRIX, EBI) - System peripherals registers. * Based on AT91SAM9261 datasheet revision D. * diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h index 1921181c63c..b7260389f7c 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h @@ -1,6 +1,9 @@ /* * arch/arm/mach-at91/include/mach/at91sam9_sdramc.h * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * * SDRAM Controllers (SDRAMC) - System peripherals registers. * Based on AT91SAM9261 datasheet revision D. * diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h index ec6ad1338b5..57de6207e57 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_smc.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h @@ -1,6 +1,9 @@ /* * arch/arm/mach-at91/include/mach/at91sam9_smc.h * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * * Static Memory Controllers (SMC) - System peripherals registers. * Based on AT91SAM9261 datasheet revision D. * diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index acd60f2a072..fb51f0e0a83 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -133,6 +133,16 @@ struct atmel_uart_data { extern void __init at91_add_device_serial(void); /* + * PWM + */ +#define AT91_PWM0 0 +#define AT91_PWM1 1 +#define AT91_PWM2 2 +#define AT91_PWM3 3 + +extern void __init at91_add_device_pwm(u32 mask); + +/* * SSC -- accessed through ssc_request(id). Drivers don't bind to SSC * platform devices. Their SSC ID is part of their configuration data, * along with information about which SSC signals they should use. @@ -162,9 +172,13 @@ extern void __init at91_add_device_ac97(struct atmel_ac97_data *data); /* ISI */ extern void __init at91_add_device_isi(void); + /* Touchscreen Controller */ +extern void __init at91_add_device_tsadcc(void); + /* LEDs */ extern void __init at91_init_leds(u8 cpu_led, u8 timer_led); extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); +extern void __init at91_pwm_leds(struct gpio_led *leds, int nr); /* FIXME: this needs a better location, but gets stuff building again */ extern int at91_suspend_entering_slow_clock(void); diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h index bda29ccbcd9..36bd55f3fc6 100644 --- a/arch/arm/mach-at91/include/mach/irqs.h +++ b/arch/arm/mach-at91/include/mach/irqs.h @@ -21,7 +21,7 @@ #ifndef __ASM_ARCH_IRQS_H #define __ASM_ARCH_IRQS_H -#include <asm/io.h> +#include <linux/io.h> #include <mach/at91_aic.h> #define NR_AIC_IRQS 32 diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h index 0410d548e9b..18bdcdeb474 100644 --- a/arch/arm/mach-at91/include/mach/uncompress.h +++ b/arch/arm/mach-at91/include/mach/uncompress.h @@ -21,7 +21,7 @@ #ifndef __ASM_ARCH_UNCOMPRESS_H #define __ASM_ARCH_UNCOMPRESS_H -#include <asm/io.h> +#include <linux/io.h> #include <linux/atmel_serial.h> #if defined(CONFIG_AT91_EARLY_DBGU) diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c index fec03c59ff9..0415a839e1a 100644 --- a/arch/arm/mach-at91/leds.c +++ b/arch/arm/mach-at91/leds.c @@ -12,6 +12,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> +#include <linux/platform_device.h> #include <mach/board.h> #include <mach/gpio.h> @@ -21,15 +22,13 @@ #if defined(CONFIG_NEW_LEDS) -#include <linux/platform_device.h> - /* * New cross-platform LED support. */ static struct gpio_led_platform_data led_data; -static struct platform_device at91_leds = { +static struct platform_device at91_gpio_leds_device = { .name = "leds-gpio", .id = -1, .dev.platform_data = &led_data, @@ -47,7 +46,7 @@ void __init at91_gpio_leds(struct gpio_led *leds, int nr) led_data.leds = leds; led_data.num_leds = nr; - platform_device_register(&at91_leds); + platform_device_register(&at91_gpio_leds_device); } #else @@ -57,6 +56,44 @@ void __init at91_gpio_leds(struct gpio_led *leds, int nr) {} /* ------------------------------------------------------------------------- */ +#if defined (CONFIG_LEDS_ATMEL_PWM) + +/* + * PWM Leds + */ + +static struct gpio_led_platform_data pwm_led_data; + +static struct platform_device at91_pwm_leds_device = { + .name = "leds-atmel-pwm", + .id = -1, + .dev.platform_data = &pwm_led_data, +}; + +void __init at91_pwm_leds(struct gpio_led *leds, int nr) +{ + int i; + u32 pwm_mask = 0; + + if (!nr) + return; + + for (i = 0; i < nr; i++) + pwm_mask |= (1 << leds[i].gpio); + + pwm_led_data.leds = leds; + pwm_led_data.num_leds = nr; + + at91_add_device_pwm(pwm_mask); + platform_device_register(&at91_pwm_leds_device); +} +#else +void __init at91_pwm_leds(struct gpio_led *leds, int nr){} +#endif + + +/* ------------------------------------------------------------------------- */ + #if defined(CONFIG_LEDS) #include <asm/leds.h> diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index ec2fe4ca1e2..9bb4f043aa2 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -17,8 +17,8 @@ #include <linux/sysfs.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/io.h> -#include <asm/io.h> #include <asm/irq.h> #include <asm/atomic.h> #include <asm/mach/time.h> diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S new file mode 100644 index 00000000000..987fab3d846 --- /dev/null +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -0,0 +1,283 @@ +/* + * arch/arm/mach-at91/pm_slow_clock.S + * + * Copyright (C) 2006 Savin Zlobec + * + * AT91SAM9 support: + * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee + * + * 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/linkage.h> +#include <mach/hardware.h> +#include <mach/at91_pmc.h> + +#ifdef CONFIG_ARCH_AT91RM9200 +#include <mach/at91rm9200_mc.h> +#elif defined(CONFIG_ARCH_AT91CAP9) +#include <mach/at91cap9_ddrsdr.h> +#else +#include <mach/at91sam9_sdramc.h> +#endif + + +#ifdef CONFIG_ARCH_AT91SAM9263 +/* + * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; + * handle those cases both here and in the Suspend-To-RAM support. + */ +#define AT91_SDRAMC AT91_SDRAMC0 +#warning Assuming EB1 SDRAM controller is *NOT* used +#endif + +/* + * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master + * clock during suspend by adjusting its prescalar and divisor. + * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there + * are errata regarding adjusting the prescalar and divisor. + */ +#undef SLOWDOWN_MASTER_CLOCK + +#define MCKRDY_TIMEOUT 1000 +#define MOSCRDY_TIMEOUT 1000 +#define PLLALOCK_TIMEOUT 1000 +#define PLLBLOCK_TIMEOUT 1000 + + +/* + * Wait until master clock is ready (after switching master clock source) + */ + .macro wait_mckrdy + mov r4, #MCKRDY_TIMEOUT +1: sub r4, r4, #1 + cmp r4, #0 + beq 2f + ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] + tst r3, #AT91_PMC_MCKRDY + beq 1b +2: + .endm + +/* + * Wait until master oscillator has stabilized. + */ + .macro wait_moscrdy + mov r4, #MOSCRDY_TIMEOUT +1: sub r4, r4, #1 + cmp r4, #0 + beq 2f + ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] + tst r3, #AT91_PMC_MOSCS + beq 1b +2: + .endm + +/* + * Wait until PLLA has locked. + */ + .macro wait_pllalock + mov r4, #PLLALOCK_TIMEOUT +1: sub r4, r4, #1 + cmp r4, #0 + beq 2f + ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] + tst r3, #AT91_PMC_LOCKA + beq 1b +2: + .endm + +/* + * Wait until PLLB has locked. + */ + .macro wait_pllblock + mov r4, #PLLBLOCK_TIMEOUT +1: sub r4, r4, #1 + cmp r4, #0 + beq 2f + ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] + tst r3, #AT91_PMC_LOCKB + beq 1b +2: + .endm + + .text + +ENTRY(at91_slow_clock) + /* Save registers on stack */ + stmfd sp!, {r0 - r12, lr} + + /* + * Register usage: + * R1 = Base address of AT91_PMC + * R2 = Base address of AT91_SDRAMC (or AT91_SYS on AT91RM9200) + * R3 = temporary register + * R4 = temporary register + */ + ldr r1, .at91_va_base_pmc + ldr r2, .at91_va_base_sdramc + + /* Drain write buffer */ + mcr p15, 0, r0, c7, c10, 4 + +#ifdef CONFIG_ARCH_AT91RM9200 + /* Put SDRAM in self-refresh mode */ + mov r3, #1 + str r3, [r2, #AT91_SDRAMC_SRR] +#elif defined(CONFIG_ARCH_AT91CAP9) + /* Enable SDRAM self-refresh mode */ + ldr r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC] + str r3, .saved_sam9_lpr + + mov r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH + str r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC] +#else + /* Enable SDRAM self-refresh mode */ + ldr r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC] + str r3, .saved_sam9_lpr + + mov r3, #AT91_SDRAMC_LPCB_SELF_REFRESH + str r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC] +#endif + + /* Save Master clock setting */ + ldr r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + str r3, .saved_mckr + + /* + * Set the Master clock source to slow clock + */ + bic r3, r3, #AT91_PMC_CSS + str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + + wait_mckrdy + +#ifdef SLOWDOWN_MASTER_CLOCK + /* + * Set the Master Clock PRES and MDIV fields. + * + * See AT91RM9200 errata #27 and #28 for details. + */ + mov r3, #0 + str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + + wait_mckrdy +#endif + + /* Save PLLA setting and disable it */ + ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + str r3, .saved_pllar + + mov r3, #AT91_PMC_PLLCOUNT + orr r3, r3, #(1 << 29) /* bit 29 always set */ + str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + + wait_pllalock + + /* Save PLLB setting and disable it */ + ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + str r3, .saved_pllbr + + mov r3, #AT91_PMC_PLLCOUNT + str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + + wait_pllblock + + /* Turn off the main oscillator */ + ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + bic r3, r3, #AT91_PMC_MOSCEN + str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + + /* Wait for interrupt */ + mcr p15, 0, r0, c7, c0, 4 + + /* Turn on the main oscillator */ + ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + orr r3, r3, #AT91_PMC_MOSCEN + str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + + wait_moscrdy + + /* Restore PLLB setting */ + ldr r3, .saved_pllbr + str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + + wait_pllblock + + /* Restore PLLA setting */ + ldr r3, .saved_pllar + str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + + wait_pllalock + +#ifdef SLOWDOWN_MASTER_CLOCK + /* + * First set PRES if it was not 0, + * than set CSS and MDIV fields. + * + * See AT91RM9200 errata #27 and #28 for details. + */ + ldr r3, .saved_mckr + tst r3, #AT91_PMC_PRES + beq 2f + and r3, r3, #AT91_PMC_PRES + str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + + wait_mckrdy +#endif + + /* + * Restore master clock setting + */ +2: ldr r3, .saved_mckr + str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + + wait_mckrdy + +#ifdef CONFIG_ARCH_AT91RM9200 + /* Do nothing - self-refresh is automatically disabled. */ +#elif defined(CONFIG_ARCH_AT91CAP9) + /* Restore LPR on AT91CAP9 */ + ldr r3, .saved_sam9_lpr + str r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC] +#else + /* Restore LPR on AT91SAM9 */ + ldr r3, .saved_sam9_lpr + str r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC] +#endif + + /* Restore registers, and return */ + ldmfd sp!, {r0 - r12, pc} + + +.saved_mckr: + .word 0 + +.saved_pllar: + .word 0 + +.saved_pllbr: + .word 0 + +.saved_sam9_lpr: + .word 0 + +.at91_va_base_pmc: + .word AT91_VA_BASE_SYS + AT91_PMC + +#ifdef CONFIG_ARCH_AT91RM9200 +.at91_va_base_sdramc: + .word AT91_VA_BASE_SYS +#elif defined(CONFIG_ARCH_AT91CAP9) +.at91_va_base_sdramc: + .word AT91_VA_BASE_SYS + AT91_DDRSDRC +#else +.at91_va_base_sdramc: + .word AT91_VA_BASE_SYS + AT91_SDRAMC +#endif + +ENTRY(at91_slow_clock_sz) + .word .-at91_slow_clock |