diff options
Diffstat (limited to 'arch/arm/mach-ixp4xx')
-rw-r--r-- | arch/arm/mach-ixp4xx/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/common-pci.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/include/mach/debug-macro.S | 2 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/include/mach/io.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/include/mach/memory.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/vulcan-pci.c | 73 | ||||
-rw-r--r-- | arch/arm/mach-ixp4xx/vulcan-setup.c | 246 |
8 files changed, 341 insertions, 9 deletions
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 9e5070da17a..6f991c5ae86 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -140,6 +140,14 @@ config MACH_FSG FSG-3 device. For more information on this platform, see http://www.nslu2-linux.org/wiki/FSG3/HomePage +config MACH_ARCOM_VULCAN + bool + prompt "Arcom/Eurotech Vulcan" + select PCI + help + Say 'Y' here if you want your kernel to support Arcom's + Vulcan board. + # # Certain registers and IRQs are only enabled if supporting IXP465 CPUs # diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index 47d1f60d23f..d807fc367dd 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile @@ -16,6 +16,7 @@ obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o obj-pci-$(CONFIG_MACH_FSG) += fsg-pci.o +obj-pci-$(CONFIG_MACH_ARCOM_VULCAN) += vulcan-pci.o obj-y += common.o @@ -31,6 +32,7 @@ obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o obj-$(CONFIG_MACH_FSG) += fsg-setup.o obj-$(CONFIG_MACH_GORAMO_MLR) += goramo_mlr.o +obj-$(CONFIG_MACH_ARCOM_VULCAN) += vulcan-setup.o obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index e3181534c7f..61cd4d64b98 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -348,7 +348,7 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) * This is really ugly and we need a better way of specifying * DMA-capable regions of memory. */ -void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size, +void __init ixp4xx_adjust_zones(unsigned long *zone_size, unsigned long *zhole_size) { unsigned int sz = SZ_64M >> PAGE_SHIFT; @@ -356,7 +356,7 @@ void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size, /* * Only adjust if > 64M on current system */ - if (node || (zone_size[0] <= sz)) + if (zone_size[0] <= sz) return; zone_size[1] = zone_size[0] - sz; @@ -382,7 +382,8 @@ void __init ixp4xx_pci_preinit(void) /* hook in our fault handler for PCI errors */ - hook_fault_code(16+6, abort_handler, SIGBUS, "imprecise external abort"); + hook_fault_code(16+6, abort_handler, SIGBUS, 0, + "imprecise external abort"); pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n"); diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S index 893873eb2a0..3fc66d6d00a 100644 --- a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S +++ b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S @@ -16,8 +16,10 @@ moveq \rx, #0xc8000000 movne \rx, #0xff000000 orrne \rx, \rx, #0x00b00000 +#ifdef __ARMEB__ add \rx,\rx,#3 @ Uart regs are at off set of 3 if @ byte writes used - Big Endian. +#endif .endm #define UART_SHIFT 2 diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h index 6ea7e2fb270..de274a1f19d 100644 --- a/arch/arm/mach-ixp4xx/include/mach/io.h +++ b/arch/arm/mach-ixp4xx/include/mach/io.h @@ -353,7 +353,7 @@ static inline unsigned int ioread8(const void __iomem *addr) return (unsigned int)inb(port & PIO_MASK); else #ifndef CONFIG_IXP4XX_INDIRECT_PCI - return (unsigned int)__raw_readb(port); + return (unsigned int)__raw_readb(addr); #else return (unsigned int)__indirect_readb(addr); #endif @@ -381,7 +381,7 @@ static inline unsigned int ioread16(const void __iomem *addr) return (unsigned int)inw(port & PIO_MASK); else #ifndef CONFIG_IXP4XX_INDIRECT_PCI - return le16_to_cpu(__raw_readw((u32)port)); + return le16_to_cpu((__force __le16)__raw_readw(addr)); #else return (unsigned int)__indirect_readw(addr); #endif @@ -440,7 +440,7 @@ static inline void iowrite8(u8 value, void __iomem *addr) outb(value, port & PIO_MASK); else #ifndef CONFIG_IXP4XX_INDIRECT_PCI - __raw_writeb(value, port); + __raw_writeb(value, addr); #else __indirect_writeb(value, addr); #endif diff --git a/arch/arm/mach-ixp4xx/include/mach/memory.h b/arch/arm/mach-ixp4xx/include/mach/memory.h index 98f5e5e2098..0136eaa2922 100644 --- a/arch/arm/mach-ixp4xx/include/mach/memory.h +++ b/arch/arm/mach-ixp4xx/include/mach/memory.h @@ -16,10 +16,10 @@ #if !defined(__ASSEMBLY__) && defined(CONFIG_PCI) -void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes); +void ixp4xx_adjust_zones(unsigned long *size, unsigned long *holes); -#define arch_adjust_zones(node, size, holes) \ - ixp4xx_adjust_zones(node, size, holes) +#define arch_adjust_zones(size, holes) \ + ixp4xx_adjust_zones(size, holes) #define ISA_DMA_THRESHOLD (SZ_64M - 1) #define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_64M) diff --git a/arch/arm/mach-ixp4xx/vulcan-pci.c b/arch/arm/mach-ixp4xx/vulcan-pci.c new file mode 100644 index 00000000000..f3111c6840e --- /dev/null +++ b/arch/arm/mach-ixp4xx/vulcan-pci.c @@ -0,0 +1,73 @@ +/* + * arch/arch/mach-ixp4xx/vulcan-pci.c + * + * Vulcan board-level PCI initialization + * + * Copyright (C) 2010 Marc Zyngier <maz@misterjones.org> + * + * based on ixdp425-pci.c: + * Copyright (C) 2002 Intel Corporation. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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/pci.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +/* PCI controller GPIO to IRQ pin mappings */ +#define INTA 2 +#define INTB 3 + +void __init vulcan_pci_preinit(void) +{ +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + /* + * Cardbus bridge wants way more than the SoC can actually offer, + * and leaves the whole PCI bus in a mess. Artificially limit it + * to 8MB per region. Of course indirect mode doesn't have this + * limitation... + */ + pci_cardbus_mem_size = SZ_8M; + pr_info("Vulcan PCI: limiting CardBus memory size to %dMB\n", + (int)(pci_cardbus_mem_size >> 20)); +#endif + set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW); + set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW); + ixp4xx_pci_preinit(); +} + +static int __init vulcan_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (slot == 1) + return IXP4XX_GPIO_IRQ(INTA); + + if (slot == 2) + return IXP4XX_GPIO_IRQ(INTB); + + return -1; +} + +struct hw_pci vulcan_pci __initdata = { + .nr_controllers = 1, + .preinit = vulcan_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, + .map_irq = vulcan_map_irq, +}; + +int __init vulcan_pci_init(void) +{ + if (machine_is_arcom_vulcan()) + pci_common_init(&vulcan_pci); + return 0; +} + +subsys_initcall(vulcan_pci_init); diff --git a/arch/arm/mach-ixp4xx/vulcan-setup.c b/arch/arm/mach-ixp4xx/vulcan-setup.c new file mode 100644 index 00000000000..465cc5cce68 --- /dev/null +++ b/arch/arm/mach-ixp4xx/vulcan-setup.c @@ -0,0 +1,246 @@ +/* + * arch/arm/mach-ixp4xx/vulcan-setup.c + * + * Arcom/Eurotech Vulcan board-setup + * + * Copyright (C) 2010 Marc Zyngier <maz@misterjones.org> + * + * based on fsg-setup.c: + * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au> + */ + +#include <linux/if_ether.h> +#include <linux/irq.h> +#include <linux/serial.h> +#include <linux/serial_8250.h> +#include <linux/io.h> +#include <linux/w1-gpio.h> +#include <linux/mtd/plat-ram.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> + +static struct flash_platform_data vulcan_flash_data = { + .map_name = "cfi_probe", + .width = 2, +}; + +static struct resource vulcan_flash_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device vulcan_flash = { + .name = "IXP4XX-Flash", + .id = 0, + .dev = { + .platform_data = &vulcan_flash_data, + }, + .resource = &vulcan_flash_resource, + .num_resources = 1, +}; + +static struct platdata_mtd_ram vulcan_sram_data = { + .mapname = "Vulcan SRAM", + .bankwidth = 1, +}; + +static struct resource vulcan_sram_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device vulcan_sram = { + .name = "mtd-ram", + .id = 0, + .dev = { + .platform_data = &vulcan_sram_data, + }, + .resource = &vulcan_sram_resource, + .num_resources = 1, +}; + +static struct resource vulcan_uart_resources[] = { + [0] = { + .start = IXP4XX_UART1_BASE_PHYS, + .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IXP4XX_UART2_BASE_PHYS, + .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + }, + [2] = { + .flags = IORESOURCE_MEM, + }, +}; + +static struct plat_serial8250_port vulcan_uart_data[] = { + [0] = { + .mapbase = IXP4XX_UART1_BASE_PHYS, + .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + [1] = { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + [2] = { + .irq = IXP4XX_GPIO_IRQ(4), + .irqflags = IRQF_TRIGGER_LOW, + .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .uartclk = 1843200, + }, + [3] = { + .irq = IXP4XX_GPIO_IRQ(4), + .irqflags = IRQF_TRIGGER_LOW, + .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .uartclk = 1843200, + }, + { } +}; + +static struct platform_device vulcan_uart = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = vulcan_uart_data, + }, + .resource = vulcan_uart_resources, + .num_resources = ARRAY_SIZE(vulcan_uart_resources), +}; + +static struct eth_plat_info vulcan_plat_eth[] = { + [0] = { + .phy = 0, + .rxq = 3, + .txreadyq = 20, + }, + [1] = { + .phy = 1, + .rxq = 4, + .txreadyq = 21, + }, +}; + +static struct platform_device vulcan_eth[] = { + [0] = { + .name = "ixp4xx_eth", + .id = IXP4XX_ETH_NPEB, + .dev = { + .platform_data = &vulcan_plat_eth[0], + }, + }, + [1] = { + .name = "ixp4xx_eth", + .id = IXP4XX_ETH_NPEC, + .dev = { + .platform_data = &vulcan_plat_eth[1], + }, + }, +}; + +static struct resource vulcan_max6369_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device vulcan_max6369 = { + .name = "max6369_wdt", + .id = -1, + .resource = &vulcan_max6369_resource, + .num_resources = 1, +}; + +static struct w1_gpio_platform_data vulcan_w1_gpio_pdata = { + .pin = 14, +}; + +static struct platform_device vulcan_w1_gpio = { + .name = "w1-gpio", + .id = 0, + .dev = { + .platform_data = &vulcan_w1_gpio_pdata, + }, +}; + +static struct platform_device *vulcan_devices[] __initdata = { + &vulcan_uart, + &vulcan_flash, + &vulcan_sram, + &vulcan_max6369, + &vulcan_eth[0], + &vulcan_eth[1], + &vulcan_w1_gpio, +}; + +static void __init vulcan_init(void) +{ + ixp4xx_sys_init(); + + /* Flash is spread over both CS0 and CS1 */ + vulcan_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + vulcan_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1; + *IXP4XX_EXP_CS0 = IXP4XX_EXP_BUS_CS_EN | + IXP4XX_EXP_BUS_STROBE_T(3) | + IXP4XX_EXP_BUS_SIZE(0xF) | + IXP4XX_EXP_BUS_BYTE_RD16 | + IXP4XX_EXP_BUS_WR_EN; + *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; + + /* SRAM on CS2, (256kB, 8bit, writable) */ + vulcan_sram_resource.start = IXP4XX_EXP_BUS_BASE(2); + vulcan_sram_resource.end = IXP4XX_EXP_BUS_BASE(2) + SZ_256K - 1; + *IXP4XX_EXP_CS2 = IXP4XX_EXP_BUS_CS_EN | + IXP4XX_EXP_BUS_STROBE_T(1) | + IXP4XX_EXP_BUS_HOLD_T(2) | + IXP4XX_EXP_BUS_SIZE(9) | + IXP4XX_EXP_BUS_SPLT_EN | + IXP4XX_EXP_BUS_WR_EN | + IXP4XX_EXP_BUS_BYTE_EN; + + /* XR16L2551 on CS3 (Moto style, 512 bytes, 8bits, writable) */ + vulcan_uart_resources[2].start = IXP4XX_EXP_BUS_BASE(3); + vulcan_uart_resources[2].end = IXP4XX_EXP_BUS_BASE(3) + 16 - 1; + vulcan_uart_data[2].mapbase = vulcan_uart_resources[2].start; + vulcan_uart_data[3].mapbase = vulcan_uart_data[2].mapbase + 8; + *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN | + IXP4XX_EXP_BUS_STROBE_T(3) | + IXP4XX_EXP_BUS_CYCLES(IXP4XX_EXP_BUS_CYCLES_MOTOROLA)| + IXP4XX_EXP_BUS_WR_EN | + IXP4XX_EXP_BUS_BYTE_EN; + + /* GPIOS on CS4 (512 bytes, 8bits, writable) */ + *IXP4XX_EXP_CS4 = IXP4XX_EXP_BUS_CS_EN | + IXP4XX_EXP_BUS_WR_EN | + IXP4XX_EXP_BUS_BYTE_EN; + + /* max6369 on CS5 (512 bytes, 8bits, writable) */ + vulcan_max6369_resource.start = IXP4XX_EXP_BUS_BASE(5); + vulcan_max6369_resource.end = IXP4XX_EXP_BUS_BASE(5); + *IXP4XX_EXP_CS5 = IXP4XX_EXP_BUS_CS_EN | + IXP4XX_EXP_BUS_WR_EN | + IXP4XX_EXP_BUS_BYTE_EN; + + platform_add_devices(vulcan_devices, ARRAY_SIZE(vulcan_devices)); +} + +MACHINE_START(ARCOM_VULCAN, "Arcom/Eurotech Vulcan") + /* Maintainer: Marc Zyngier <maz@misterjones.org> */ + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixp4xx_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, + .boot_params = 0x0100, + .init_machine = vulcan_init, +MACHINE_END |