diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 11:58:30 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 11:58:30 -0800 |
commit | 08249903ea233a79b4167395f2fb79ccd1fb5f94 (patch) | |
tree | 13285b46a495b578f721bb83024dae579466e089 /arch | |
parent | 0d6326a100d7aec588d7c1da9ad77ca7cc7c5b71 (diff) | |
parent | 183b3af66eb71b5337be10d82dd177a8e3f414e1 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6:
avr32: Move syscalls.h under arch/avr32/include/asm/
avr32: Define DIE_OOPS
avr32: Remove DMATEST from defconfigs
arch/avr32: Eliminate NULL test and memset after alloc_bootmem
avr32: data param to at32_add_device_mci() must be non-NULL
atmel-mci: move atmel-mci.h file to include/linux
avr32: Hammerhead board support
avr32: Allow reserving multiple pins at once
favr-32: Remove deprecated call
MIMC200: Remove deprecated call
avr: struct device - replace bus_id with dev_name(), dev_set_name()
avr32: Introducing asm/syscalls.h
Diffstat (limited to 'arch')
31 files changed, 2248 insertions, 115 deletions
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 26eca87f6735..b189680d18b0 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -122,6 +122,24 @@ config BOARD_ATNGW100 bool "ATNGW100 Network Gateway" select CPU_AT32AP7000 +config BOARD_HAMMERHEAD + bool "Hammerhead board" + select CPU_AT32AP7000 + select USB_ARCH_HAS_HCD + help + The Hammerhead platform is built around a AVR32 32-bit microcontroller from Atmel. + It offers versatile peripherals, such as ethernet, usb device, usb host etc. + + The board also incooperates a power supply and is a Power over Ethernet (PoE) Powered + Device (PD). + + Additonally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is + mapped into the 32-bit AVR memory bus. The FPGA offers two DDR2 SDRAM interfaces, which + will cover even the most exceptional need of memory bandwidth. Together with the onboard + video decoder the board is ready for video processing. + + For more information see: http://www.miromico.com/hammerhead + config BOARD_FAVR_32 bool "Favr-32 LCD-board" select CPU_AT32AP7000 @@ -133,6 +151,7 @@ endchoice source "arch/avr32/boards/atstk1000/Kconfig" source "arch/avr32/boards/atngw100/Kconfig" +source "arch/avr32/boards/hammerhead/Kconfig" source "arch/avr32/boards/favr-32/Kconfig" choice diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile index b088e103e753..f3ef3bbf797c 100644 --- a/arch/avr32/Makefile +++ b/arch/avr32/Makefile @@ -33,6 +33,7 @@ head-y += arch/avr32/kernel/head.o core-y += $(machdirs) core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/ core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/ +core-$(CONFIG_BOARD_HAMMERHEAD) += arch/avr32/boards/hammerhead/ core-$(CONFIG_BOARD_FAVR_32) += arch/avr32/boards/favr-32/ core-$(CONFIG_BOARD_MIMC200) += arch/avr32/boards/mimc200/ core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/ diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index 32fb9ba0fbdf..05d3722fff18 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c @@ -19,8 +19,8 @@ #include <linux/types.h> #include <linux/leds.h> #include <linux/spi/spi.h> +#include <linux/atmel-mci.h> -#include <asm/atmel-mci.h> #include <asm/io.h> #include <asm/setup.h> diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 5c5cdf3b464f..1f33a106905c 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -16,12 +16,12 @@ #include <linux/types.h> #include <linux/spi/spi.h> #include <linux/spi/at73c213.h> +#include <linux/atmel-mci.h> #include <video/atmel_lcdc.h> #include <asm/io.h> #include <asm/setup.h> -#include <asm/atmel-mci.h> #include <mach/at32ap700x.h> #include <mach/board.h> @@ -287,23 +287,7 @@ static int __init atstk1002_init(void) * ATSTK1000 uses 32-bit SDRAM interface. Reserve the * SDRAM-specific pins so that nobody messes with them. */ - at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */ - at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */ - at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */ - at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */ - at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */ - at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */ - at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */ - at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */ - at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */ - at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */ - at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */ - at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */ - at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */ - at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */ - at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */ - at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */ - at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */ + at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); #ifdef CONFIG_BOARD_ATSTK1006 smc_set_timing(&nand_config, &nand_timing); diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c index 134b566630b0..b3a23c88bcfe 100644 --- a/arch/avr32/boards/atstk1000/atstk1003.c +++ b/arch/avr32/boards/atstk1000/atstk1003.c @@ -17,9 +17,9 @@ #include <linux/spi/at73c213.h> #include <linux/spi/spi.h> +#include <linux/atmel-mci.h> #include <asm/setup.h> -#include <asm/atmel-mci.h> #include <mach/at32ap700x.h> #include <mach/board.h> @@ -131,23 +131,7 @@ static int __init atstk1003_init(void) * ATSTK1000 uses 32-bit SDRAM interface. Reserve the * SDRAM-specific pins so that nobody messes with them. */ - at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */ - at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */ - at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */ - at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */ - at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */ - at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */ - at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */ - at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */ - at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */ - at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */ - at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */ - at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */ - at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */ - at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */ - at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */ - at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */ - at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */ + at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); #ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM at32_add_device_usart(1); diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c index cb32eb844aa7..29b35aca96cd 100644 --- a/arch/avr32/boards/atstk1000/atstk1004.c +++ b/arch/avr32/boards/atstk1000/atstk1004.c @@ -17,11 +17,11 @@ #include <linux/spi/at73c213.h> #include <linux/spi/spi.h> +#include <linux/atmel-mci.h> #include <video/atmel_lcdc.h> #include <asm/setup.h> -#include <asm/atmel-mci.h> #include <mach/at32ap700x.h> #include <mach/board.h> diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c index 1ee4faf0742d..745c408c2ac5 100644 --- a/arch/avr32/boards/favr-32/setup.c +++ b/arch/avr32/boards/favr-32/setup.c @@ -17,6 +17,7 @@ #include <linux/linkage.h> #include <linux/gpio.h> #include <linux/leds.h> +#include <linux/atmel-mci.h> #include <linux/atmel-pwm-bl.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> @@ -79,6 +80,14 @@ static struct spi_board_info __initdata spi1_board_info[] = { }, }; +static struct mci_platform_data __initdata mci0_data = { + .slot[0] = { + .bus_width = 4, + .detect_pin = -ENODEV, + .wp_pin = -ENODEV, + }, +}; + static struct fb_videomode __initdata lb104v03_modes[] = { { .name = "640x480 @ 50", @@ -307,28 +316,10 @@ static int __init favr32_init(void) * Favr-32 uses 32-bit SDRAM interface. Reserve the SDRAM-specific * pins so that nobody messes with them. */ - at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */ - at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */ - at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */ - at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */ - at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */ - at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */ - at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */ - at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */ - at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */ - at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */ - at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */ - at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */ - at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */ - at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */ - at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */ - at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */ - at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */ + at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); at32_select_gpio(GPIO_PIN_PB(3), 0); /* IRQ from ADS7843 */ - at32_add_system_devices(); - at32_add_device_usart(0); set_hw_addr(at32_add_device_eth(0, ð_data[0])); @@ -339,7 +330,7 @@ static int __init favr32_init(void) at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel); at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); - at32_add_device_mci(0, NULL); + at32_add_device_mci(0, &mci0_data); at32_add_device_usba(0, NULL); at32_add_device_lcdc(0, &favr32_lcdc_data, fbmem_start, fbmem_size, 0); diff --git a/arch/avr32/boards/hammerhead/Kconfig b/arch/avr32/boards/hammerhead/Kconfig new file mode 100644 index 000000000000..fda2331f9789 --- /dev/null +++ b/arch/avr32/boards/hammerhead/Kconfig @@ -0,0 +1,43 @@ +# Hammerhead customization + +if BOARD_HAMMERHEAD + +config BOARD_HAMMERHEAD_USB + bool "Philips ISP116x-hcd USB support" + help + This enables USB support for Hammerheads internal ISP116x + controller from Philips. + + Choose 'Y' here if you want to have your board USB driven. + +config BOARD_HAMMERHEAD_LCD + bool "Atmel AT91/AT32 LCD support" + help + This enables LCD support for the Hammerhead board. You may + also add support for framebuffer devices (AT91/AT32 LCD Controller) + and framebuffer console support to get the most out of your LCD. + + Choose 'Y' here if you have ordered a Corona daugther board and + want to have support for your Hantronix HDA-351T-LV LCD. + +config BOARD_HAMMERHEAD_SND + bool "Atmel AC97 Sound support" + help + This enables Sound support for the Hammerhead board. You may + also go trough the ALSA settings to get it working. + + Choose 'Y' here if you have ordered a Corona daugther board and + want to make your board funky. + +config BOARD_HAMMERHEAD_FPGA + bool "Hammerhead FPGA Support" + default y + help + This adds support for the Cyclone III FPGA from Altera + found on Miromico's Hammerhead board. + + Choose 'Y' here if you want to have FPGA support enabled. + You will have to choose the "Hammerhead FPGA Device Support" in + Device Drivers->Misc to be able to use FPGA functionality. + +endif # BOARD_ATNGW100 diff --git a/arch/avr32/boards/hammerhead/Makefile b/arch/avr32/boards/hammerhead/Makefile new file mode 100644 index 000000000000..c740aa116755 --- /dev/null +++ b/arch/avr32/boards/hammerhead/Makefile @@ -0,0 +1 @@ +obj-y += setup.o flash.o diff --git a/arch/avr32/boards/hammerhead/flash.c b/arch/avr32/boards/hammerhead/flash.c new file mode 100644 index 000000000000..a98c6dd3a028 --- /dev/null +++ b/arch/avr32/boards/hammerhead/flash.c @@ -0,0 +1,377 @@ +/* + * Hammerhead board-specific flash initialization + * + * Copyright (C) 2008 Miromico AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/physmap.h> +#include <linux/usb/isp116x.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/delay.h> + +#include <mach/portmux.h> +#include <mach/at32ap700x.h> +#include <mach/smc.h> + +#include "../../mach-at32ap/clock.h" +#include "flash.h" + + +#define HAMMERHEAD_USB_PERIPH_GCLK0 0x40000000 +#define HAMMERHEAD_USB_PERIPH_CS2 0x02000000 +#define HAMMERHEAD_USB_PERIPH_EXTINT0 0x02000000 + +#define HAMMERHEAD_FPGA_PERIPH_MOSI 0x00000002 +#define HAMMERHEAD_FPGA_PERIPH_SCK 0x00000020 +#define HAMMERHEAD_FPGA_PERIPH_EXTINT3 0x10000000 + +static struct smc_timing flash_timing __initdata = { + .ncs_read_setup = 0, + .nrd_setup = 40, + .ncs_write_setup = 0, + .nwe_setup = 10, + + .ncs_read_pulse = 80, + .nrd_pulse = 40, + .ncs_write_pulse = 65, + .nwe_pulse = 55, + + .read_cycle = 120, + .write_cycle = 120, +}; + +static struct smc_config flash_config __initdata = { + .bus_width = 2, + .nrd_controlled = 1, + .nwe_controlled = 1, + .byte_write = 1, +}; + +static struct mtd_partition flash_parts[] = { + { + .name = "u-boot", + .offset = 0x00000000, + .size = 0x00020000, /* 128 KiB */ + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "root", + .offset = 0x00020000, + .size = 0x007d0000, + }, + { + .name = "env", + .offset = 0x007f0000, + .size = 0x00010000, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static struct physmap_flash_data flash_data = { + .width = 2, + .nr_parts = ARRAY_SIZE(flash_parts), + .parts = flash_parts, +}; + +static struct resource flash_resource = { + .start = 0x00000000, + .end = 0x007fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "physmap-flash", + .id = 0, + .resource = &flash_resource, + .num_resources = 1, + .dev = { .platform_data = &flash_data, }, +}; + +#ifdef CONFIG_BOARD_HAMMERHEAD_USB + +static struct smc_timing isp1160_timing __initdata = { + .ncs_read_setup = 75, + .nrd_setup = 75, + .ncs_write_setup = 75, + .nwe_setup = 75, + + + /* We use conservative timing settings, as the minimal settings aren't + stable. There may be room for tweaking. */ + .ncs_read_pulse = 75, /* min. 33ns */ + .nrd_pulse = 75, /* min. 33ns */ + .ncs_write_pulse = 75, /* min. 26ns */ + .nwe_pulse = 75, /* min. 26ns */ + + .read_cycle = 225, /* min. 143ns */ + .write_cycle = 225, /* min. 136ns */ +}; + +static struct smc_config isp1160_config __initdata = { + .bus_width = 2, + .nrd_controlled = 1, + .nwe_controlled = 1, + .byte_write = 0, +}; + +/* + * The platform delay function is only used to enforce the strange + * read to write delay. This can not be configured in the SMC. All other + * timings are controlled by the SMC (see timings obove) + * So in isp116x-hcd.c we should comment out USE_PLATFORM_DELAY + */ +void isp116x_delay(struct device *dev, int delay) +{ + if (delay > 150) + ndelay(delay - 150); +} + +static struct isp116x_platform_data isp1160_data = { + .sel15Kres = 1, /* use internal downstream resistors */ + .oc_enable = 0, /* external overcurrent detection */ + .int_edge_triggered = 0, /* interrupt is level triggered */ + .int_act_high = 0, /* interrupt is active low */ + .delay = isp116x_delay, /* platform delay function */ +}; + +static struct resource isp1160_resource[] = { + { + .start = 0x08000000, + .end = 0x08000001, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x08000002, + .end = 0x08000003, + .flags = IORESOURCE_MEM, + }, + { + .start = 64, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device isp1160_device = { + .name = "isp116x-hcd", + .id = 0, + .resource = isp1160_resource, + .num_resources = 3, + .dev = { + .platform_data = &isp1160_data, + }, +}; +#endif + +#ifdef CONFIG_BOARD_HAMMERHEAD_USB +static int __init hammerhead_usbh_init(void) +{ + struct clk *gclk; + struct clk *osc; + + int ret; + + /* setup smc for usbh */ + smc_set_timing(&isp1160_config, &isp1160_timing); + ret = smc_set_configuration(2, &isp1160_config); + + if (ret < 0) { + printk(KERN_ERR + "hammerhead: failed to set ISP1160 USBH timing\n"); + return ret; + } + + /* setup gclk0 to run from osc1 */ + gclk = clk_get(NULL, "gclk0"); + if (IS_ERR(gclk)) + goto err_gclk; + + osc = clk_get(NULL, "osc1"); + if (IS_ERR(osc)) + goto err_osc; + + if (clk_set_parent(gclk, osc)) { + pr_debug("hammerhead: failed to set osc1 for USBH clock\n"); + goto err_set_clk; + } + + /* set clock to 6MHz */ + clk_set_rate(gclk, 6000000); + + /* and enable */ + clk_enable(gclk); + + /* select GCLK0 peripheral function */ + at32_select_periph(GPIO_PIOA_BASE, HAMMERHEAD_USB_PERIPH_GCLK0, + GPIO_PERIPH_A, 0); + + /* enable CS2 peripheral function */ + at32_select_periph(GPIO_PIOE_BASE, HAMMERHEAD_USB_PERIPH_CS2, + GPIO_PERIPH_A, 0); + + /* H_WAKEUP must be driven low */ + at32_select_gpio(GPIO_PIN_PA(8), AT32_GPIOF_OUTPUT); + + /* Select EXTINT0 for PB25 */ + at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_USB_PERIPH_EXTINT0, + GPIO_PERIPH_A, 0); + + /* register usbh device driver */ + platform_device_register(&isp1160_device); + + err_set_clk: + clk_put(osc); + err_osc: + clk_put(gclk); + err_gclk: + return ret; +} +#endif + +#ifdef CONFIG_BOARD_HAMMERHEAD_FPGA +static struct smc_timing fpga_timing __initdata = { + .ncs_read_setup = 16, + .nrd_setup = 32, + .ncs_read_pulse = 48, + .nrd_pulse = 32, + .read_cycle = 64, + + .ncs_write_setup = 16, + .nwe_setup = 16, + .ncs_write_pulse = 32, + .nwe_pulse = 32, + .write_cycle = 64, +}; + +static struct smc_config fpga_config __initdata = { + .bus_width = 4, + .nrd_controlled = 1, + .nwe_controlled = 1, + .byte_write = 0, +}; + +static struct resource hh_fpga0_resource[] = { + { + .start = 0xffe00400, + .end = 0xffe00400 + 0x3ff, + .flags = IORESOURCE_MEM, + }, + { + .start = 4, + .end = 4, + .flags = IORESOURCE_IRQ, + }, + { + .start = 0x0c000000, + .end = 0x0c000100, + .flags = IORESOURCE_MEM, + }, + { + .start = 67, + .end = 67, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 hh_fpga0_dma_mask = DMA_32BIT_MASK; +static struct platform_device hh_fpga0_device = { + .name = "hh_fpga", + .id = 0, + .dev = { + .dma_mask = &hh_fpga0_dma_mask, + .coherent_dma_mask = DMA_32BIT_MASK, + }, + .resource = hh_fpga0_resource, + .num_resources = ARRAY_SIZE(hh_fpga0_resource), +}; + +static struct clk hh_fpga0_spi_clk = { + .name = "spi_clk", + .dev = &hh_fpga0_device.dev, + .mode = pba_clk_mode, + .get_rate = pba_clk_get_rate, + .index = 1, +}; + +struct platform_device *__init at32_add_device_hh_fpga(void) +{ + /* Select peripheral functionallity for SPI SCK and MOSI */ + at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_SCK, + GPIO_PERIPH_B, 0); + at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_MOSI, + GPIO_PERIPH_B, 0); + + /* reserve all other needed gpio + * We have on board pull ups, so there is no need + * to enable gpio pull ups */ + /* INIT_DONE (input) */ + at32_select_gpio(GPIO_PIN_PB(0), 0); + + /* nSTATUS (input) */ + at32_select_gpio(GPIO_PIN_PB(2), 0); + + /* nCONFIG (output, low) */ + at32_select_gpio(GPIO_PIN_PB(3), AT32_GPIOF_OUTPUT); + + /* CONF_DONE (input) */ + at32_select_gpio(GPIO_PIN_PB(4), 0); + + /* Select EXTINT3 for PB28 (Interrupt from FPGA) */ + at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_EXTINT3, + GPIO_PERIPH_A, 0); + + /* Get our parent clock */ + hh_fpga0_spi_clk.parent = clk_get(NULL, "pba"); + clk_put(hh_fpga0_spi_clk.parent); + + /* Register clock in at32 clock tree */ + at32_clk_register(&hh_fpga0_spi_clk); + + platform_device_register(&hh_fpga0_device); + return &hh_fpga0_device; +} +#endif + +/* This needs to be called after the SMC has been initialized */ +static int __init hammerhead_flash_init(void) +{ + int ret; + + smc_set_timing(&flash_config, &flash_timing); + ret = smc_set_configuration(0, &flash_config); + + if (ret < 0) { + printk(KERN_ERR "hammerhead: failed to set NOR flash timing\n"); + return ret; + } + + platform_device_register(&flash_device); + +#ifdef CONFIG_BOARD_HAMMERHEAD_USB + hammerhead_usbh_init(); +#endif + +#ifdef CONFIG_BOARD_HAMMERHEAD_FPGA + /* Setup SMC for FPGA interface */ + smc_set_timing(&fpga_config, &fpga_timing); + ret = smc_set_configuration(3, &fpga_config); +#endif + + + if (ret < 0) { + printk(KERN_ERR "hammerhead: failed to set FPGA timing\n"); + return ret; + } + + return 0; +} + +device_initcall(hammerhead_flash_init); diff --git a/arch/avr32/boards/hammerhead/flash.h b/arch/avr32/boards/hammerhead/flash.h new file mode 100644 index 000000000000..ea70c626587b --- /dev/null +++ b/arch/avr32/boards/hammerhead/flash.h @@ -0,0 +1,6 @@ +#ifndef __BOARDS_HAMMERHEAD_FLASH_H +#define __BOARDS_HAMMERHEAD_FLASH_H + +struct platform_device *at32_add_device_hh_fpga(void); + +#endif /* __BOARDS_HAMMERHEAD_FLASH_H */ diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c new file mode 100644 index 000000000000..4d2fe82b2029 --- /dev/null +++ b/arch/avr32/boards/hammerhead/setup.c @@ -0,0 +1,245 @@ +/* + * Board-specific setup code for the Miromico Hammerhead board + * + * Copyright (C) 2008 Miromico AG + * + * 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/atmel-mci.h> +#include <linux/clk.h> +#include <linux/fb.h> +#include <linux/etherdevice.h> +#include <linux/i2c.h> +#include <linux/i2c-gpio.h> +#include <linux/init.h> +#include <linux/linkage.h> +#include <linux/platform_device.h> +#include <linux/types.h> +#include <linux/spi/spi.h> + +#include <video/atmel_lcdc.h> + +#include <linux/io.h> +#include <asm/setup.h> + +#include <mach/at32ap700x.h> +#include <mach/board.h> +#include <mach/init.h> +#include <mach/portmux.h> + +#include "../../mach-at32ap/clock.h" +#include "flash.h" + +/* Oscillator frequencies. These are board-specific */ +unsigned long at32_board_osc_rates[3] = { + [0] = 32768, /* 32.768 kHz on RTC osc */ + [1] = 25000000, /* 25MHz on osc0 */ + [2] = 12000000, /* 12 MHz on osc1 */ +}; + +/* Initialized by bootloader-specific startup code. */ +struct tag *bootloader_tags __initdata; + +#ifdef CONFIG_BOARD_HAMMERHEAD_LCD +static struct fb_videomode __initdata hda350tlv_modes[] = { + { + .name = "320x240 @ 75", + .refresh = 75, + .xres = 320, + .yres = 240, + .pixclock = KHZ2PICOS(6891), + + .left_margin = 48, + .right_margin = 18, + .upper_margin = 18, + .lower_margin = 4, + .hsync_len = 20, + .vsync_len = 2, + + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +static struct fb_monspecs __initdata hammerhead_hda350t_monspecs = { + .manufacturer = "HAN", + .monitor = "HDA350T-LV", + .modedb = hda350tlv_modes, + .modedb_len = ARRAY_SIZE(hda350tlv_modes), + .hfmin = 14900, + .hfmax = 22350, + .vfmin = 60, + .vfmax = 90, + .dclkmax = 10000000, +}; + +struct atmel_lcdfb_info __initdata hammerhead_lcdc_data = { + .default_bpp = 24, + .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, + .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT + | ATMEL_LCDC_INVCLK + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE + | ATMEL_LCDC_MEMOR_BIG), + .default_monspecs = &hammerhead_hda350t_monspecs, + .guard_time = 2, +}; +#endif + +static struct mci_platform_data __initdata mci0_data = { + .slot[0] = { + .bus_width = 4, + .detect_pin = -ENODEV, + .wp_pin = -ENODEV, + }, +}; + +struct eth_addr { + u8 addr[6]; +}; + +static struct eth_addr __initdata hw_addr[1]; +static struct eth_platform_data __initdata eth_data[1]; + +/* + * The next two functions should go away as the boot loader is + * supposed to initialize the macb address registers with a valid + * ethernet address. But we need to keep it around for a while until + * we can be reasonably sure the boot loader does this. + * + * The phy_id is ignored as the driver will probe for it. + */ +static int __init parse_tag_ethernet(struct tag *tag) +{ + int i = tag->u.ethernet.mac_index; + + if (i < ARRAY_SIZE(hw_addr)) + memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, + sizeof(hw_addr[i].addr)); + + return 0; +} +__tagtable(ATAG_ETHERNET, parse_tag_ethernet); + +static void __init set_hw_addr(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + const u8 *addr; + void __iomem *regs; + struct clk *pclk; + + if (!res) + return; + + if (pdev->id >= ARRAY_SIZE(hw_addr)) + return; + + addr = hw_addr[pdev->id].addr; + + if (!is_valid_ether_addr(addr)) + return; + + /* + * Since this is board-specific code, we'll cheat and use the + * physical address directly as we happen to know that it's + * the same as the virtual address. + */ + regs = (void __iomem __force *)res->start; + pclk = clk_get(&pdev->dev, "pclk"); + + if (!pclk) + return; + + clk_enable(pclk); + + __raw_writel((addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | + addr[0], regs + 0x98); + __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); + + clk_disable(pclk); + clk_put(pclk); +} + +void __init setup_board(void) +{ + at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */ + at32_setup_serial_console(0); +} + +static struct i2c_gpio_platform_data i2c_gpio_data = { + .sda_pin = GPIO_PIN_PA(6), + .scl_pin = GPIO_PIN_PA(7), + .sda_is_open_drain = 1, + .scl_is_open_drain = 1, + .udelay = 2, /* close to 100 kHz */ +}; + +static struct platform_device i2c_gpio_device = { + .name = "i2c-gpio", + .id = 0, + .dev = { .platform_data = &i2c_gpio_data, }, +}; |