diff options
Diffstat (limited to 'arch/arm/mach-iop33x')
-rw-r--r-- | arch/arm/mach-iop33x/Kconfig | 21 | ||||
-rw-r--r-- | arch/arm/mach-iop33x/Makefile | 11 | ||||
-rw-r--r-- | arch/arm/mach-iop33x/Makefile.boot | 3 | ||||
-rw-r--r-- | arch/arm/mach-iop33x/iq80331.c | 148 | ||||
-rw-r--r-- | arch/arm/mach-iop33x/iq80332.c | 148 | ||||
-rw-r--r-- | arch/arm/mach-iop33x/irq.c | 127 | ||||
-rw-r--r-- | arch/arm/mach-iop33x/uart.c | 105 |
7 files changed, 563 insertions, 0 deletions
diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig new file mode 100644 index 00000000000..9aa016bb18f --- /dev/null +++ b/arch/arm/mach-iop33x/Kconfig @@ -0,0 +1,21 @@ +if ARCH_IOP33X + +menu "IOP33x Implementation Options" + +comment "IOP33x Platform Types" + +config ARCH_IQ80331 + bool "Enable support for IQ80331" + help + Say Y here if you want to run your kernel on the Intel IQ80331 + evaluation kit for the IOP331 chipset. + +config MACH_IQ80332 + bool "Enable support for IQ80332" + help + Say Y here if you want to run your kernel on the Intel IQ80332 + evaluation kit for the IOP332 chipset. + +endmenu + +endif diff --git a/arch/arm/mach-iop33x/Makefile b/arch/arm/mach-iop33x/Makefile new file mode 100644 index 00000000000..90081d8c9d1 --- /dev/null +++ b/arch/arm/mach-iop33x/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +obj-y := irq.o uart.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_IQ80331) += iq80331.o +obj-$(CONFIG_MACH_IQ80332) += iq80332.o diff --git a/arch/arm/mach-iop33x/Makefile.boot b/arch/arm/mach-iop33x/Makefile.boot new file mode 100644 index 00000000000..67039c3e0c4 --- /dev/null +++ b/arch/arm/mach-iop33x/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c new file mode 100644 index 00000000000..97a7b748826 --- /dev/null +++ b/arch/arm/mach-iop33x/iq80331.c @@ -0,0 +1,148 @@ +/* + * arch/arm/mach-iop33x/iq80331.c + * + * Board support code for the Intel IQ80331 platform. + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2003 Intel Corp. + * + * 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. + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/pci.h> +#include <asm/mach/time.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> + +/* + * IQ80331 timer tick configuration. + */ +static void __init iq80331_timer_init(void) +{ + /* D-Step parts run at a higher internal bus frequency */ + if (*IOP3XX_ATURID >= 0xa) + iop3xx_init_time(333000000); + else + iop3xx_init_time(266000000); +} + +static struct sys_timer iq80331_timer = { + .init = iq80331_timer_init, + .offset = iop3xx_gettimeoffset, +}; + + +/* + * IQ80331 PCI. + */ +static inline int __init +iq80331_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (slot == 1 && pin == 1) { + /* PCI-X Slot INTA */ + irq = IRQ_IOP33X_XINT1; + } else if (slot == 1 && pin == 2) { + /* PCI-X Slot INTB */ + irq = IRQ_IOP33X_XINT2; + } else if (slot == 1 && pin == 3) { + /* PCI-X Slot INTC */ + irq = IRQ_IOP33X_XINT3; + } else if (slot == 1 && pin == 4) { + /* PCI-X Slot INTD */ + irq = IRQ_IOP33X_XINT0; + } else if (slot == 2) { + /* GigE */ + irq = IRQ_IOP33X_XINT2; + } else { + printk(KERN_ERR "iq80331_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +static struct hw_pci iq80331_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = iq80331_pci_map_irq, +}; + +static int __init iq80331_pci_init(void) +{ + if (machine_is_iq80331()) + pci_common_init(&iq80331_pci); + + return 0; +} + +subsys_initcall(iq80331_pci_init); + + +/* + * IQ80331 machine initialisation. + */ +static struct physmap_flash_data iq80331_flash_data = { + .width = 1, +}; + +static struct resource iq80331_flash_resource = { + .start = 0xc0000000, + .end = 0xc07fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq80331_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &iq80331_flash_data, + }, + .num_resources = 1, + .resource = &iq80331_flash_resource, +}; + +static void __init iq80331_init_machine(void) +{ + platform_device_register(&iop3xx_i2c0_device); + platform_device_register(&iop3xx_i2c1_device); + platform_device_register(&iop33x_uart0_device); + platform_device_register(&iop33x_uart1_device); + platform_device_register(&iq80331_flash_device); +} + +MACHINE_START(IQ80331, "Intel IQ80331") + /* Maintainer: Intel Corp. */ + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = iop3xx_map_io, + .init_irq = iop33x_init_irq, + .timer = &iq80331_timer, + .init_machine = iq80331_init_machine, +MACHINE_END diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c new file mode 100644 index 00000000000..9887bfc1c07 --- /dev/null +++ b/arch/arm/mach-iop33x/iq80332.c @@ -0,0 +1,148 @@ +/* + * arch/arm/mach-iop33x/iq80332.c + * + * Board support code for the Intel IQ80332 platform. + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2004 Intel Corp. + * + * 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. + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/pci.h> +#include <asm/mach/time.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> + +/* + * IQ80332 timer tick configuration. + */ +static void __init iq80332_timer_init(void) +{ + /* D-Step parts and the iop333 run at a higher internal bus frequency */ + if (*IOP3XX_ATURID >= 0xa || *IOP3XX_ATUDID == 0x374) + iop3xx_init_time(333000000); + else + iop3xx_init_time(266000000); +} + +static struct sys_timer iq80332_timer = { + .init = iq80332_timer_init, + .offset = iop3xx_gettimeoffset, +}; + + +/* + * IQ80332 PCI. + */ +static inline int __init +iq80332_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (slot == 4 && pin == 1) { + /* PCI-X Slot INTA */ + irq = IRQ_IOP33X_XINT0; + } else if (slot == 4 && pin == 2) { + /* PCI-X Slot INTB */ + irq = IRQ_IOP33X_XINT1; + } else if (slot == 4 && pin == 3) { + /* PCI-X Slot INTC */ + irq = IRQ_IOP33X_XINT2; + } else if (slot == 4 && pin == 4) { + /* PCI-X Slot INTD */ + irq = IRQ_IOP33X_XINT3; + } else if (slot == 6) { + /* GigE */ + irq = IRQ_IOP33X_XINT2; + } else { + printk(KERN_ERR "iq80332_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +static struct hw_pci iq80332_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = iq80332_pci_map_irq, +}; + +static int __init iq80332_pci_init(void) +{ + if (machine_is_iq80332()) + pci_common_init(&iq80332_pci); + + return 0; +} + +subsys_initcall(iq80332_pci_init); + + +/* + * IQ80332 machine initialisation. + */ +static struct physmap_flash_data iq80332_flash_data = { + .width = 1, +}; + +static struct resource iq80332_flash_resource = { + .start = 0xc0000000, + .end = 0xc07fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq80332_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &iq80332_flash_data, + }, + .num_resources = 1, + .resource = &iq80332_flash_resource, +}; + +static void __init iq80332_init_machine(void) +{ + platform_device_register(&iop3xx_i2c0_device); + platform_device_register(&iop3xx_i2c1_device); + platform_device_register(&iop33x_uart0_device); + platform_device_register(&iop33x_uart1_device); + platform_device_register(&iq80332_flash_device); +} + +MACHINE_START(IQ80332, "Intel IQ80332") + /* Maintainer: Intel Corp. */ + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = iop3xx_map_io, + .init_irq = iop33x_init_irq, + .timer = &iq80332_timer, + .init_machine = iq80332_init_machine, +MACHINE_END diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c new file mode 100644 index 00000000000..63304b3d0d7 --- /dev/null +++ b/arch/arm/mach-iop33x/irq.c @@ -0,0 +1,127 @@ +/* + * arch/arm/mach-iop33x/irq.c + * + * Generic IOP331 IRQ handling functionality + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2003 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <asm/mach/irq.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +static u32 iop33x_mask0; +static u32 iop33x_mask1; + +static inline void intctl0_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intctl1_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intstr0_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intstr1_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intbase_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intsize_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static void +iop33x_irq_mask1 (unsigned int irq) +{ + iop33x_mask0 &= ~(1 << irq); + intctl0_write(iop33x_mask0); +} + +static void +iop33x_irq_mask2 (unsigned int irq) +{ + iop33x_mask1 &= ~(1 << (irq - 32)); + intctl1_write(iop33x_mask1); +} + +static void +iop33x_irq_unmask1(unsigned int irq) +{ + iop33x_mask0 |= 1 << irq; + intctl0_write(iop33x_mask0); +} + +static void +iop33x_irq_unmask2(unsigned int irq) +{ + iop33x_mask1 |= (1 << (irq - 32)); + intctl1_write(iop33x_mask1); +} + +struct irq_chip iop33x_irqchip1 = { + .name = "IOP33x-1", + .ack = iop33x_irq_mask1, + .mask = iop33x_irq_mask1, + .unmask = iop33x_irq_unmask1, +}; + +struct irq_chip iop33x_irqchip2 = { + .name = "IOP33x-2", + .ack = iop33x_irq_mask2, + .mask = iop33x_irq_mask2, + .unmask = iop33x_irq_unmask2, +}; + +void __init iop33x_init_irq(void) +{ + int i; + + intctl0_write(0); + intctl1_write(0); + intstr0_write(0); + intstr1_write(0); + intbase_write(0); + intsize_write(1); + if (machine_is_iq80331()) + *IOP3XX_PCIIRSR = 0x0f; + + for (i = 0; i < NR_IRQS; i++) { + set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } +} diff --git a/arch/arm/mach-iop33x/uart.c b/arch/arm/mach-iop33x/uart.c new file mode 100644 index 00000000000..ac297cd0276 --- /dev/null +++ b/arch/arm/mach-iop33x/uart.c @@ -0,0 +1,105 @@ +/* + * arch/arm/mach-iop33x/uart.c + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2004 Intel Corporation. + * + * 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/mm.h> +#include <linux/init.h> +#include <linux/major.h> +#include <linux/fs.h> +#include <linux/platform_device.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/mach/map.h> +#include <asm/setup.h> +#include <asm/system.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/hardware/iop3xx.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#define IOP33X_UART_XTAL 33334000 + +static struct plat_serial8250_port iop33x_uart0_data[] = { + { + .membase = (char *)IOP33X_UART0_VIRT, + .mapbase = IOP33X_UART0_PHYS, + .irq = IRQ_IOP33X_UART0, + .uartclk = IOP33X_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct resource iop33x_uart0_resources[] = { + [0] = { + .start = IOP33X_UART0_PHYS, + .end = IOP33X_UART0_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP33X_UART0, + .end = IRQ_IOP33X_UART0, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device iop33x_uart0_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = iop33x_uart0_data, + }, + .num_resources = 2, + .resource = iop33x_uart0_resources, +}; + + +static struct resource iop33x_uart1_resources[] = { + [0] = { + .start = IOP33X_UART1_PHYS, + .end = IOP33X_UART1_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP33X_UART1, + .end = IRQ_IOP33X_UART1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct plat_serial8250_port iop33x_uart1_data[] = { + { + .membase = (char *)IOP33X_UART1_VIRT, + .mapbase = IOP33X_UART1_PHYS, + .irq = IRQ_IOP33X_UART1, + .uartclk = IOP33X_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +struct platform_device iop33x_uart1_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM1, + .dev = { + .platform_data = iop33x_uart1_data, + }, + .num_resources = 2, + .resource = iop33x_uart1_resources, +}; |