add idl4k kernel firmware version 1.13.0.105

This commit is contained in:
Jaroslav Kysela
2015-03-26 17:22:37 +01:00
parent 5194d2792e
commit e9070cdc77
31064 changed files with 12769984 additions and 0 deletions

View File

@@ -0,0 +1,218 @@
if ARCH_IXP4XX
config ARCH_SUPPORTS_BIG_ENDIAN
bool
default y
menu "Intel IXP4xx Implementation Options"
comment "IXP4xx Platforms"
config MACH_NSLU2
bool
prompt "Linksys NSLU2"
select PCI
help
Say 'Y' here if you want your kernel to support Linksys's
NSLU2 NAS device. For more information on this platform,
see http://www.nslu2-linux.org
config MACH_AVILA
bool "Avila"
select PCI
help
Say 'Y' here if you want your kernel to support the Gateworks
Avila Network Platform. For more information on this platform,
see <file:Documentation/arm/IXP4xx>.
config MACH_LOFT
bool "Loft"
depends on MACH_AVILA
help
Say 'Y' here if you want your kernel to support the Giant
Shoulder Inc Loft board (a minor variation on the standard
Gateworks Avila Network Platform).
config ARCH_ADI_COYOTE
bool "Coyote"
select PCI
help
Say 'Y' here if you want your kernel to support the ADI
Engineering Coyote Gateway Reference Platform. For more
information on this platform, see <file:Documentation/arm/IXP4xx>.
config MACH_GATEWAY7001
bool "Gateway 7001"
select PCI
help
Say 'Y' here if you want your kernel to support Gateway's
7001 Access Point. For more information on this platform,
see http://openwrt.org
config MACH_WG302V2
bool "Netgear WG302 v2 / WAG302 v2"
select PCI
help
Say 'Y' here if you want your kernel to support Netgear's
WG302 v2 or WAG302 v2 Access Points. For more information
on this platform, see http://openwrt.org
config ARCH_IXDP425
bool "IXDP425"
help
Say 'Y' here if you want your kernel to support Intel's
IXDP425 Development Platform (Also known as Richfield).
For more information on this platform, see <file:Documentation/arm/IXP4xx>.
config MACH_IXDPG425
bool "IXDPG425"
help
Say 'Y' here if you want your kernel to support Intel's
IXDPG425 Development Platform (Also known as Montajade).
For more information on this platform, see <file:Documentation/arm/IXP4xx>.
config MACH_IXDP465
bool "IXDP465"
help
Say 'Y' here if you want your kernel to support Intel's
IXDP465 Development Platform (Also known as BMP).
For more information on this platform, see <file:Documentation/arm/IXP4xx>.
config MACH_GORAMO_MLR
bool "GORAMO Multi Link Router"
help
Say 'Y' here if you want your kernel to support GORAMO
MultiLink router.
config MACH_KIXRP435
bool "KIXRP435"
help
Say 'Y' here if you want your kernel to support Intel's
KIXRP435 Reference Platform.
For more information on this platform, see <file:Documentation/arm/IXP4xx>.
#
# IXCDP1100 is the exact same HW as IXDP425, but with a different machine
# number from the bootloader due to marketing monkeys, so we just enable it
# by default if IXDP425 is enabled.
#
config ARCH_IXCDP1100
bool
depends on ARCH_IXDP425
default y
config ARCH_PRPMC1100
bool "PrPMC1100"
help
Say 'Y' here if you want your kernel to support the Motorola
PrPCM1100 Processor Mezanine Module. For more information on
this platform, see <file:Documentation/arm/IXP4xx>.
config MACH_NAS100D
bool
prompt "NAS100D"
select PCI
help
Say 'Y' here if you want your kernel to support Iomega's
NAS 100d device. For more information on this platform,
see http://www.nslu2-linux.org/wiki/NAS100d/HomePage
config MACH_DSMG600
bool
prompt "D-Link DSM-G600 RevA"
select PCI
help
Say 'Y' here if you want your kernel to support D-Link's
DSM-G600 RevA device. For more information on this platform,
see http://www.nslu2-linux.org/wiki/DSMG600/HomePage
config ARCH_IXDP4XX
bool
depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435
default y
config MACH_FSG
bool
prompt "Freecom FSG-3"
select PCI
help
Say 'Y' here if you want your kernel to support Freecom's
FSG-3 device. For more information on this platform,
see http://www.nslu2-linux.org/wiki/FSG3/HomePage
#
# Certain registers and IRQs are only enabled if supporting IXP465 CPUs
#
config CPU_IXP46X
bool
depends on MACH_IXDP465
default y
config CPU_IXP43X
bool
depends on MACH_KIXRP435
default y
config MACH_GTWX5715
bool "Gemtek WX5715 (Linksys WRV54G)"
depends on ARCH_IXP4XX
select PCI
help
This board is currently inside the Linksys WRV54G Gateways.
IXP425 - 266mhz
32mb SDRAM
8mb Flash
miniPCI slot 0 does not have a card connector soldered to the board
miniPCI slot 1 has an ISL3880 802.11g card (Prism54)
npe0 is connected to a Kendin KS8995M Switch (4 ports)
npe1 is the "wan" port
"Console" UART is available on J11 as console
"High Speed" UART is n/c (as far as I can tell)
20 Pin ARM/Xscale JTAG interface on J2
comment "IXP4xx Options"
config IXP4XX_INDIRECT_PCI
bool "Use indirect PCI memory access"
depends on PCI
help
IXP4xx provides two methods of accessing PCI memory space:
1) A direct mapped window from 0x48000000 to 0x4bffffff (64MB).
To access PCI via this space, we simply ioremap() the BAR
into the kernel and we can use the standard read[bwl]/write[bwl]
macros. This is the preferred method due to speed but it
limits the system to just 64MB of PCI memory. This can be
problematic if using video cards and other memory-heavy devices.
2) If > 64MB of memory space is required, the IXP4xx can be
configured to use indirect registers to access PCI This allows
for up to 128MB (0x48000000 to 0x4fffffff) of memory on the bus.
The disadvantage of this is that every PCI access requires
three local register accesses plus a spinlock, but in some
cases the performance hit is acceptable. In addition, you cannot
mmap() PCI devices in this case due to the indirect nature
of the PCI window.
By default, the direct method is used. Choose this option if you
need to use the indirect method instead. If you don't know
what you need, leave this option unselected.
config IXP4XX_QMGR
tristate "IXP4xx Queue Manager support"
help
This driver supports IXP4xx built-in hardware queue manager
and is automatically selected by Ethernet and HSS drivers.
config IXP4XX_NPE
tristate "IXP4xx Network Processor Engine support"
select HOTPLUG
select FW_LOADER
help
This driver supports IXP4xx built-in network coprocessors
and is automatically selected by Ethernet and HSS drivers.
endmenu
endif

View File

@@ -0,0 +1,37 @@
#
# Makefile for the linux kernel.
#
obj-pci-y :=
obj-pci-n :=
obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o
obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o
obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o
obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o
obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o
obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
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-y += common.o
obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o
obj-$(CONFIG_MACH_AVILA) += avila-setup.o
obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o
obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o
obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o
obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o
obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o
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_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o
obj-$(CONFIG_IXP4XX_NPE) += ixp4xx_npe.o

View File

@@ -0,0 +1,3 @@
zreladdr-y := 0x00008000
params_phys-y := 0x00000100

View File

@@ -0,0 +1,78 @@
/*
* arch/arm/mach-ixp4xx/avila-pci.c
*
* Gateworks Avila board-level PCI initialization
*
* Author: Michael-Luke Jones <mlj28@cam.ac.uk>
*
* Based on ixdp-pci.c
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* 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/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/mach/pci.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
void __init avila_pci_preinit(void)
{
set_irq_type(IRQ_AVILA_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_AVILA_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_AVILA_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_AVILA_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init avila_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static int pci_irq_table[AVILA_PCI_IRQ_LINES] = {
IRQ_AVILA_PCI_INTA,
IRQ_AVILA_PCI_INTB,
IRQ_AVILA_PCI_INTC,
IRQ_AVILA_PCI_INTD
};
int irq = -1;
if (slot >= 1 &&
slot <= (machine_is_loft() ? LOFT_PCI_MAX_DEV : AVILA_PCI_MAX_DEV) &&
pin >= 1 && pin <= AVILA_PCI_IRQ_LINES) {
irq = pci_irq_table[(slot + pin - 2) % 4];
}
return irq;
}
struct hw_pci avila_pci __initdata = {
.nr_controllers = 1,
.preinit = avila_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = avila_map_irq,
};
int __init avila_pci_init(void)
{
if (machine_is_avila() || machine_is_loft())
pci_common_init(&avila_pci);
return 0;
}
subsys_initcall(avila_pci_init);

View File

@@ -0,0 +1,192 @@
/*
* arch/arm/mach-ixp4xx/avila-setup.c
*
* Gateworks Avila board-setup
*
* Author: Michael-Luke Jones <mlj28@cam.ac.uk>
*
* Based on ixdp-setup.c
* Copyright (C) 2003-2005 MontaVista Software, Inc.
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>
#include <linux/i2c-gpio.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
static struct flash_platform_data avila_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource avila_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device avila_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = {
.platform_data = &avila_flash_data,
},
.num_resources = 1,
.resource = &avila_flash_resource,
};
static struct i2c_gpio_platform_data avila_i2c_gpio_data = {
.sda_pin = AVILA_SDA_PIN,
.scl_pin = AVILA_SCL_PIN,
};
static struct platform_device avila_i2c_gpio = {
.name = "i2c-gpio",
.id = 0,
.dev = {
.platform_data = &avila_i2c_gpio_data,
},
};
static struct resource avila_uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM
}
};
static struct plat_serial8250_port avila_uart_data[] = {
{
.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,
},
{
.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,
},
{ },
};
static struct platform_device avila_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = avila_uart_data,
.num_resources = 2,
.resource = avila_uart_resources
};
static struct resource avila_pata_resources[] = {
{
.flags = IORESOURCE_MEM
},
{
.flags = IORESOURCE_MEM,
},
{
.name = "intrq",
.start = IRQ_IXP4XX_GPIO12,
.end = IRQ_IXP4XX_GPIO12,
.flags = IORESOURCE_IRQ,
},
};
static struct ixp4xx_pata_data avila_pata_data = {
.cs0_bits = 0xbfff0043,
.cs1_bits = 0xbfff0043,
};
static struct platform_device avila_pata = {
.name = "pata_ixp4xx_cf",
.id = 0,
.dev.platform_data = &avila_pata_data,
.num_resources = ARRAY_SIZE(avila_pata_resources),
.resource = avila_pata_resources,
};
static struct platform_device *avila_devices[] __initdata = {
&avila_i2c_gpio,
&avila_flash,
&avila_uart
};
static void __init avila_init(void)
{
ixp4xx_sys_init();
avila_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
avila_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
platform_add_devices(avila_devices, ARRAY_SIZE(avila_devices));
avila_pata_resources[0].start = IXP4XX_EXP_BUS_BASE(1);
avila_pata_resources[0].end = IXP4XX_EXP_BUS_END(1);
avila_pata_resources[1].start = IXP4XX_EXP_BUS_BASE(2);
avila_pata_resources[1].end = IXP4XX_EXP_BUS_END(2);
avila_pata_data.cs0_cfg = IXP4XX_EXP_CS1;
avila_pata_data.cs1_cfg = IXP4XX_EXP_CS2;
platform_device_register(&avila_pata);
}
MACHINE_START(AVILA, "Gateworks Avila Network Platform")
/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
.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 = avila_init,
MACHINE_END
/*
* Loft is functionally equivalent to Avila except that it has a
* different number for the maximum PCI devices. The MACHINE
* structure below is identical to Avila except for the comment.
*/
#ifdef CONFIG_MACH_LOFT
MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")
/* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */
.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 = avila_init,
MACHINE_END
#endif

View File

@@ -0,0 +1,537 @@
/*
* arch/arm/mach-ixp4xx/common-pci.c
*
* IXP4XX PCI routines for all platforms
*
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003 Greg Ungerer <gerg@snapgear.com>
* 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/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/io.h>
#include <asm/dma-mapping.h>
#include <asm/cputype.h>
#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/system.h>
#include <asm/mach/pci.h>
#include <mach/hardware.h>
/*
* IXP4xx PCI read function is dependent on whether we are
* running A0 or B0 (AppleGate) silicon.
*/
int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
/*
* Base address for PCI regsiter region
*/
unsigned long ixp4xx_pci_reg_base = 0;
/*
* PCI cfg an I/O routines are done by programming a
* command/byte enable register, and then read/writing
* the data from a data regsiter. We need to ensure
* these transactions are atomic or we will end up
* with corrupt data on the bus or in a driver.
*/
static DEFINE_SPINLOCK(ixp4xx_pci_lock);
/*
* Read from PCI config space
*/
static void crp_read(u32 ad_cbe, u32 *data)
{
unsigned long flags;
spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_CRP_AD_CBE = ad_cbe;
*data = *PCI_CRP_RDATA;
spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
}
/*
* Write to PCI config space
*/
static void crp_write(u32 ad_cbe, u32 data)
{
unsigned long flags;
spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
*PCI_CRP_WDATA = data;
spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
}
static inline int check_master_abort(void)
{
/* check Master Abort bit after access */
unsigned long isr = *PCI_ISR;
if (isr & PCI_ISR_PFE) {
/* make sure the Master Abort bit is reset */
*PCI_ISR = PCI_ISR_PFE;
pr_debug("%s failed\n", __func__);
return 1;
}
return 0;
}
int ixp4xx_pci_read_errata(u32 addr, u32 cmd, u32* data)
{
unsigned long flags;
int retval = 0;
int i;
spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_NP_AD = addr;
/*
* PCI workaround - only works if NP PCI space reads have
* no side effects!!! Read 8 times. last one will be good.
*/
for (i = 0; i < 8; i++) {
*PCI_NP_CBE = cmd;
*data = *PCI_NP_RDATA;
*data = *PCI_NP_RDATA;
}
if(check_master_abort())
retval = 1;
spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
return retval;
}
int ixp4xx_pci_read_no_errata(u32 addr, u32 cmd, u32* data)
{
unsigned long flags;
int retval = 0;
spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_NP_AD = addr;
/* set up and execute the read */
*PCI_NP_CBE = cmd;
/* the result of the read is now in NP_RDATA */
*data = *PCI_NP_RDATA;
if(check_master_abort())
retval = 1;
spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
return retval;
}
int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data)
{
unsigned long flags;
int retval = 0;
spin_lock_irqsave(&ixp4xx_pci_lock, flags);
*PCI_NP_AD = addr;
/* set up the write */
*PCI_NP_CBE = cmd;
/* execute the write by writing to NP_WDATA */
*PCI_NP_WDATA = data;
if(check_master_abort())
retval = 1;
spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
return retval;
}
static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where)
{
u32 addr;
if (!bus_num) {
/* type 0 */
addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) |
(where & ~3);
} else {
/* type 1 */
addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) |
((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
}
return addr;
}
/*
* Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
* 0 and 3 are not valid indexes...
*/
static u32 bytemask[] = {
/*0*/ 0,
/*1*/ 0xff,
/*2*/ 0xffff,
/*3*/ 0,
/*4*/ 0xffffffff,
};
static u32 local_byte_lane_enable_bits(u32 n, int size)
{
if (size == 1)
return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL;
if (size == 2)
return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL;
if (size == 4)
return 0;
return 0xffffffff;
}
static int local_read_config(int where, int size, u32 *value)
{
u32 n, data;
pr_debug("local_read_config from %d size %d\n", where, size);
n = where % 4;
crp_read(where & ~3, &data);
*value = (data >> (8*n)) & bytemask[size];
pr_debug("local_read_config read %#x\n", *value);
return PCIBIOS_SUCCESSFUL;
}
static int local_write_config(int where, int size, u32 value)
{
u32 n, byte_enables, data;
pr_debug("local_write_config %#x to %d size %d\n", value, where, size);
n = where % 4;
byte_enables = local_byte_lane_enable_bits(n, size);
if (byte_enables == 0xffffffff)
return PCIBIOS_BAD_REGISTER_NUMBER;
data = value << (8*n);
crp_write((where & ~3) | byte_enables, data);
return PCIBIOS_SUCCESSFUL;
}
static u32 byte_lane_enable_bits(u32 n, int size)
{
if (size == 1)
return (0xf & ~BIT(n)) << 4;
if (size == 2)
return (0xf & ~(BIT(n) | BIT(n+1))) << 4;
if (size == 4)
return 0;
return 0xffffffff;
}
static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
u32 n, byte_enables, addr, data;
u8 bus_num = bus->number;
pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size,
bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
*value = 0xffffffff;
n = where % 4;
byte_enables = byte_lane_enable_bits(n, size);
if (byte_enables == 0xffffffff)
return PCIBIOS_BAD_REGISTER_NUMBER;
addr = ixp4xx_config_addr(bus_num, devfn, where);
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = (data >> (8*n)) & bytemask[size];
pr_debug("read_config_byte read %#x\n", *value);
return PCIBIOS_SUCCESSFUL;
}
static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
u32 n, byte_enables, addr, data;
u8 bus_num = bus->number;
pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where,
size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
n = where % 4;
byte_enables = byte_lane_enable_bits(n, size);
if (byte_enables == 0xffffffff)
return PCIBIOS_BAD_REGISTER_NUMBER;
addr = ixp4xx_config_addr(bus_num, devfn, where);
data = value << (8*n);
if (ixp4xx_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
return PCIBIOS_DEVICE_NOT_FOUND;
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops ixp4xx_ops = {
.read = ixp4xx_pci_read_config,
.write = ixp4xx_pci_write_config,
};
/*
* PCI abort handler
*/
static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
u32 isr, status;
isr = *PCI_ISR;
local_read_config(PCI_STATUS, 2, &status);
pr_debug("PCI: abort_handler addr = %#lx, isr = %#x, "
"status = %#x\n", addr, isr, status);
/* make sure the Master Abort bit is reset */
*PCI_ISR = PCI_ISR_PFE;
status |= PCI_STATUS_REC_MASTER_ABORT;
local_write_config(PCI_STATUS, 2, status);
/*
* If it was an imprecise abort, then we need to correct the
* return address to be _after_ the instruction.
*/
if (fsr & (1 << 10))
regs->ARM_pc += 4;
return 0;
}
/*
* Setup DMA mask to 64MB on PCI devices. Ignore all other devices.
*/
static int ixp4xx_pci_platform_notify(struct device *dev)
{
if(dev->bus == &pci_bus_type) {
*dev->dma_mask = SZ_64M - 1;
dev->coherent_dma_mask = SZ_64M - 1;
dmabounce_register_dev(dev, 2048, 4096);
}
return 0;
}
static int ixp4xx_pci_platform_notify_remove(struct device *dev)
{
if(dev->bus == &pci_bus_type) {
dmabounce_unregister_dev(dev);
}
return 0;
}
int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
{
return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M);
}
/*
* Only first 64MB of memory can be accessed via PCI.
* We use GFP_DMA to allocate safe buffers to do map/unmap.
* 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,
unsigned long *zhole_size)
{
unsigned int sz = SZ_64M >> PAGE_SHIFT;
/*
* Only adjust if > 64M on current system
*/
if (node || (zone_size[0] <= sz))
return;
zone_size[1] = zone_size[0] - sz;
zone_size[0] = sz;
zhole_size[1] = zhole_size[0];
zhole_size[0] = 0;
}
void __init ixp4xx_pci_preinit(void)
{
unsigned long cpuid = read_cpuid_id();
/*
* Determine which PCI read method to use.
* Rev 0 IXP425 requires workaround.
*/
if (!(cpuid & 0xf) && cpu_is_ixp42x()) {
printk("PCI: IXP42x A0 silicon detected - "
"PCI Non-Prefetch Workaround Enabled\n");
ixp4xx_pci_read = ixp4xx_pci_read_errata;
} else
ixp4xx_pci_read = ixp4xx_pci_read_no_errata;
/* hook in our fault handler for PCI errors */
hook_fault_code(16+6, abort_handler, SIGBUS, "imprecise external abort");
pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
/*
* We use identity AHB->PCI address translation
* in the 0x48000000 to 0x4bffffff address space
*/
*PCI_PCIMEMBASE = 0x48494A4B;
/*
* We also use identity PCI->AHB address translation
* in 4 16MB BARs that begin at the physical memory start
*/
*PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
((PHYS_OFFSET & 0xFF000000) >> 8) +
((PHYS_OFFSET & 0xFF000000) >> 16) +
((PHYS_OFFSET & 0xFF000000) >> 24) +
0x00010203;
if (*PCI_CSR & PCI_CSR_HOST) {
printk("PCI: IXP4xx is host\n");
pr_debug("setup BARs in controller\n");
/*
* We configure the PCI inbound memory windows to be
* 1:1 mapped to SDRAM
*/
local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + SZ_48M);
/*
* Enable CSR window at 64 MiB to allow PCI masters
* to continue prefetching past 64 MiB boundary.
*/
local_write_config(PCI_BASE_ADDRESS_4, 4, PHYS_OFFSET + SZ_64M);
/*
* Enable the IO window to be way up high, at 0xfffffc00
*/
local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
} else {
printk("PCI: IXP4xx is target - No bus scan performed\n");
}
printk("PCI: IXP4xx Using %s access for memory space\n",
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
"direct"
#else
"indirect"
#endif
);
pr_debug("clear error bits in ISR\n");
*PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE;
/*
* Set Initialize Complete in PCI Control Register: allow IXP4XX to
* respond to PCI configuration cycles. Specify that the AHB bus is
* operating in big endian mode. Set up byte lane swapping between
* little-endian PCI and the big-endian AHB bus
*/
#ifdef __ARMEB__
*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
#else
*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE;
#endif
pr_debug("DONE\n");
}
int ixp4xx_setup(int nr, struct pci_sys_data *sys)
{
struct resource *res;
if (nr >= 1)
return 0;
res = kzalloc(sizeof(*res) * 2, GFP_KERNEL);
if (res == NULL) {
/*
* If we're out of memory this early, something is wrong,
* so we might as well catch it here.
*/
panic("PCI: unable to allocate resources?\n");
}
local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
res[0].name = "PCI I/O Space";
res[0].start = 0x00000000;
res[0].end = 0x0000ffff;
res[0].flags = IORESOURCE_IO;
res[1].name = "PCI Memory Space";
res[1].start = PCIBIOS_MIN_MEM;
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
res[1].end = 0x4bffffff;
#else
res[1].end = 0x4fffffff;
#endif
res[1].flags = IORESOURCE_MEM;
request_resource(&ioport_resource, &res[0]);
request_resource(&iomem_resource, &res[1]);
sys->resource[0] = &res[0];
sys->resource[1] = &res[1];
sys->resource[2] = NULL;
platform_notify = ixp4xx_pci_platform_notify;
platform_notify_remove = ixp4xx_pci_platform_notify_remove;
return 1;
}
struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
{
return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
}
/*
* We override these so we properly do dmabounce otherwise drivers
* are able to set the dma_mask to 0xffffffff and we can no longer
* trap bounces. :(
*
* We just return true on everyhing except for < 64MB in which case
* we will fail miseralby and die since we can't handle that case.
*/
int
pci_set_dma_mask(struct pci_dev *dev, u64 mask)
{
if (mask >= SZ_64M - 1 )
return 0;
return -EIO;
}
int
pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
{
if (mask >= SZ_64M - 1 )
return 0;
return -EIO;
}
EXPORT_SYMBOL(ixp4xx_pci_read);
EXPORT_SYMBOL(ixp4xx_pci_write);

View File

@@ -0,0 +1,493 @@
/*
* arch/arm/mach-ixp4xx/common.c
*
* Generic code shared across all IXP4XX platforms
*
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2002 (c) Intel Corporation
* Copyright 2003-2004 (c) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/bootmem.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/io.h>
#include <mach/udc.h>
#include <mach/hardware.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
static void __init ixp4xx_clocksource_init(void);
static void __init ixp4xx_clockevent_init(void);
static struct clock_event_device clockevent_ixp4xx;
/*************************************************************************
* IXP4xx chipset I/O mapping
*************************************************************************/
static struct map_desc ixp4xx_io_desc[] __initdata = {
{ /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
.virtual = IXP4XX_PERIPHERAL_BASE_VIRT,
.pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
.length = IXP4XX_PERIPHERAL_REGION_SIZE,
.type = MT_DEVICE
}, { /* Expansion Bus Config Registers */
.virtual = IXP4XX_EXP_CFG_BASE_VIRT,
.pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
.length = IXP4XX_EXP_CFG_REGION_SIZE,
.type = MT_DEVICE
}, { /* PCI Registers */
.virtual = IXP4XX_PCI_CFG_BASE_VIRT,
.pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
.length = IXP4XX_PCI_CFG_REGION_SIZE,
.type = MT_DEVICE
},
#ifdef CONFIG_DEBUG_LL
{ /* Debug UART mapping */
.virtual = IXP4XX_DEBUG_UART_BASE_VIRT,
.pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS),
.length = IXP4XX_DEBUG_UART_REGION_SIZE,
.type = MT_DEVICE
}
#endif
};
void __init ixp4xx_map_io(void)
{
iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
}
/*************************************************************************
* IXP4xx chipset IRQ handling
*
* TODO: GPIO IRQs should be marked invalid until the user of the IRQ
* (be it PCI or something else) configures that GPIO line
* as an IRQ.
**************************************************************************/
enum ixp4xx_irq_type {
IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
};
/* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */
static unsigned long long ixp4xx_irq_edge = 0;
/*
* IRQ -> GPIO mapping table
*/
static signed char irq2gpio[32] = {
-1, -1, -1, -1, -1, -1, 0, 1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, -1, -1,
};
int gpio_to_irq(int gpio)
{
int irq;
for (irq = 0; irq < 32; irq++) {
if (irq2gpio[irq] == gpio)
return irq;
}
return -EINVAL;
}
EXPORT_SYMBOL(gpio_to_irq);
int irq_to_gpio(int irq)
{
int gpio = (irq < 32) ? irq2gpio[irq] : -EINVAL;
if (gpio == -1)
return -EINVAL;
return gpio;
}
EXPORT_SYMBOL(irq_to_gpio);
static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
{
int line = irq2gpio[irq];
u32 int_style;
enum ixp4xx_irq_type irq_type;
volatile u32 *int_reg;
/*
* Only for GPIO IRQs
*/
if (line < 0)
return -EINVAL;
switch (type){
case IRQ_TYPE_EDGE_BOTH:
int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
irq_type = IXP4XX_IRQ_EDGE;
break;
case IRQ_TYPE_EDGE_RISING:
int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
irq_type = IXP4XX_IRQ_EDGE;
break;
case IRQ_TYPE_EDGE_FALLING:
int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
irq_type = IXP4XX_IRQ_EDGE;
break;
case IRQ_TYPE_LEVEL_HIGH:
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
irq_type = IXP4XX_IRQ_LEVEL;
break;
case IRQ_TYPE_LEVEL_LOW:
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
irq_type = IXP4XX_IRQ_LEVEL;
break;
default:
return -EINVAL;
}
if (irq_type == IXP4XX_IRQ_EDGE)
ixp4xx_irq_edge |= (1 << irq);
else
ixp4xx_irq_edge &= ~(1 << irq);
if (line >= 8) { /* pins 8-15 */
line -= 8;
int_reg = IXP4XX_GPIO_GPIT2R;
} else { /* pins 0-7 */
int_reg = IXP4XX_GPIO_GPIT1R;
}
/* Clear the style for the appropriate pin */
*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
(line * IXP4XX_GPIO_STYLE_SIZE));
*IXP4XX_GPIO_GPISR = (1 << line);
/* Set the new style */
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
/* Configure the line as an input */
gpio_line_config(irq2gpio[irq], IXP4XX_GPIO_IN);
return 0;
}
static void ixp4xx_irq_mask(unsigned int irq)
{
if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
*IXP4XX_ICMR2 &= ~(1 << (irq - 32));
else
*IXP4XX_ICMR &= ~(1 << irq);
}
static void ixp4xx_irq_ack(unsigned int irq)
{
int line = (irq < 32) ? irq2gpio[irq] : -1;
if (line >= 0)
*IXP4XX_GPIO_GPISR = (1 << line);
}
/*
* Level triggered interrupts on GPIO lines can only be cleared when the
* interrupt condition disappears.
*/
static void ixp4xx_irq_unmask(unsigned int irq)
{
if (!(ixp4xx_irq_edge & (1 << irq)))
ixp4xx_irq_ack(irq);
if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
*IXP4XX_ICMR2 |= (1 << (irq - 32));
else
*IXP4XX_ICMR |= (1 << irq);
}
static struct irq_chip ixp4xx_irq_chip = {
.name = "IXP4xx",
.ack = ixp4xx_irq_ack,
.mask = ixp4xx_irq_mask,
.unmask = ixp4xx_irq_unmask,
.set_type = ixp4xx_set_irq_type,
};
void __init ixp4xx_init_irq(void)
{
int i = 0;
/* Route all sources to IRQ instead of FIQ */
*IXP4XX_ICLR = 0x0;
/* Disable all interrupt */
*IXP4XX_ICMR = 0x0;
if (cpu_is_ixp46x() || cpu_is_ixp43x()) {
/* Route upper 32 sources to IRQ instead of FIQ */
*IXP4XX_ICLR2 = 0x00;
/* Disable upper 32 interrupts */
*IXP4XX_ICMR2 = 0x00;
}
/* Default to all level triggered */
for(i = 0; i < NR_IRQS; i++) {
set_irq_chip(i, &ixp4xx_irq_chip);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
}
/*************************************************************************
* IXP4xx timer tick
* We use OS timer1 on the CPU for the timer tick and the timestamp
* counter as a source of real clock ticks to account for missed jiffies.
*************************************************************************/
static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = dev_id;
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct irqaction ixp4xx_timer_irq = {
.name = "timer1",
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ixp4xx_timer_interrupt,
.dev_id = &clockevent_ixp4xx,
};
void __init ixp4xx_timer_init(void)
{
/* Reset/disable counter */
*IXP4XX_OSRT1 = 0;
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
/* Reset time-stamp counter */
*IXP4XX_OSTS = 0;
/* Connect the interrupt handler and enable the interrupt */
setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
ixp4xx_clocksource_init();
ixp4xx_clockevent_init();
}
struct sys_timer ixp4xx_timer = {
.init = ixp4xx_timer_init,
};
static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info)
{
memcpy(&ixp4xx_udc_info, info, sizeof *info);
}
static struct resource ixp4xx_udc_resources[] = {
[0] = {
.start = 0xc800b000,
.end = 0xc800bfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IXP4XX_USB,
.end = IRQ_IXP4XX_USB,
.flags = IORESOURCE_IRQ,
},
};
/*
* USB device controller. The IXP4xx uses the same controller as PXA25X,
* so we just use the same device.
*/
static struct platform_device ixp4xx_udc_device = {
.name = "pxa25x-udc",
.id = -1,
.num_resources = 2,
.resource = ixp4xx_udc_resources,
.dev = {
.platform_data = &ixp4xx_udc_info,
},
};
static struct platform_device *ixp4xx_devices[] __initdata = {
&ixp4xx_udc_device,
};
static struct resource ixp46x_i2c_resources[] = {
[0] = {
.start = 0xc8011000,
.end = 0xc801101c,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IXP4XX_I2C,
.end = IRQ_IXP4XX_I2C,
.flags = IORESOURCE_IRQ
}
};
/*
* I2C controller. The IXP46x uses the same block as the IOP3xx, so
* we just use the same device name.
*/
static struct platform_device ixp46x_i2c_controller = {
.name = "IOP3xx-I2C",
.id = 0,
.num_resources = 2,
.resource = ixp46x_i2c_resources
};
static struct platform_device *ixp46x_devices[] __initdata = {
&ixp46x_i2c_controller
};
unsigned long ixp4xx_exp_bus_size;
EXPORT_SYMBOL(ixp4xx_exp_bus_size);
void __init ixp4xx_sys_init(void)
{
ixp4xx_exp_bus_size = SZ_16M;
platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
if (cpu_is_ixp46x()) {
int region;
platform_add_devices(ixp46x_devices,
ARRAY_SIZE(ixp46x_devices));
for (region = 0; region < 7; region++) {
if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) {
ixp4xx_exp_bus_size = SZ_32M;
break;
}
}
}
printk("IXP4xx: Using %luMiB expansion bus window size\n",
ixp4xx_exp_bus_size >> 20);
}
/*
* clocksource
*/
static cycle_t ixp4xx_get_cycles(struct clocksource *cs)
{
return *IXP4XX_OSTS;
}
static struct clocksource clocksource_ixp4xx = {
.name = "OSTS",
.rating = 200,
.read = ixp4xx_get_cycles,
.mask = CLOCKSOURCE_MASK(32),
.shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
unsigned long ixp4xx_timer_freq = FREQ;
EXPORT_SYMBOL(ixp4xx_timer_freq);
static void __init ixp4xx_clocksource_init(void)
{
clocksource_ixp4xx.mult =
clocksource_hz2mult(ixp4xx_timer_freq,
clocksource_ixp4xx.shift);
clocksource_register(&clocksource_ixp4xx);
}
/*
* clockevents
*/
static int ixp4xx_set_next_event(unsigned long evt,
struct clock_event_device *unused)
{
unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
*IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
return 0;
}
static void ixp4xx_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
osrt = LATCH & ~IXP4XX_OST_RELOAD_MASK;
opts = IXP4XX_OST_ENABLE;
break;
case CLOCK_EVT_MODE_ONESHOT:
/* period set by 'set next_event' */
osrt = 0;
opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
break;
case CLOCK_EVT_MODE_SHUTDOWN:
opts &= ~IXP4XX_OST_ENABLE;
break;
case CLOCK_EVT_MODE_RESUME:
opts |= IXP4XX_OST_ENABLE;
break;
case CLOCK_EVT_MODE_UNUSED:
default:
osrt = opts = 0;
break;
}
*IXP4XX_OSRT1 = osrt | opts;
}
static struct clock_event_device clockevent_ixp4xx = {
.name = "ixp4xx timer1",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.rating = 200,
.shift = 24,
.set_mode = ixp4xx_set_mode,
.set_next_event = ixp4xx_set_next_event,
};
static void __init ixp4xx_clockevent_init(void)
{
clockevent_ixp4xx.mult = div_sc(FREQ, NSEC_PER_SEC,
clockevent_ixp4xx.shift);
clockevent_ixp4xx.max_delta_ns =
clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx);
clockevent_ixp4xx.min_delta_ns =
clockevent_delta2ns(0xf, &clockevent_ixp4xx);
clockevent_ixp4xx.cpumask = cpumask_of(0);
clockevents_register_device(&clockevent_ixp4xx);
}

View File

@@ -0,0 +1,61 @@
/*
* arch/arm/mach-ixp4xx/coyote-pci.c
*
* PCI setup routines for ADI Engineering Coyote platform
*
* Copyright (C) 2002 Jungo Software Technologies.
* Copyright (C) 2003 MontaVista Softwrae, Inc.
*
* Maintainer: Deepak Saxena <dsaxena@mvista.com>
*
* 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/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
void __init coyote_pci_preinit(void)
{
set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init coyote_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
if (slot == COYOTE_PCI_SLOT0_DEVID)
return IRQ_COYOTE_PCI_SLOT0;
else if (slot == COYOTE_PCI_SLOT1_DEVID)
return IRQ_COYOTE_PCI_SLOT1;
else return -1;
}
struct hw_pci coyote_pci __initdata = {
.nr_controllers = 1,
.preinit = coyote_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = coyote_map_irq,
};
int __init coyote_pci_init(void)
{
if (machine_is_adi_coyote())
pci_common_init(&coyote_pci);
return 0;
}
subsys_initcall(coyote_pci_init);

View File

@@ -0,0 +1,130 @@
/*
* arch/arm/mach-ixp4xx/coyote-setup.c
*
* Board setup for ADI Engineering and IXDGP425 boards
*
* Copyright (C) 2003-2005 MontaVista Software, Inc.
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
static struct flash_platform_data coyote_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource coyote_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device coyote_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = {
.platform_data = &coyote_flash_data,
},
.num_resources = 1,
.resource = &coyote_flash_resource,
};
static struct resource coyote_uart_resource = {
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
};
static struct plat_serial8250_port coyote_uart_data[] = {
{
.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,
},
{ },
};
static struct platform_device coyote_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = coyote_uart_data,
},
.num_resources = 1,
.resource = &coyote_uart_resource,
};
static struct platform_device *coyote_devices[] __initdata = {
&coyote_flash,
&coyote_uart
};
static void __init coyote_init(void)
{
ixp4xx_sys_init();
coyote_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
coyote_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
if (machine_is_ixdpg425()) {
coyote_uart_data[0].membase =
(char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET);
coyote_uart_data[0].mapbase = IXP4XX_UART1_BASE_PHYS;
coyote_uart_data[0].irq = IRQ_IXP4XX_UART1;
}
platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices));
}
#ifdef CONFIG_ARCH_ADI_COYOTE
MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
/* Maintainer: MontaVista Software, Inc. */
.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 = coyote_init,
MACHINE_END
#endif
/*
* IXDPG425 is identical to Coyote except for which serial port
* is connected.
*/
#ifdef CONFIG_MACH_IXDPG425
MACHINE_START(IXDPG425, "Intel IXDPG425")
/* Maintainer: MontaVista Software, Inc. */
.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 = coyote_init,
MACHINE_END
#endif

View File

@@ -0,0 +1,74 @@
/*
* DSM-G600 board-level PCI initialization
*
* Copyright (C) 2006 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* based on ixdp425-pci.c:
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*
* Maintainer: http://www.nslu2-linux.org/
*
* 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>
void __init dsmg600_pci_preinit(void)
{
set_irq_type(IRQ_DSMG600_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTE, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTF, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static int pci_irq_table[DSMG600_PCI_MAX_DEV][DSMG600_PCI_IRQ_LINES] =
{
{ IRQ_DSMG600_PCI_INTE, -1, -1 },
{ IRQ_DSMG600_PCI_INTA, -1, -1 },
{ IRQ_DSMG600_PCI_INTB, IRQ_DSMG600_PCI_INTC, IRQ_DSMG600_PCI_INTD },
{ IRQ_DSMG600_PCI_INTF, -1, -1 },
};
int irq = -1;
if (slot >= 1 && slot <= DSMG600_PCI_MAX_DEV &&
pin >= 1 && pin <= DSMG600_PCI_IRQ_LINES)
irq = pci_irq_table[slot-1][pin-1];
return irq;
}
struct hw_pci __initdata dsmg600_pci = {
.nr_controllers = 1,
.preinit = dsmg600_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = dsmg600_map_irq,
};
int __init dsmg600_pci_init(void)
{
if (machine_is_dsmg600())
pci_common_init(&dsmg600_pci);
return 0;
}
subsys_initcall(dsmg600_pci_init);

View File

@@ -0,0 +1,272 @@
/*
* DSM-G600 board-setup
*
* Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
* Copyright (C) 2006 Tower Technologies
*
* based on ixdp425-setup.c:
* Copyright (C) 2003-2004 MontaVista Software, Inc.
* based on nslu2-power.c:
* Copyright (C) 2005 Tower Technologies
* based on nslu2-io.c:
* Copyright (C) 2004 Karen Spearel
*
* Author: Alessandro Zummo <a.zummo@towertech.it>
* Author: Michael Westerhof <mwester@dls.net>
* Author: Rod Whitby <rod@whitby.id.au>
* Maintainers: http://www.nslu2-linux.org/
*/
#include <linux/irq.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/leds.h>
#include <linux/reboot.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/time.h>
#include <asm/gpio.h>
static struct flash_platform_data dsmg600_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource dsmg600_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device dsmg600_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev.platform_data = &dsmg600_flash_data,
.num_resources = 1,
.resource = &dsmg600_flash_resource,
};
static struct i2c_gpio_platform_data dsmg600_i2c_gpio_data = {
.sda_pin = DSMG600_SDA_PIN,
.scl_pin = DSMG600_SCL_PIN,
};
static struct platform_device dsmg600_i2c_gpio = {
.name = "i2c-gpio",
.id = 0,
.dev = {
.platform_data = &dsmg600_i2c_gpio_data,
},
};
static struct i2c_board_info __initdata dsmg600_i2c_board_info [] = {
{
I2C_BOARD_INFO("pcf8563", 0x51),
},
};
static struct gpio_led dsmg600_led_pins[] = {
{
.name = "dsmg600:green:power",
.gpio = DSMG600_LED_PWR_GPIO,
},
{
.name = "dsmg600:green:wlan",
.gpio = DSMG600_LED_WLAN_GPIO,
.active_low = true,
},
};
static struct gpio_led_platform_data dsmg600_led_data = {
.num_leds = ARRAY_SIZE(dsmg600_led_pins),
.leds = dsmg600_led_pins,
};
static struct platform_device dsmg600_leds = {
.name = "leds-gpio",
.id = -1,
.dev.platform_data = &dsmg600_led_data,
};
static struct resource dsmg600_uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
}
};
static struct plat_serial8250_port dsmg600_uart_data[] = {
{
.mapbase = IXP4XX_UART1_BASE_PHYS,
.membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART1,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{
.mapbase = IXP4XX_UART2_BASE_PHYS,
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART2,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{ }
};
static struct platform_device dsmg600_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = dsmg600_uart_data,
.num_resources = ARRAY_SIZE(dsmg600_uart_resources),
.resource = dsmg600_uart_resources,
};
static struct platform_device *dsmg600_devices[] __initdata = {
&dsmg600_i2c_gpio,
&dsmg600_flash,
&dsmg600_leds,
};
static void dsmg600_power_off(void)
{
/* enable the pwr cntl gpio */
gpio_line_config(DSMG600_PO_GPIO, IXP4XX_GPIO_OUT);
/* poweroff */
gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH);
}
/* This is used to make sure the power-button pusher is serious. The button
* must be held until the value of this counter reaches zero.
*/
static int power_button_countdown;
/* Must hold the button down for at least this many counts to be processed */
#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
static void dsmg600_power_handler(unsigned long data);
static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0);
static void dsmg600_power_handler(unsigned long data)
{
/* This routine is called twice per second to check the
* state of the power button.
*/
if (gpio_get_value(DSMG600_PB_GPIO)) {
/* IO Pin is 1 (button pushed) */
if (power_button_countdown > 0)
power_button_countdown--;
} else {
/* Done on button release, to allow for auto-power-on mods. */
if (power_button_countdown == 0) {
/* Signal init to do the ctrlaltdel action,
* this will bypass init if it hasn't started
* and do a kernel_restart.
*/
ctrl_alt_del();
/* Change the state of the power LED to "blink" */
gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
} else {
power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
}
}
mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
}
static irqreturn_t dsmg600_reset_handler(int irq, void *dev_id)
{
/* This is the paper-clip reset, it shuts the machine down directly. */
machine_power_off();
return IRQ_HANDLED;
}
static void __init dsmg600_timer_init(void)
{
/* The xtal on this machine is non-standard. */
ixp4xx_timer_freq = DSMG600_FREQ;
/* Call standard timer_init function. */
ixp4xx_timer_init();
}
static struct sys_timer dsmg600_timer = {
.init = dsmg600_timer_init,
};
static void __init dsmg600_init(void)
{
ixp4xx_sys_init();
/* Make sure that GPIO14 and GPIO15 are not used as clocks */
*IXP4XX_GPIO_GPCLKR = 0;
dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
dsmg600_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
i2c_register_board_info(0, dsmg600_i2c_board_info,
ARRAY_SIZE(dsmg600_i2c_board_info));
/* The UART is required on the DSM-G600 (Redboot cannot use the
* NIC) -- do it here so that it does *not* get removed if
* platform_add_devices fails!
*/
(void)platform_device_register(&dsmg600_uart);
platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices));
pm_power_off = dsmg600_power_off;
if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler,
IRQF_DISABLED | IRQF_TRIGGER_LOW,
"DSM-G600 reset button", NULL) < 0) {
printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
gpio_to_irq(DSMG600_RB_GPIO));
}
/* The power button on the D-Link DSM-G600 is on GPIO 15, but
* it cannot handle interrupts on that GPIO line. So we'll
* have to poll it with a kernel timer.
*/
/* Make sure that the power button GPIO is set up as an input */
gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN);
/* Set the initial value for the power button IRQ handler */
power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
}
MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
/* Maintainer: www.nslu2-linux.org */
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &dsmg600_timer,
.init_machine = dsmg600_init,
MACHINE_END

View File

@@ -0,0 +1,71 @@
/*
* arch/arch/mach-ixp4xx/fsg-pci.c
*
* FSG board-level PCI initialization
*
* Author: Rod Whitby <rod@whitby.id.au>
* Maintainer: http://www.nslu2-linux.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>
void __init fsg_pci_preinit(void)
{
set_irq_type(IRQ_FSG_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_FSG_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_FSG_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init fsg_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static int pci_irq_table[FSG_PCI_IRQ_LINES] = {
IRQ_FSG_PCI_INTC,
IRQ_FSG_PCI_INTB,
IRQ_FSG_PCI_INTA,
};
int irq = -1;
slot = slot - 11;
if (slot >= 1 && slot <= FSG_PCI_MAX_DEV &&
pin >= 1 && pin <= FSG_PCI_IRQ_LINES)
irq = pci_irq_table[(slot - 1)];
printk(KERN_INFO "%s: Mapped slot %d pin %d to IRQ %d\n",
__func__, slot, pin, irq);
return irq;
}
struct hw_pci fsg_pci __initdata = {
.nr_controllers = 1,
.preinit = fsg_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = fsg_map_irq,
};
int __init fsg_pci_init(void)
{
if (machine_is_fsg())
pci_common_init(&fsg_pci);
return 0;
}
subsys_initcall(fsg_pci_init);

View File

@@ -0,0 +1,275 @@
/*
* arch/arm/mach-ixp4xx/fsg-setup.c
*
* FSG board-setup
*
* Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
*
* based on ixdp425-setup.c:
* Copyright (C) 2003-2004 MontaVista Software, Inc.
* based on nslu2-power.c
* Copyright (C) 2005 Tower Technologies
*
* Author: Rod Whitby <rod@whitby.id.au>
* Maintainers: http://www.nslu2-linux.org/
*
*/
#include <linux/if_ether.h>
#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/leds.h>
#include <linux/reboot.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/io.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/gpio.h>
static struct flash_platform_data fsg_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource fsg_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device fsg_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = {
.platform_data = &fsg_flash_data,
},
.num_resources = 1,
.resource = &fsg_flash_resource,
};
static struct i2c_gpio_platform_data fsg_i2c_gpio_data = {
.sda_pin = FSG_SDA_PIN,
.scl_pin = FSG_SCL_PIN,
};
static struct platform_device fsg_i2c_gpio = {
.name = "i2c-gpio",
.id = 0,
.dev = {
.platform_data = &fsg_i2c_gpio_data,
},
};
static struct i2c_board_info __initdata fsg_i2c_board_info [] = {
{
I2C_BOARD_INFO("isl1208", 0x6f),
},
};
static struct resource fsg_uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
}
};
static struct plat_serial8250_port fsg_uart_data[] = {
{
.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,
},
{
.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,
},
{ }
};
static struct platform_device fsg_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = fsg_uart_data,
},
.num_resources = ARRAY_SIZE(fsg_uart_resources),
.resource = fsg_uart_resources,
};
static struct platform_device fsg_leds = {
.name = "fsg-led",
.id = -1,
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct eth_plat_info fsg_plat_eth[] = {
{
.phy = 5,
.rxq = 3,
.txreadyq = 20,
}, {
.phy = 4,
.rxq = 4,
.txreadyq = 21,
}
};
static struct platform_device fsg_eth[] = {
{
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev = {
.platform_data = fsg_plat_eth,
},
}, {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEC,
.dev = {
.platform_data = fsg_plat_eth + 1,
},
}
};
static struct platform_device *fsg_devices[] __initdata = {
&fsg_i2c_gpio,
&fsg_flash,
&fsg_leds,
&fsg_eth[0],
&fsg_eth[1],
};
static irqreturn_t fsg_power_handler(int irq, void *dev_id)
{
/* Signal init to do the ctrlaltdel action, this will bypass init if
* it hasn't started and do a kernel_restart.
*/
ctrl_alt_del();
return IRQ_HANDLED;
}
static irqreturn_t fsg_reset_handler(int irq, void *dev_id)
{
/* This is the paper-clip reset which does an emergency reboot. */
printk(KERN_INFO "Restarting system.\n");
machine_restart(NULL);
/* This should never be reached. */
return IRQ_HANDLED;
}
static void __init fsg_init(void)
{
uint8_t __iomem *f;
ixp4xx_sys_init();
fsg_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
fsg_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
/* Configure CS2 for operation, 8bit and writable */
*IXP4XX_EXP_CS2 = 0xbfff0002;
i2c_register_board_info(0, fsg_i2c_board_info,
ARRAY_SIZE(fsg_i2c_board_info));
/* This is only useful on a modified machine, but it is valuable
* to have it first in order to see debug messages, and so that
* it does *not* get removed if platform_add_devices fails!
*/
(void)platform_device_register(&fsg_uart);
platform_add_devices(fsg_devices, ARRAY_SIZE(fsg_devices));
if (request_irq(gpio_to_irq(FSG_RB_GPIO), &fsg_reset_handler,
IRQF_DISABLED | IRQF_TRIGGER_LOW,
"FSG reset button", NULL) < 0) {
printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
gpio_to_irq(FSG_RB_GPIO));
}
if (request_irq(gpio_to_irq(FSG_SB_GPIO), &fsg_power_handler,
IRQF_DISABLED | IRQF_TRIGGER_LOW,
"FSG power button", NULL) < 0) {
printk(KERN_DEBUG "Power Button IRQ %d not available\n",
gpio_to_irq(FSG_SB_GPIO));
}
/*
* Map in a portion of the flash and read the MAC addresses.
* Since it is stored in BE in the flash itself, we need to
* byteswap it if we're in LE mode.
*/
f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x400000);
if (f) {
#ifdef __ARMEB__
int i;
for (i = 0; i < 6; i++) {
fsg_plat_eth[0].hwaddr[i] = readb(f + 0x3C0422 + i);
fsg_plat_eth[1].hwaddr[i] = readb(f + 0x3C043B + i);
}
#else
/*
Endian-swapped reads from unaligned addresses are
required to extract the two MACs from the big-endian
Redboot config area in flash.
*/
fsg_plat_eth[0].hwaddr[0] = readb(f + 0x3C0421);
fsg_plat_eth[0].hwaddr[1] = readb(f + 0x3C0420);
fsg_plat_eth[0].hwaddr[2] = readb(f + 0x3C0427);
fsg_plat_eth[0].hwaddr[3] = readb(f + 0x3C0426);
fsg_plat_eth[0].hwaddr[4] = readb(f + 0x3C0425);
fsg_plat_eth[0].hwaddr[5] = readb(f + 0x3C0424);
fsg_plat_eth[1].hwaddr[0] = readb(f + 0x3C0439);
fsg_plat_eth[1].hwaddr[1] = readb(f + 0x3C043F);
fsg_plat_eth[1].hwaddr[2] = readb(f + 0x3C043E);
fsg_plat_eth[1].hwaddr[3] = readb(f + 0x3C043D);
fsg_plat_eth[1].hwaddr[4] = readb(f + 0x3C043C);
fsg_plat_eth[1].hwaddr[5] = readb(f + 0x3C0443);
#endif
iounmap(f);
}
printk(KERN_INFO "FSG: Using MAC address %pM for port 0\n",
fsg_plat_eth[0].hwaddr);
printk(KERN_INFO "FSG: Using MAC address %pM for port 1\n",
fsg_plat_eth[1].hwaddr);
}
MACHINE_START(FSG, "Freecom FSG-3")
/* Maintainer: www.nslu2-linux.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 = fsg_init,
MACHINE_END

View File

@@ -0,0 +1,63 @@
/*
* arch/arch/mach-ixp4xx/gateway7001-pci.c
*
* PCI setup routines for Gateway 7001
*
* Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
*
* based on coyote-pci.c:
* Copyright (C) 2002 Jungo Software Technologies.
* Copyright (C) 2003 MontaVista Softwrae, Inc.
*
* Maintainer: Imre Kaloz <kaloz@openwrt.org>
*
* 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/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/mach/pci.h>
void __init gateway7001_pci_preinit(void)
{
set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init gateway7001_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
if (slot == 1)
return IRQ_IXP4XX_GPIO11;
else if (slot == 2)
return IRQ_IXP4XX_GPIO10;
else return -1;
}
struct hw_pci gateway7001_pci __initdata = {
.nr_controllers = 1,
.preinit = gateway7001_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = gateway7001_map_irq,
};
int __init gateway7001_pci_init(void)
{
if (machine_is_gateway7001())
pci_common_init(&gateway7001_pci);
return 0;
}
subsys_initcall(gateway7001_pci_init);

View File

@@ -0,0 +1,108 @@
/*
* arch/arm/mach-ixp4xx/gateway7001-setup.c
*
* Board setup for the Gateway 7001 board
*
* Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
*
* based on coyote-setup.c:
* Copyright (C) 2003-2005 MontaVista Software, Inc.
*
* Author: Imre Kaloz <Kaloz@openwrt.org>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
static struct flash_platform_data gateway7001_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource gateway7001_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device gateway7001_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = {
.platform_data = &gateway7001_flash_data,
},
.num_resources = 1,
.resource = &gateway7001_flash_resource,
};
static struct resource gateway7001_uart_resource = {
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
};
static struct plat_serial8250_port gateway7001_uart_data[] = {
{
.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,
},
{ },
};
static struct platform_device gateway7001_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = gateway7001_uart_data,
},
.num_resources = 1,
.resource = &gateway7001_uart_resource,
};
static struct platform_device *gateway7001_devices[] __initdata = {
&gateway7001_flash,
&gateway7001_uart
};
static void __init gateway7001_init(void)
{
ixp4xx_sys_init();
gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
}
#ifdef CONFIG_MACH_GATEWAY7001
MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
/* Maintainer: Imre Kaloz <kaloz@openwrt.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 = gateway7001_init,
MACHINE_END
#endif

View File

@@ -0,0 +1,507 @@
/*
* Goramo MultiLink router platform code
* Copyright (C) 2006-2009 Krzysztof Halasa <khc@pm.waw.pl>
*/
#include <linux/delay.h>
#include <linux/hdlc.h>
#include <linux/i2c-gpio.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/serial_8250.h>
#include <asm/mach-types.h>
#include <asm/system.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/pci.h>
#define xgpio_irq(n) (IRQ_IXP4XX_GPIO ## n)
#define gpio_irq(n) xgpio_irq(n)
#define SLOT_ETHA 0x0B /* IDSEL = AD21 */
#define SLOT_ETHB 0x0C /* IDSEL = AD20 */
#define SLOT_MPCI 0x0D /* IDSEL = AD19 */
#define SLOT_NEC 0x0E /* IDSEL = AD18 */
#define IRQ_ETHA IRQ_IXP4XX_GPIO4
#define IRQ_ETHB IRQ_IXP4XX_GPIO5
#define IRQ_NEC IRQ_IXP4XX_GPIO3
#define IRQ_MPCI IRQ_IXP4XX_GPIO12
/* GPIO lines */
#define GPIO_SCL 0
#define GPIO_SDA 1
#define GPIO_STR 2
#define GPIO_HSS0_DCD_N 6
#define GPIO_HSS1_DCD_N 7
#define GPIO_HSS0_CTS_N 10
#define GPIO_HSS1_CTS_N 11
#define GPIO_HSS1_RTS_N 13
#define GPIO_HSS0_RTS_N 14
/* Control outputs from 74HC4094 */
#define CONTROL_HSS0_CLK_INT 0
#define CONTROL_HSS1_CLK_INT 1
#define CONTROL_HSS0_DTR_N 2
#define CONTROL_HSS1_DTR_N 3
#define CONTROL_EXT 4
#define CONTROL_AUTO_RESET 5
#define CONTROL_PCI_RESET_N 6
#define CONTROL_EEPROM_WC_N 7
/* offsets from start of flash ROM = 0x50000000 */
#define CFG_ETH0_ADDRESS 0x40 /* 6 bytes */
#define CFG_ETH1_ADDRESS 0x46 /* 6 bytes */
#define CFG_REV 0x4C /* u32 */
#define CFG_SDRAM_SIZE 0x50 /* u32 */
#define CFG_SDRAM_CONF 0x54 /* u32 */
#define CFG_SDRAM_MODE 0x58 /* u32 */
#define CFG_SDRAM_REFRESH 0x5C /* u32 */
#define CFG_HW_BITS 0x60 /* u32 */
#define CFG_HW_USB_PORTS 0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
#define CFG_HW_HAS_PCI_SLOT 0x00000008
#define CFG_HW_HAS_ETH0 0x00000010
#define CFG_HW_HAS_ETH1 0x00000020
#define CFG_HW_HAS_HSS0 0x00000040
#define CFG_HW_HAS_HSS1 0x00000080
#define CFG_HW_HAS_UART0 0x00000100
#define CFG_HW_HAS_UART1 0x00000200
#define CFG_HW_HAS_EEPROM 0x00000400
#define FLASH_CMD_READ_ARRAY 0xFF
#define FLASH_CMD_READ_ID 0x90
#define FLASH_SER_OFF 0x102 /* 0x81 in 16-bit mode */
static u32 hw_bits = 0xFFFFFFFD; /* assume all hardware present */;
static u8 control_value;
static void set_scl(u8 value)
{
gpio_line_set(GPIO_SCL, !!value);
udelay(3);
}
static void set_sda(u8 value)
{
gpio_line_set(GPIO_SDA, !!value);
udelay(3);
}
static void set_str(u8 value)
{
gpio_line_set(GPIO_STR, !!value);
udelay(3);
}
static inline void set_control(int line, int value)
{
if (value)
control_value |= (1 << line);
else
control_value &= ~(1 << line);
}
static void output_control(void)
{
int i;
gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);
for (i = 0; i < 8; i++) {
set_scl(0);
set_sda(control_value & (0x80 >> i)); /* MSB first */
set_scl(1); /* active edge */
}
set_str(1);
set_str(0);
set_scl(0);
set_sda(1); /* Be ready for START */
set_scl(1);
}
static void (*set_carrier_cb_tab[2])(void *pdev, int carrier);
static int hss_set_clock(int port, unsigned int clock_type)
{
int ctrl_int = port ? CONTROL_HSS1_CLK_INT : CONTROL_HSS0_CLK_INT;
switch (clock_type) {
case CLOCK_DEFAULT:
case CLOCK_EXT:
set_control(ctrl_int, 0);
output_control();
return CLOCK_EXT;
case CLOCK_INT:
set_control(ctrl_int, 1);
output_control();
return CLOCK_INT;
default:
return -EINVAL;
}
}
static irqreturn_t hss_dcd_irq(int irq, void *pdev)
{
int i, port = (irq == gpio_irq(GPIO_HSS1_DCD_N));
gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
set_carrier_cb_tab[port](pdev, !i);
return IRQ_HANDLED;
}
static int hss_open(int port, void *pdev,
void (*set_carrier_cb)(void *pdev, int carrier))
{
int i, irq;
if (!port)
irq = gpio_irq(GPIO_HSS0_DCD_N);
else
irq = gpio_irq(GPIO_HSS1_DCD_N);
gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
set_carrier_cb(pdev, !i);
set_carrier_cb_tab[!!port] = set_carrier_cb;
if ((i = request_irq(irq, hss_dcd_irq, 0, "IXP4xx HSS", pdev)) != 0) {
printk(KERN_ERR "ixp4xx_hss: failed to request IRQ%i (%i)\n",
irq, i);
return i;
}
set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);
output_control();
gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
return 0;
}
static void hss_close(int port, void *pdev)
{
free_irq(port ? gpio_irq(GPIO_HSS1_DCD_N) : gpio_irq(GPIO_HSS0_DCD_N),
pdev);
set_carrier_cb_tab[!!port] = NULL; /* catch bugs */
set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
output_control();
gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
}
/* Flash memory */
static struct flash_platform_data flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device device_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = { .platform_data = &flash_data },
.num_resources = 1,
.resource = &flash_resource,
};
/* I^2C interface */
static struct i2c_gpio_platform_data i2c_data = {
.sda_pin = GPIO_SDA,
.scl_pin = GPIO_SCL,
};
static struct platform_device device_i2c = {
.name = "i2c-gpio",
.id = 0,
.dev = { .platform_data = &i2c_data },
};
/* IXP425 2 UART ports */
static struct resource uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
}
};
static struct plat_serial8250_port uart_data[] = {
{
.mapbase = IXP4XX_UART1_BASE_PHYS,
.membase = (char __iomem *)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,
},
{
.mapbase = IXP4XX_UART2_BASE_PHYS,
.membase = (char __iomem *)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,
},
{ },
};
static struct platform_device device_uarts = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = uart_data,
.num_resources = 2,
.resource = uart_resources,
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct eth_plat_info eth_plat[] = {
{
.phy = 0,
.rxq = 3,
.txreadyq = 32,
}, {
.phy = 1,
.rxq = 4,
.txreadyq = 33,
}
};
static struct platform_device device_eth_tab[] = {
{
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = eth_plat,
}, {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEC,
.dev.platform_data = eth_plat + 1,
}
};
/* IXP425 2 synchronous serial ports */
static struct hss_plat_info hss_plat[] = {
{
.set_clock = hss_set_clock,
.open = hss_open,
.close = hss_close,
.txreadyq = 34,
}, {
.set_clock = hss_set_clock,
.open = hss_open,
.close = hss_close,
.txreadyq = 35,
}
};
static struct platform_device device_hss_tab[] = {
{
.name = "ixp4xx_hss",
.id = 0,
.dev.platform_data = hss_plat,
}, {
.name = "ixp4xx_hss",
.id = 1,
.dev.platform_data = hss_plat + 1,
}
};
static struct platform_device *device_tab[6] __initdata = {
&device_flash, /* index 0 */
};
static inline u8 __init flash_readb(u8 __iomem *flash, u32 addr)
{
#ifdef __ARMEB__
return __raw_readb(flash + addr);
#else
return __raw_readb(flash + (addr ^ 3));
#endif
}
static inline u16 __init flash_readw(u8 __iomem *flash, u32 addr)
{
#ifdef __ARMEB__
return __raw_readw(flash + addr);
#else
return __raw_readw(flash + (addr ^ 2));
#endif
}
static void __init gmlr_init(void)
{
u8 __iomem *flash;
int i, devices = 1; /* flash */
ixp4xx_sys_init();
if ((flash = ioremap(IXP4XX_EXP_BUS_BASE_PHYS, 0x80)) == NULL)
printk(KERN_ERR "goramo-mlr: unable to access system"
" configuration data\n");
else {
system_rev = __raw_readl(flash + CFG_REV);
hw_bits = __raw_readl(flash + CFG_HW_BITS);
for (i = 0; i < ETH_ALEN; i++) {
eth_plat[0].hwaddr[i] =
flash_readb(flash, CFG_ETH0_ADDRESS + i);
eth_plat[1].hwaddr[i] =
flash_readb(flash, CFG_ETH1_ADDRESS + i);
}
__raw_writew(FLASH_CMD_READ_ID, flash);
system_serial_high = flash_readw(flash, FLASH_SER_OFF);
system_serial_high <<= 16;
system_serial_high |= flash_readw(flash, FLASH_SER_OFF + 2);
system_serial_low = flash_readw(flash, FLASH_SER_OFF + 4);
system_serial_low <<= 16;
system_serial_low |= flash_readw(flash, FLASH_SER_OFF + 6);
__raw_writew(FLASH_CMD_READ_ARRAY, flash);
iounmap(flash);
}
switch (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1)) {
case CFG_HW_HAS_UART0:
memset(&uart_data[1], 0, sizeof(uart_data[1]));
device_uarts.num_resources = 1;
break;
case CFG_HW_HAS_UART1:
device_uarts.dev.platform_data = &uart_data[1];
device_uarts.resource = &uart_resources[1];
device_uarts.num_resources = 1;
break;
}
if (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1))
device_tab[devices++] = &device_uarts; /* max index 1 */
if (hw_bits & CFG_HW_HAS_ETH0)
device_tab[devices++] = &device_eth_tab[0]; /* max index 2 */
if (hw_bits & CFG_HW_HAS_ETH1)
device_tab[devices++] = &device_eth_tab[1]; /* max index 3 */
if (hw_bits & CFG_HW_HAS_HSS0)
device_tab[devices++] = &device_hss_tab[0]; /* max index 4 */
if (hw_bits & CFG_HW_HAS_HSS1)
device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
if (hw_bits & CFG_HW_HAS_EEPROM)
device_tab[devices++] = &device_i2c; /* max index 6 */
gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);
gpio_line_config(GPIO_STR, IXP4XX_GPIO_OUT);
gpio_line_config(GPIO_HSS0_RTS_N, IXP4XX_GPIO_OUT);
gpio_line_config(GPIO_HSS1_RTS_N, IXP4XX_GPIO_OUT);
gpio_line_config(GPIO_HSS0_DCD_N, IXP4XX_GPIO_IN);
gpio_line_config(GPIO_HSS1_DCD_N, IXP4XX_GPIO_IN);
set_irq_type(gpio_irq(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
set_irq_type(gpio_irq(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
set_control(CONTROL_HSS0_DTR_N, 1);
set_control(CONTROL_HSS1_DTR_N, 1);
set_control(CONTROL_EEPROM_WC_N, 1);
set_control(CONTROL_PCI_RESET_N, 1);
output_control();
msleep(1); /* Wait for PCI devices to initialize */
flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
platform_add_devices(device_tab, devices);
}
#ifdef CONFIG_PCI
static void __init gmlr_pci_preinit(void)
{
set_irq_type(IRQ_ETHA, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_ETHB, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_NEC, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_MPCI, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static void __init gmlr_pci_postinit(void)
{
if ((hw_bits & CFG_HW_USB_PORTS) >= 2 &&
(hw_bits & CFG_HW_USB_PORTS) < 5) {
/* need to adjust number of USB ports on NEC chip */
u32 value, addr = BIT(32 - SLOT_NEC) | 0xE0;
if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
value &= ~7;
value |= (hw_bits & CFG_HW_USB_PORTS);
ixp4xx_pci_write(addr, NP_CMD_CONFIGWRITE, value);
}
}
}
static int __init gmlr_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
switch(slot) {
case SLOT_ETHA: return IRQ_ETHA;
case SLOT_ETHB: return IRQ_ETHB;
case SLOT_NEC: return IRQ_NEC;
default: return IRQ_MPCI;
}
}
static struct hw_pci gmlr_hw_pci __initdata = {
.nr_controllers = 1,
.preinit = gmlr_pci_preinit,
.postinit = gmlr_pci_postinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = gmlr_map_irq,
};
static int __init gmlr_pci_init(void)
{
if (machine_is_goramo_mlr() &&
(hw_bits & (CFG_HW_USB_PORTS | CFG_HW_HAS_PCI_SLOT)))
pci_common_init(&gmlr_hw_pci);
return 0;
}
subsys_initcall(gmlr_pci_init);
#endif /* CONFIG_PCI */
MACHINE_START(GORAMO_MLR, "MultiLink")
/* Maintainer: Krzysztof Halasa */
.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 = gmlr_init,
MACHINE_END

View File

@@ -0,0 +1,91 @@
/*
* arch/arm/mach-ixp4xx/gtwx5715-pci.c
*
* Gemtek GTWX5715 (Linksys WRV54G) board setup
*
* Copyright (C) 2004 George T. Joseph
* Derived from Coyote
*
* 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/pci.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <mach/gtwx5715.h>
#include <asm/mach/pci.h>
/*
* The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
* Slot 0 isn't actually populated with a card connector but
* we initialize it anyway in case a future version has the
* slot populated or someone with good soldering skills has
* some free time.
*/
void __init gtwx5715_pci_preinit(void)
{
set_irq_type(GTWX5715_PCI_SLOT0_INTA_IRQ, IRQ_TYPE_LEVEL_LOW);
set_irq_type(GTWX5715_PCI_SLOT0_INTB_IRQ, IRQ_TYPE_LEVEL_LOW);
set_irq_type(GTWX5715_PCI_SLOT1_INTA_IRQ, IRQ_TYPE_LEVEL_LOW);
set_irq_type(GTWX5715_PCI_SLOT1_INTB_IRQ, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init gtwx5715_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int rc;
static int gtwx5715_irqmap
[GTWX5715_PCI_SLOT_COUNT]
[GTWX5715_PCI_INT_PIN_COUNT] = {
{GTWX5715_PCI_SLOT0_INTA_IRQ, GTWX5715_PCI_SLOT0_INTB_IRQ},
{GTWX5715_PCI_SLOT1_INTA_IRQ, GTWX5715_PCI_SLOT1_INTB_IRQ},
};
if (slot >= GTWX5715_PCI_SLOT_COUNT ||
pin >= GTWX5715_PCI_INT_PIN_COUNT) rc = -1;
else
rc = gtwx5715_irqmap[slot][pin-1];
printk("%s: Mapped slot %d pin %d to IRQ %d\n", __func__, slot, pin, rc);
return(rc);
}
struct hw_pci gtwx5715_pci __initdata = {
.nr_controllers = 1,
.preinit = gtwx5715_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = gtwx5715_map_irq,
};
int __init gtwx5715_pci_init(void)
{
if (machine_is_gtwx5715())
{
pci_common_init(&gtwx5715_pci);
}
return 0;
}
subsys_initcall(gtwx5715_pci_init);

View File

@@ -0,0 +1,151 @@
/*
* arch/arm/mach-ixp4xx/gtwx5715-setup.c
*
* Gemtek GTWX5715 (Linksys WRV54G) board setup
*
* Copyright (C) 2004 George T. Joseph
* Derived from Coyote
*
* 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/init.h>
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <mach/gtwx5715.h>
/*
* Xscale UART registers are 32 bits wide with only the least
* significant 8 bits having any meaning. From a configuration
* perspective, this means 2 things...
*
* Setting .regshift = 2 so that the standard 16550 registers
* line up on every 4th byte.
*
* Shifting the register start virtual address +3 bytes when
* compiled big-endian. Since register writes are done on a
* single byte basis, if the shift isn't done the driver will
* write the value into the most significant byte of the register,
* which is ignored, instead of the least significant.
*/
#ifdef __ARMEB__
#define REG_OFFSET 3
#else
#define REG_OFFSET 0
#endif
/*
* Only the second or "console" uart is connected on the gtwx5715.
*/
static struct resource gtwx5715_uart_resources[] = {
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_IXP4XX_UART2,
.end = IRQ_IXP4XX_UART2,
.flags = IORESOURCE_IRQ,
},
{ },
};
static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
{
.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,
},
{ },
};
static struct platform_device gtwx5715_uart_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = gtwx5715_uart_platform_data,
},
.num_resources = 2,
.resource = gtwx5715_uart_resources,
};
static struct flash_platform_data gtwx5715_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource gtwx5715_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device gtwx5715_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = {
.platform_data = &gtwx5715_flash_data,
},
.num_resources = 1,
.resource = &gtwx5715_flash_resource,
};
static struct platform_device *gtwx5715_devices[] __initdata = {
&gtwx5715_uart_device,
&gtwx5715_flash,
};
static void __init gtwx5715_init(void)
{
ixp4xx_sys_init();
gtwx5715_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
gtwx5715_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1;
platform_add_devices(gtwx5715_devices, ARRAY_SIZE(gtwx5715_devices));
}
MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
/* Maintainer: George Joseph */
.phys_io = IXP4XX_UART2_BASE_PHYS,
.io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,
.init_machine = gtwx5715_init,
MACHINE_END

View File

@@ -0,0 +1,39 @@
/*
* arch/arm/mach-ixp4xx/include/mach/avila.h
*
* Gateworks Avila platform specific definitions
*
* Author: Michael-Luke Jones <mlj28@cam.ac.uk>
*
* Based on ixdp425.h
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2004 (c) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#define AVILA_SDA_PIN 7
#define AVILA_SCL_PIN 6
/*
* AVILA PCI IRQs
*/
#define AVILA_PCI_MAX_DEV 4
#define LOFT_PCI_MAX_DEV 6
#define AVILA_PCI_IRQ_LINES 4
/* PCI controller GPIO to IRQ pin mappings */
#define AVILA_PCI_INTA_PIN 11
#define AVILA_PCI_INTB_PIN 10
#define AVILA_PCI_INTC_PIN 9
#define AVILA_PCI_INTD_PIN 8

View File

@@ -0,0 +1,33 @@
/*
* arch/arm/mach-ixp4xx/include/mach/coyote.h
*
* ADI Engineering platform specific definitions
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2004 (c) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
/* PCI controller GPIO to IRQ pin mappings */
#define COYOTE_PCI_SLOT0_PIN 6
#define COYOTE_PCI_SLOT1_PIN 11
#define COYOTE_PCI_SLOT0_DEVID 14
#define COYOTE_PCI_SLOT1_DEVID 15
#define COYOTE_IDE_BASE_PHYS IXP4XX_EXP_BUS_BASE(3)
#define COYOTE_IDE_BASE_VIRT 0xFFFE1000
#define COYOTE_IDE_REGION_SIZE 0x1000
#define COYOTE_IDE_DATA_PORT 0xFFFE10E0
#define COYOTE_IDE_CTRL_PORT 0xFFFE10FC
#define COYOTE_IDE_ERROR_PORT 0xFFFE10E2

View File

@@ -0,0 +1,57 @@
/*
* arch/arm/mach-ixp4xx/include/mach/cpu.h
*
* IXP4XX cpu type detection
*
* Copyright (C) 2007 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.
*
*/
#ifndef __ASM_ARCH_CPU_H__
#define __ASM_ARCH_CPU_H__
#include <asm/cputype.h>
/* Processor id value in CP15 Register 0 */
#define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */
#define IXP42X_PROCESSOR_ID_MASK 0xffffffc0
#define IXP43X_PROCESSOR_ID_VALUE 0x69054040
#define IXP43X_PROCESSOR_ID_MASK 0xfffffff0
#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
#define IXP46X_PROCESSOR_ID_MASK 0xfffffff0
#define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP42X_PROCESSOR_ID_MASK | 0xF)) == \
IXP42X_PROCESSOR_ID_VALUE)
#define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
IXP42X_PROCESSOR_ID_VALUE)
#define cpu_is_ixp43x() ((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
IXP43X_PROCESSOR_ID_VALUE)
#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
IXP46X_PROCESSOR_ID_VALUE)
static inline u32 ixp4xx_read_feature_bits(void)
{
u32 val = ~*IXP4XX_EXP_CFG2;
if (cpu_is_ixp42x_rev_a0())
return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
IXP4XX_FEATURE_AES);
if (cpu_is_ixp42x())
return val & IXP42X_FEATURE_MASK;
if (cpu_is_ixp43x())
return val & IXP43X_FEATURE_MASK;
return val & IXP46X_FEATURE_MASK;
}
static inline void ixp4xx_write_feature_bits(u32 value)
{
*IXP4XX_EXP_CFG2 = ~value;
}
#endif /* _ASM_ARCH_CPU_H */

View File

@@ -0,0 +1,24 @@
/* arch/arm/mach-ixp4xx/include/mach/debug-macro.S
*
* Debugging macro include header
*
* Copyright (C) 1994-1999 Russell King
* Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
*
* 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.
*/
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
moveq \rx, #0xc8000000
movne \rx, #0xff000000
orrne \rx, \rx, #0x00b00000
add \rx,\rx,#3 @ Uart regs are at off set of 3 if
@ byte writes used - Big Endian.
.endm
#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>

View File

@@ -0,0 +1,52 @@
/*
* DSM-G600 platform specific definitions
*
* Copyright (C) 2006 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* based on ixdp425.h:
* Copyright 2004 (C) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#define DSMG600_SDA_PIN 5
#define DSMG600_SCL_PIN 4
/*
* DSMG600 PCI IRQs
*/
#define DSMG600_PCI_MAX_DEV 4
#define DSMG600_PCI_IRQ_LINES 3
/* PCI controller GPIO to IRQ pin mappings */
#define DSMG600_PCI_INTA_PIN 11
#define DSMG600_PCI_INTB_PIN 10
#define DSMG600_PCI_INTC_PIN 9
#define DSMG600_PCI_INTD_PIN 8
#define DSMG600_PCI_INTE_PIN 7
#define DSMG600_PCI_INTF_PIN 6
/* DSM-G600 Timer Setting */
#define DSMG600_FREQ 66000000
/* Buttons */
#define DSMG600_PB_GPIO 15 /* power button */
#define DSMG600_RB_GPIO 3 /* reset button */
/* Power control */
#define DSMG600_PO_GPIO 2 /* power off */
/* LEDs */
#define DSMG600_LED_PWR_GPIO 0
#define DSMG600_LED_WLAN_GPIO 14

View File

@@ -0,0 +1,47 @@
/*
* arch/arm/mach-ixp4xx/include/mach/entry-macro.S
*
* Low-level IRQ helper macros for IXP4xx-based platforms
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <mach/hardware.h>
.macro disable_fiq
.endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
ldr \irqstat, [\irqstat] @ get interrupts
cmp \irqstat, #0
beq 1001f @ upper IRQ?
clz \irqnr, \irqstat
mov \base, #31
sub \irqnr, \base, \irqnr
b 1002f @ lower IRQ being
@ handled
1001:
/*
* IXP465/IXP435 has an upper IRQ status register
*/
#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X)
ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP2_OFFSET)
ldr \irqstat, [\irqstat] @ get upper interrupts
mov \irqnr, #63
clz \irqstat, \irqstat
cmp \irqstat, #32
subne \irqnr, \irqnr, \irqstat
#endif
1002:
.endm

View File

@@ -0,0 +1,50 @@
/*
* arch/arm/mach-ixp4xx/include/mach/fsg.h
*
* Freecom FSG-3 platform specific definitions
*
* Author: Rod Whitby <rod@whitby.id.au>
* Author: Tomasz Chmielewski <mangoo@wpkg.org>
* Maintainers: http://www.nslu2-linux.org
*
* Based on coyote.h by
* Copyright 2004 (c) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#define FSG_SDA_PIN 12
#define FSG_SCL_PIN 13
/*
* FSG PCI IRQs
*/
#define FSG_PCI_MAX_DEV 3
#define FSG_PCI_IRQ_LINES 3
/* PCI controller GPIO to IRQ pin mappings */
#define FSG_PCI_INTA_PIN 6
#define FSG_PCI_INTB_PIN 7
#define FSG_PCI_INTC_PIN 5
/* Buttons */
#define FSG_SB_GPIO 4 /* sync button */
#define FSG_RB_GPIO 9 /* reset button */
#define FSG_UB_GPIO 10 /* usb button */
/* LEDs */
#define FSG_LED_WLAN_BIT 0
#define FSG_LED_WAN_BIT 1
#define FSG_LED_SATA_BIT 2
#define FSG_LED_USB_BIT 4
#define FSG_LED_RING_BIT 5
#define FSG_LED_SYNC_BIT 7

View File

@@ -0,0 +1,76 @@
/*
* arch/arm/mach-ixp4xx/include/mach/gpio.h
*
* IXP4XX GPIO wrappers for arch-neutral GPIO calls
*
* Written by Milan Svoboda <msvoboda@ra.rockwell.com>
* Based on PXA implementation by Philipp Zabel <philipp.zabel@gmail.com>
*
* 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
*
*/
#ifndef __ASM_ARCH_IXP4XX_GPIO_H
#define __ASM_ARCH_IXP4XX_GPIO_H
#include <linux/kernel.h>
#include <mach/hardware.h>
static inline int gpio_request(unsigned gpio, const char *label)
{
return 0;
}
static inline void gpio_free(unsigned gpio)
{
might_sleep();
return;
}
static inline int gpio_direction_input(unsigned gpio)
{
gpio_line_config(gpio, IXP4XX_GPIO_IN);
return 0;
}
static inline int gpio_direction_output(unsigned gpio, int level)
{
gpio_line_set(gpio, level);
gpio_line_config(gpio, IXP4XX_GPIO_OUT);
return 0;
}
static inline int gpio_get_value(unsigned gpio)
{
int value;
gpio_line_get(gpio, &value);
return value;
}
static inline void gpio_set_value(unsigned gpio, int value)
{
gpio_line_set(gpio, value);
}
#include <asm-generic/gpio.h> /* cansleep wrappers */
extern int gpio_to_irq(int gpio);
extern int irq_to_gpio(int gpio);
#endif

View File

@@ -0,0 +1,116 @@
/*
* arch/arm/mach-ixp4xx/include/mach/gtwx5715.h
*
* Gemtek GTWX5715 Gateway (Linksys WRV54G)
*
* Copyright 2004 (c) George T. Joseph
*
* 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.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#include "irqs.h"
#define GTWX5715_GPIO0 0
#define GTWX5715_GPIO1 1
#define GTWX5715_GPIO2 2
#define GTWX5715_GPIO3 3
#define GTWX5715_GPIO4 4
#define GTWX5715_GPIO5 5
#define GTWX5715_GPIO6 6
#define GTWX5715_GPIO7 7
#define GTWX5715_GPIO8 8
#define GTWX5715_GPIO9 9
#define GTWX5715_GPIO10 10
#define GTWX5715_GPIO11 11
#define GTWX5715_GPIO12 12
#define GTWX5715_GPIO13 13
#define GTWX5715_GPIO14 14
#define GTWX5715_GPIO0_IRQ IRQ_IXP4XX_GPIO0
#define GTWX5715_GPIO1_IRQ IRQ_IXP4XX_GPIO1
#define GTWX5715_GPIO2_IRQ IRQ_IXP4XX_GPIO2
#define GTWX5715_GPIO3_IRQ IRQ_IXP4XX_GPIO3
#define GTWX5715_GPIO4_IRQ IRQ_IXP4XX_GPIO4
#define GTWX5715_GPIO5_IRQ IRQ_IXP4XX_GPIO5
#define GTWX5715_GPIO6_IRQ IRQ_IXP4XX_GPIO6
#define GTWX5715_GPIO7_IRQ IRQ_IXP4XX_GPIO7
#define GTWX5715_GPIO8_IRQ IRQ_IXP4XX_GPIO8
#define GTWX5715_GPIO9_IRQ IRQ_IXP4XX_GPIO9
#define GTWX5715_GPIO10_IRQ IRQ_IXP4XX_GPIO10
#define GTWX5715_GPIO11_IRQ IRQ_IXP4XX_GPIO11
#define GTWX5715_GPIO12_IRQ IRQ_IXP4XX_GPIO12
#define GTWX5715_GPIO13_IRQ IRQ_IXP4XX_SW_INT1
#define GTWX5715_GPIO14_IRQ IRQ_IXP4XX_SW_INT2
/* PCI controller GPIO to IRQ pin mappings
INTA INTB
SLOT 0 10 11
SLOT 1 11 10
*/
#define GTWX5715_PCI_SLOT0_DEVID 0
#define GTWX5715_PCI_SLOT0_INTA_GPIO GTWX5715_GPIO10
#define GTWX5715_PCI_SLOT0_INTB_GPIO GTWX5715_GPIO11
#define GTWX5715_PCI_SLOT0_INTA_IRQ GTWX5715_GPIO10_IRQ
#define GTWX5715_PCI_SLOT0_INTB_IRQ GTWX5715_GPIO11_IRQ
#define GTWX5715_PCI_SLOT1_DEVID 1
#define GTWX5715_PCI_SLOT1_INTA_GPIO GTWX5715_GPIO11
#define GTWX5715_PCI_SLOT1_INTB_GPIO GTWX5715_GPIO10
#define GTWX5715_PCI_SLOT1_INTA_IRQ GTWX5715_GPIO11_IRQ
#define GTWX5715_PCI_SLOT1_INTB_IRQ GTWX5715_GPIO10_IRQ
#define GTWX5715_PCI_SLOT_COUNT 2
#define GTWX5715_PCI_INT_PIN_COUNT 2
/*
* GPIO 5,6,7 and12 are hard wired to the Kendin KS8995M Switch
* and operate as an SPI type interface. The details of the interface
* are available on Kendin/Micrel's web site.
*/
#define GTWX5715_KSSPI_SELECT GTWX5715_GPIO5
#define GTWX5715_KSSPI_TXD GTWX5715_GPIO6
#define GTWX5715_KSSPI_CLOCK GTWX5715_GPIO7
#define GTWX5715_KSSPI_RXD GTWX5715_GPIO12
/*
* The "reset" button is wired to GPIO 3.
* The GPIO is brought "low" when the button is pushed.
*/
#define GTWX5715_BUTTON_GPIO GTWX5715_GPIO3
#define GTWX5715_BUTTON_IRQ GTWX5715_GPIO3_IRQ
/*
* Board Label Front Label
* LED1 Power
* LED2 Wireless-G
* LED3 not populated but could be
* LED4 Internet
* LED5 - LED8 Controlled by KS8995M Switch
* LED9 DMZ
*/
#define GTWX5715_LED1_GPIO GTWX5715_GPIO2
#define GTWX5715_LED2_GPIO GTWX5715_GPIO9
#define GTWX5715_LED3_GPIO GTWX5715_GPIO8
#define GTWX5715_LED4_GPIO GTWX5715_GPIO1
#define GTWX5715_LED9_GPIO GTWX5715_GPIO4

View File

@@ -0,0 +1,50 @@
/*
* arch/arm/mach-ixp4xx/include/mach/hardware.h
*
* 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.
*
*/
/*
* Hardware definitions for IXP4xx based systems
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#define __ASM_ARCH_HARDWARE_H__
#define PCIBIOS_MIN_IO 0x00001000
#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x40000000 : 0x48000000)
/*
* We override the standard dma-mask routines for bouncing.
*/
#define HAVE_ARCH_PCI_SET_DMA_MASK
#define pcibios_assign_all_busses() 1
/* Register locations and bits */
#include "ixp4xx-regs.h"
#ifndef __ASSEMBLER__
#include <mach/cpu.h>
#endif
/* Platform helper functions and definitions */
#include "platform.h"
/* Platform specific details */
#include "ixdp425.h"
#include "avila.h"
#include "coyote.h"
#include "prpmc1100.h"
#include "nslu2.h"
#include "nas100d.h"
#include "dsmg600.h"
#include "fsg.h"
#endif /* _ASM_ARCH_HARDWARE_H */

View File

@@ -0,0 +1,567 @@
/*
* arch/arm/mach-ixp4xx/include/mach/io.h
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002-2005 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.
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#include <linux/bitops.h>
#include <mach/hardware.h>
#define IO_SPACE_LIMIT 0x0000ffff
extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
/*
* IXP4xx provides two methods of accessing PCI memory space:
*
* 1) A direct mapped window from 0x48000000 to 0x4bffffff (64MB).
* To access PCI via this space, we simply ioremap() the BAR
* into the kernel and we can use the standard read[bwl]/write[bwl]
* macros. This is the preffered method due to speed but it
* limits the system to just 64MB of PCI memory. This can be
* problamatic if using video cards and other memory-heavy
* targets.
*
* 2) If > 64MB of memory space is required, the IXP4xx can be configured
* to use indirect registers to access PCI (as we do below for I/O
* transactions). This allows for up to 128MB (0x48000000 to 0x4fffffff)
* of memory on the bus. The disadvantage of this is that every
* PCI access requires three local register accesses plus a spinlock,
* but in some cases the performance hit is acceptable. In addition,
* you cannot mmap() PCI devices in this case.
*
*/
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
#define __mem_pci(a) (a)
#else
/*
* In the case of using indirect PCI, we simply return the actual PCI
* address and our read/write implementation use that to drive the
* access registers. If something outside of PCI is ioremap'd, we
* fallback to the default.
*/
static inline void __iomem *
__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned int mtype)
{
if((addr < PCIBIOS_MIN_MEM) || (addr > 0x4fffffff))
return __arm_ioremap(addr, size, mtype);
return (void __iomem *)addr;
}
static inline void
__ixp4xx_iounmap(void __iomem *addr)
{
if ((__force u32)addr >= VMALLOC_START)
__iounmap(addr);
}
#define __arch_ioremap(a, s, f) __ixp4xx_ioremap(a, s, f)
#define __arch_iounmap(a) __ixp4xx_iounmap(a)
#define writeb(v, p) __ixp4xx_writeb(v, p)
#define writew(v, p) __ixp4xx_writew(v, p)
#define writel(v, p) __ixp4xx_writel(v, p)
#define writesb(p, v, l) __ixp4xx_writesb(p, v, l)
#define writesw(p, v, l) __ixp4xx_writesw(p, v, l)
#define writesl(p, v, l) __ixp4xx_writesl(p, v, l)
#define readb(p) __ixp4xx_readb(p)
#define readw(p) __ixp4xx_readw(p)
#define readl(p) __ixp4xx_readl(p)
#define readsb(p, v, l) __ixp4xx_readsb(p, v, l)
#define readsw(p, v, l) __ixp4xx_readsw(p, v, l)
#define readsl(p, v, l) __ixp4xx_readsl(p, v, l)
static inline void
__ixp4xx_writeb(u8 value, volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
if (addr >= VMALLOC_START) {
__raw_writeb(value, addr);
return;
}
n = addr % 4;
byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
data = value << (8*n);
ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
}
static inline void
__ixp4xx_writesb(volatile void __iomem *bus_addr, const u8 *vaddr, int count)
{
while (count--)
writeb(*vaddr++, bus_addr);
}
static inline void
__ixp4xx_writew(u16 value, volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
if (addr >= VMALLOC_START) {
__raw_writew(value, addr);
return;
}
n = addr % 4;
byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
data = value << (8*n);
ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
}
static inline void
__ixp4xx_writesw(volatile void __iomem *bus_addr, const u16 *vaddr, int count)
{
while (count--)
writew(*vaddr++, bus_addr);
}
static inline void
__ixp4xx_writel(u32 value, volatile void __iomem *p)
{
u32 addr = (__force u32)p;
if (addr >= VMALLOC_START) {
__raw_writel(value, p);
return;
}
ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
}
static inline void
__ixp4xx_writesl(volatile void __iomem *bus_addr, const u32 *vaddr, int count)
{
while (count--)
writel(*vaddr++, bus_addr);
}
static inline unsigned char
__ixp4xx_readb(const volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
if (addr >= VMALLOC_START)
return __raw_readb(addr);
n = addr % 4;
byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
return 0xff;
return data >> (8*n);
}
static inline void
__ixp4xx_readsb(const volatile void __iomem *bus_addr, u8 *vaddr, u32 count)
{
while (count--)
*vaddr++ = readb(bus_addr);
}
static inline unsigned short
__ixp4xx_readw(const volatile void __iomem *p)
{
u32 addr = (u32)p;
u32 n, byte_enables, data;
if (addr >= VMALLOC_START)
return __raw_readw(addr);
n = addr % 4;
byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
return 0xffff;
return data>>(8*n);
}
static inline void
__ixp4xx_readsw(const volatile void __iomem *bus_addr, u16 *vaddr, u32 count)
{
while (count--)
*vaddr++ = readw(bus_addr);
}
static inline unsigned long
__ixp4xx_readl(const volatile void __iomem *p)
{
u32 addr = (__force u32)p;
u32 data;
if (addr >= VMALLOC_START)
return __raw_readl(p);
if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
return 0xffffffff;
return data;
}
static inline void
__ixp4xx_readsl(const volatile void __iomem *bus_addr, u32 *vaddr, u32 count)
{
while (count--)
*vaddr++ = readl(bus_addr);
}
/*
* We can use the built-in functions b/c they end up calling writeb/readb
*/
#define memset_io(c,v,l) _memset_io((c),(v),(l))
#define memcpy_fromio(a,c,l) _memcpy_fromio((a),(c),(l))
#define memcpy_toio(c,a,l) _memcpy_toio((c),(a),(l))
#endif
#ifndef CONFIG_PCI
#define __io(v) __typesafe_io(v)
#else
/*
* IXP4xx does not have a transparent cpu -> PCI I/O translation
* window. Instead, it has a set of registers that must be tweaked
* with the proper byte lanes, command types, and address for the
* transaction. This means that we need to override the default
* I/O functions.
*/
#define outb(p, v) __ixp4xx_outb(p, v)
#define outw(p, v) __ixp4xx_outw(p, v)
#define outl(p, v) __ixp4xx_outl(p, v)
#define outsb(p, v, l) __ixp4xx_outsb(p, v, l)
#define outsw(p, v, l) __ixp4xx_outsw(p, v, l)
#define outsl(p, v, l) __ixp4xx_outsl(p, v, l)
#define inb(p) __ixp4xx_inb(p)
#define inw(p) __ixp4xx_inw(p)
#define inl(p) __ixp4xx_inl(p)
#define insb(p, v, l) __ixp4xx_insb(p, v, l)
#define insw(p, v, l) __ixp4xx_insw(p, v, l)
#define insl(p, v, l) __ixp4xx_insl(p, v, l)
static inline void
__ixp4xx_outb(u8 value, u32 addr)
{
u32 n, byte_enables, data;
n = addr % 4;
byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
data = value << (8*n);
ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
}
static inline void
__ixp4xx_outsb(u32 io_addr, const u8 *vaddr, u32 count)
{
while (count--)
outb(*vaddr++, io_addr);
}
static inline void
__ixp4xx_outw(u16 value, u32 addr)
{
u32 n, byte_enables, data;
n = addr % 4;
byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
data = value << (8*n);
ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
}
static inline void
__ixp4xx_outsw(u32 io_addr, const u16 *vaddr, u32 count)
{
while (count--)
outw(cpu_to_le16(*vaddr++), io_addr);
}
static inline void
__ixp4xx_outl(u32 value, u32 addr)
{
ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
}
static inline void
__ixp4xx_outsl(u32 io_addr, const u32 *vaddr, u32 count)
{
while (count--)
outl(*vaddr++, io_addr);
}
static inline u8
__ixp4xx_inb(u32 addr)
{
u32 n, byte_enables, data;
n = addr % 4;
byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
return 0xff;
return data >> (8*n);
}
static inline void
__ixp4xx_insb(u32 io_addr, u8 *vaddr, u32 count)
{
while (count--)
*vaddr++ = inb(io_addr);
}
static inline u16
__ixp4xx_inw(u32 addr)
{
u32 n, byte_enables, data;
n = addr % 4;
byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
return 0xffff;
return data>>(8*n);
}
static inline void
__ixp4xx_insw(u32 io_addr, u16 *vaddr, u32 count)
{
while (count--)
*vaddr++ = le16_to_cpu(inw(io_addr));
}
static inline u32
__ixp4xx_inl(u32 addr)
{
u32 data;
if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
return 0xffffffff;
return data;
}
static inline void
__ixp4xx_insl(u32 io_addr, u32 *vaddr, u32 count)
{
while (count--)
*vaddr++ = inl(io_addr);
}
#define PIO_OFFSET 0x10000UL
#define PIO_MASK 0x0ffffUL
#define __is_io_address(p) (((unsigned long)p >= PIO_OFFSET) && \
((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
static inline unsigned int
__ixp4xx_ioread8(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
return (unsigned int)__ixp4xx_inb(port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return (unsigned int)__raw_readb(port);
#else
return (unsigned int)__ixp4xx_readb(addr);
#endif
}
static inline void
__ixp4xx_ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_insb(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsb(addr, vaddr, count);
#else
__ixp4xx_readsb(addr, vaddr, count);
#endif
}
static inline unsigned int
__ixp4xx_ioread16(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
return (unsigned int)__ixp4xx_inw(port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return le16_to_cpu(__raw_readw((u32)port));
#else
return (unsigned int)__ixp4xx_readw(addr);
#endif
}
static inline void
__ixp4xx_ioread16_rep(const void __iomem *addr, void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_insw(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsw(addr, vaddr, count);
#else
__ixp4xx_readsw(addr, vaddr, count);
#endif
}
static inline unsigned int
__ixp4xx_ioread32(const void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
return (unsigned int)__ixp4xx_inl(port & PIO_MASK);
else {
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
return le32_to_cpu((__force __le32)__raw_readl(addr));
#else
return (unsigned int)__ixp4xx_readl(addr);
#endif
}
}
static inline void
__ixp4xx_ioread32_rep(const void __iomem *addr, void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_insl(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_readsl(addr, vaddr, count);
#else
__ixp4xx_readsl(addr, vaddr, count);
#endif
}
static inline void
__ixp4xx_iowrite8(u8 value, void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_outb(value, port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writeb(value, port);
#else
__ixp4xx_writeb(value, addr);
#endif
}
static inline void
__ixp4xx_iowrite8_rep(void __iomem *addr, const void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_outsb(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesb(addr, vaddr, count);
#else
__ixp4xx_writesb(addr, vaddr, count);
#endif
}
static inline void
__ixp4xx_iowrite16(u16 value, void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_outw(value, port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writew(cpu_to_le16(value), addr);
#else
__ixp4xx_writew(value, addr);
#endif
}
static inline void
__ixp4xx_iowrite16_rep(void __iomem *addr, const void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_outsw(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesw(addr, vaddr, count);
#else
__ixp4xx_writesw(addr, vaddr, count);
#endif
}
static inline void
__ixp4xx_iowrite32(u32 value, void __iomem *addr)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_outl(value, port & PIO_MASK);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writel((u32 __force)cpu_to_le32(value), addr);
#else
__ixp4xx_writel(value, addr);
#endif
}
static inline void
__ixp4xx_iowrite32_rep(void __iomem *addr, const void *vaddr, u32 count)
{
unsigned long port = (unsigned long __force)addr;
if (__is_io_address(port))
__ixp4xx_outsl(port & PIO_MASK, vaddr, count);
else
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
__raw_writesl(addr, vaddr, count);
#else
__ixp4xx_writesl(addr, vaddr, count);
#endif
}
#define ioread8(p) __ixp4xx_ioread8(p)
#define ioread16(p) __ixp4xx_ioread16(p)
#define ioread32(p) __ixp4xx_ioread32(p)
#define ioread8_rep(p, v, c) __ixp4xx_ioread8_rep(p, v, c)
#define ioread16_rep(p, v, c) __ixp4xx_ioread16_rep(p, v, c)
#define ioread32_rep(p, v, c) __ixp4xx_ioread32_rep(p, v, c)
#define iowrite8(v,p) __ixp4xx_iowrite8(v,p)
#define iowrite16(v,p) __ixp4xx_iowrite16(v,p)
#define iowrite32(v,p) __ixp4xx_iowrite32(v,p)
#define iowrite8_rep(p, v, c) __ixp4xx_iowrite8_rep(p, v, c)
#define iowrite16_rep(p, v, c) __ixp4xx_iowrite16_rep(p, v, c)
#define iowrite32_rep(p, v, c) __ixp4xx_iowrite32_rep(p, v, c)
#define ioport_map(port, nr) ((void __iomem*)(port + PIO_OFFSET))
#define ioport_unmap(addr)
#endif // !CONFIG_PCI
#endif // __ASM_ARM_ARCH_IO_H

View File

@@ -0,0 +1,138 @@
/*
* arch/arm/mach-ixp4xx/include/mach/irqs.h
*
* IRQ definitions for IXP4XX based systems
*
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003 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.
*
*/
#ifndef _ARCH_IXP4XX_IRQS_H_
#define _ARCH_IXP4XX_IRQS_H_
#define IRQ_IXP4XX_NPEA 0
#define IRQ_IXP4XX_NPEB 1
#define IRQ_IXP4XX_NPEC 2
#define IRQ_IXP4XX_QM1 3
#define IRQ_IXP4XX_QM2 4
#define IRQ_IXP4XX_TIMER1 5
#define IRQ_IXP4XX_GPIO0 6
#define IRQ_IXP4XX_GPIO1 7
#define IRQ_IXP4XX_PCI_INT 8
#define IRQ_IXP4XX_PCI_DMA1 9
#define IRQ_IXP4XX_PCI_DMA2 10
#define IRQ_IXP4XX_TIMER2 11
#define IRQ_IXP4XX_USB 12
#define IRQ_IXP4XX_UART2 13
#define IRQ_IXP4XX_TIMESTAMP 14
#define IRQ_IXP4XX_UART1 15
#define IRQ_IXP4XX_WDOG 16
#define IRQ_IXP4XX_AHB_PMU 17
#define IRQ_IXP4XX_XSCALE_PMU 18
#define IRQ_IXP4XX_GPIO2 19
#define IRQ_IXP4XX_GPIO3 20
#define IRQ_IXP4XX_GPIO4 21
#define IRQ_IXP4XX_GPIO5 22
#define IRQ_IXP4XX_GPIO6 23
#define IRQ_IXP4XX_GPIO7 24
#define IRQ_IXP4XX_GPIO8 25
#define IRQ_IXP4XX_GPIO9 26
#define IRQ_IXP4XX_GPIO10 27
#define IRQ_IXP4XX_GPIO11 28
#define IRQ_IXP4XX_GPIO12 29
#define IRQ_IXP4XX_SW_INT1 30
#define IRQ_IXP4XX_SW_INT2 31
#define IRQ_IXP4XX_USB_HOST 32
#define IRQ_IXP4XX_I2C 33
#define IRQ_IXP4XX_SSP 34
#define IRQ_IXP4XX_TSYNC 35
#define IRQ_IXP4XX_EAU_DONE 36
#define IRQ_IXP4XX_SHA_DONE 37
#define IRQ_IXP4XX_SWCP_PE 58
#define IRQ_IXP4XX_QM_PE 60
#define IRQ_IXP4XX_MCU_ECC 61
#define IRQ_IXP4XX_EXP_PE 62
/*
* Only first 32 sources are valid if running on IXP42x systems
*/
#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X)
#define NR_IRQS 64
#else
#define NR_IRQS 32
#endif
#define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU)
/*
* IXDP425 board IRQs
*/
#define IRQ_IXDP425_PCI_INTA IRQ_IXP4XX_GPIO11
#define IRQ_IXDP425_PCI_INTB IRQ_IXP4XX_GPIO10
#define IRQ_IXDP425_PCI_INTC IRQ_IXP4XX_GPIO9
#define IRQ_IXDP425_PCI_INTD IRQ_IXP4XX_GPIO8
/*
* Gateworks Avila board IRQs
*/
#define IRQ_AVILA_PCI_INTA IRQ_IXP4XX_GPIO11
#define IRQ_AVILA_PCI_INTB IRQ_IXP4XX_GPIO10
#define IRQ_AVILA_PCI_INTC IRQ_IXP4XX_GPIO9
#define IRQ_AVILA_PCI_INTD IRQ_IXP4XX_GPIO8
/*
* PrPMC1100 Board IRQs
*/
#define IRQ_PRPMC1100_PCI_INTA IRQ_IXP4XX_GPIO11
#define IRQ_PRPMC1100_PCI_INTB IRQ_IXP4XX_GPIO10
#define IRQ_PRPMC1100_PCI_INTC IRQ_IXP4XX_GPIO9
#define IRQ_PRPMC1100_PCI_INTD IRQ_IXP4XX_GPIO8
/*
* ADI Coyote Board IRQs
*/
#define IRQ_COYOTE_PCI_SLOT0 IRQ_IXP4XX_GPIO6
#define IRQ_COYOTE_PCI_SLOT1 IRQ_IXP4XX_GPIO11
#define IRQ_COYOTE_IDE IRQ_IXP4XX_GPIO5
/*
* NSLU2 board IRQs
*/
#define IRQ_NSLU2_PCI_INTA IRQ_IXP4XX_GPIO11
#define IRQ_NSLU2_PCI_INTB IRQ_IXP4XX_GPIO10
#define IRQ_NSLU2_PCI_INTC IRQ_IXP4XX_GPIO9
/*
* NAS100D board IRQs
*/
#define IRQ_NAS100D_PCI_INTA IRQ_IXP4XX_GPIO11
#define IRQ_NAS100D_PCI_INTB IRQ_IXP4XX_GPIO10
#define IRQ_NAS100D_PCI_INTC IRQ_IXP4XX_GPIO9
#define IRQ_NAS100D_PCI_INTD IRQ_IXP4XX_GPIO8
#define IRQ_NAS100D_PCI_INTE IRQ_IXP4XX_GPIO7
/*
* D-Link DSM-G600 RevA board IRQs
*/
#define IRQ_DSMG600_PCI_INTA IRQ_IXP4XX_GPIO11
#define IRQ_DSMG600_PCI_INTB IRQ_IXP4XX_GPIO10
#define IRQ_DSMG600_PCI_INTC IRQ_IXP4XX_GPIO9
#define IRQ_DSMG600_PCI_INTD IRQ_IXP4XX_GPIO8
#define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7
#define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6
/*
* Freecom FSG-3 Board IRQs
*/
#define IRQ_FSG_PCI_INTA IRQ_IXP4XX_GPIO6
#define IRQ_FSG_PCI_INTB IRQ_IXP4XX_GPIO7
#define IRQ_FSG_PCI_INTC IRQ_IXP4XX_GPIO5
#endif

View File

@@ -0,0 +1,39 @@
/*
* arch/arm/mach-ixp4xx/include/mach/ixdp425.h
*
* IXDP425 platform specific definitions
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2004 (c) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#define IXDP425_SDA_PIN 7
#define IXDP425_SCL_PIN 6
/*
* IXDP425 PCI IRQs
*/
#define IXDP425_PCI_MAX_DEV 4
#define IXDP425_PCI_IRQ_LINES 4
/* PCI controller GPIO to IRQ pin mappings */
#define IXDP425_PCI_INTA_PIN 11
#define IXDP425_PCI_INTB_PIN 10
#define IXDP425_PCI_INTC_PIN 9
#define IXDP425_PCI_INTD_PIN 8
/* NAND Flash pins */
#define IXDP425_NAND_NCE_PIN 12
#define IXDP425_NAND_CMD_BYTE 0x01
#define IXDP425_NAND_ADDR_BYTE 0x02

View File

@@ -0,0 +1,660 @@
/*
* arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
*
* Register definitions for IXP4xx chipset. This file contains
* register location and bit definitions only. Platform specific
* definitions and helper function declarations are in platform.h
* and machine-name.h.
*
* 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.
*
*/
#ifndef _ASM_ARM_IXP4XX_H_
#define _ASM_ARM_IXP4XX_H_
/*
* IXP4xx Linux Memory Map:
*
* Phy Size Virt Description
* =========================================================================
*
* 0x00000000 0x10000000(max) PAGE_OFFSET System RAM
*
* 0x48000000 0x04000000 ioremap'd PCI Memory Space
*
* 0x50000000 0x10000000 ioremap'd EXP BUS
*
* 0x6000000 0x00004000 ioremap'd QMgr
*
* 0xC0000000 0x00001000 0xffbff000 PCI CFG
*
* 0xC4000000 0x00001000 0xffbfe000 EXP CFG
*
* 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals
*/
/*
* Queue Manager
*/
#define IXP4XX_QMGR_BASE_PHYS (0x60000000)
#define IXP4XX_QMGR_REGION_SIZE (0x00004000)
/*
* Expansion BUS Configuration registers
*/
#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000)
#define IXP4XX_EXP_CFG_BASE_VIRT (0xFFBFE000)
#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000)
/*
* PCI Config registers
*/
#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000)
#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFF000)
#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000)
/*
* Peripheral space
*/
#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000)
#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBEB000)
#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
/*
* Debug UART
*
* This is basically a remap of UART1 into a region that is section
* aligned so that it * can be used with the low-level debug code.
*/
#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000)
#define IXP4XX_DEBUG_UART_BASE_VIRT (0xffb00000)
#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
#define IXP4XX_EXP_CS0_OFFSET 0x00
#define IXP4XX_EXP_CS1_OFFSET 0x04
#define IXP4XX_EXP_CS2_OFFSET 0x08
#define IXP4XX_EXP_CS3_OFFSET 0x0C
#define IXP4XX_EXP_CS4_OFFSET 0x10
#define IXP4XX_EXP_CS5_OFFSET 0x14
#define IXP4XX_EXP_CS6_OFFSET 0x18
#define IXP4XX_EXP_CS7_OFFSET 0x1C
#define IXP4XX_EXP_CFG0_OFFSET 0x20
#define IXP4XX_EXP_CFG1_OFFSET 0x24
#define IXP4XX_EXP_CFG2_OFFSET 0x28
#define IXP4XX_EXP_CFG3_OFFSET 0x2C
/*
* Expansion Bus Controller registers.
*/
#define IXP4XX_EXP_REG(x) ((volatile u32 *)(IXP4XX_EXP_CFG_BASE_VIRT+(x)))
#define IXP4XX_EXP_CS0 IXP4XX_EXP_REG(IXP4XX_EXP_CS0_OFFSET)
#define IXP4XX_EXP_CS1 IXP4XX_EXP_REG(IXP4XX_EXP_CS1_OFFSET)
#define IXP4XX_EXP_CS2 IXP4XX_EXP_REG(IXP4XX_EXP_CS2_OFFSET)
#define IXP4XX_EXP_CS3 IXP4XX_EXP_REG(IXP4XX_EXP_CS3_OFFSET)
#define IXP4XX_EXP_CS4 IXP4XX_EXP_REG(IXP4XX_EXP_CS4_OFFSET)
#define IXP4XX_EXP_CS5 IXP4XX_EXP_REG(IXP4XX_EXP_CS5_OFFSET)
#define IXP4XX_EXP_CS6 IXP4XX_EXP_REG(IXP4XX_EXP_CS6_OFFSET)
#define IXP4XX_EXP_CS7 IXP4XX_EXP_REG(IXP4XX_EXP_CS7_OFFSET)
#define IXP4XX_EXP_CFG0 IXP4XX_EXP_REG(IXP4XX_EXP_CFG0_OFFSET)
#define IXP4XX_EXP_CFG1 IXP4XX_EXP_REG(IXP4XX_EXP_CFG1_OFFSET)
#define IXP4XX_EXP_CFG2 IXP4XX_EXP_REG(IXP4XX_EXP_CFG2_OFFSET)
#define IXP4XX_EXP_CFG3 IXP4XX_EXP_REG(IXP4XX_EXP_CFG3_OFFSET)
/*
* Peripheral Space Register Region Base Addresses
*/
#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
#define IXP4XX_NPEA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
#define IXP4XX_NPEB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
#define IXP4XX_NPEC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
#define IXP4XX_EthC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
/* ixp46X only */
#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
#define IXP4XX_EthB1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
#define IXP4XX_EthB2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
#define IXP4XX_EthB3_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
#define IXP4XX_TIMESYNC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
#define IXP4XX_I2C_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
#define IXP4XX_NPEA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x6000)
#define IXP4XX_NPEB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x7000)
#define IXP4XX_NPEC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x8000)
#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
#define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
/* ixp46X only */
#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
#define IXP4XX_EthB1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
#define IXP4XX_EthB2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
#define IXP4XX_EthB3_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
#define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
#define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
#define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
/*
* Constants to make it easy to access Interrupt Controller registers
*/
#define IXP4XX_ICPR_OFFSET 0x00 /* Interrupt Status */
#define IXP4XX_ICMR_OFFSET 0x04 /* Interrupt Enable */
#define IXP4XX_ICLR_OFFSET 0x08 /* Interrupt IRQ/FIQ Select */
#define IXP4XX_ICIP_OFFSET 0x0C /* IRQ Status */
#define IXP4XX_ICFP_OFFSET 0x10 /* FIQ Status */
#define IXP4XX_ICHR_OFFSET 0x14 /* Interrupt Priority */
#define IXP4XX_ICIH_OFFSET 0x18 /* IRQ Highest Pri Int */
#define IXP4XX_ICFH_OFFSET 0x1C /* FIQ Highest Pri Int */
/*
* IXP465-only
*/
#define IXP4XX_ICPR2_OFFSET 0x20 /* Interrupt Status 2 */
#define IXP4XX_ICMR2_OFFSET 0x24 /* Interrupt Enable 2 */
#define IXP4XX_ICLR2_OFFSET 0x28 /* Interrupt IRQ/FIQ Select 2 */
#define IXP4XX_ICIP2_OFFSET 0x2C /* IRQ Status */
#define IXP4XX_ICFP2_OFFSET 0x30 /* FIQ Status */
#define IXP4XX_ICEEN_OFFSET 0x34 /* Error High Pri Enable */
/*
* Interrupt Controller Register Definitions.
*/
#define IXP4XX_INTC_REG(x) ((volatile u32 *)(IXP4XX_INTC_BASE_VIRT+(x)))
#define IXP4XX_ICPR IXP4XX_INTC_REG(IXP4XX_ICPR_OFFSET)
#define IXP4XX_ICMR IXP4XX_INTC_REG(IXP4XX_ICMR_OFFSET)
#define IXP4XX_ICLR IXP4XX_INTC_REG(IXP4XX_ICLR_OFFSET)
#define IXP4XX_ICIP IXP4XX_INTC_REG(IXP4XX_ICIP_OFFSET)
#define IXP4XX_ICFP IXP4XX_INTC_REG(IXP4XX_ICFP_OFFSET)
#define IXP4XX_ICHR IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET)
#define IXP4XX_ICIH IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET)
#define IXP4XX_ICFH IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET)
#define IXP4XX_ICPR2 IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET)
#define IXP4XX_ICMR2 IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET)
#define IXP4XX_ICLR2 IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET)
#define IXP4XX_ICIP2 IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET)
#define IXP4XX_ICFP2 IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET)
#define IXP4XX_ICEEN IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET)
/*
* Constants to make it easy to access GPIO registers
*/
#define IXP4XX_GPIO_GPOUTR_OFFSET 0x00
#define IXP4XX_GPIO_GPOER_OFFSET 0x04
#define IXP4XX_GPIO_GPINR_OFFSET 0x08
#define IXP4XX_GPIO_GPISR_OFFSET 0x0C
#define IXP4XX_GPIO_GPIT1R_OFFSET 0x10
#define IXP4XX_GPIO_GPIT2R_OFFSET 0x14
#define IXP4XX_GPIO_GPCLKR_OFFSET 0x18
#define IXP4XX_GPIO_GPDBSELR_OFFSET 0x1C
/*
* GPIO Register Definitions.
* [Only perform 32bit reads/writes]
*/
#define IXP4XX_GPIO_REG(x) ((volatile u32 *)(IXP4XX_GPIO_BASE_VIRT+(x)))
#define IXP4XX_GPIO_GPOUTR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOUTR_OFFSET)
#define IXP4XX_GPIO_GPOER IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOER_OFFSET)
#define IXP4XX_GPIO_GPINR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPINR_OFFSET)
#define IXP4XX_GPIO_GPISR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPISR_OFFSET)
#define IXP4XX_GPIO_GPIT1R IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT1R_OFFSET)
#define IXP4XX_GPIO_GPIT2R IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT2R_OFFSET)
#define IXP4XX_GPIO_GPCLKR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPCLKR_OFFSET)
#define IXP4XX_GPIO_GPDBSELR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPDBSELR_OFFSET)
/*
* GPIO register bit definitions
*/
/* Interrupt styles
*/
#define IXP4XX_GPIO_STYLE_ACTIVE_HIGH 0x0
#define IXP4XX_GPIO_STYLE_ACTIVE_LOW 0x1
#define IXP4XX_GPIO_STYLE_RISING_EDGE 0x2
#define IXP4XX_GPIO_STYLE_FALLING_EDGE 0x3
#define IXP4XX_GPIO_STYLE_TRANSITIONAL 0x4
/*
* Mask used to clear interrupt styles
*/
#define IXP4XX_GPIO_STYLE_CLEAR 0x7
#define IXP4XX_GPIO_STYLE_SIZE 3
/*
* Constants to make it easy to access Timer Control/Status registers
*/
#define IXP4XX_OSTS_OFFSET 0x00 /* Continious TimeStamp */
#define IXP4XX_OST1_OFFSET 0x04 /* Timer 1 Timestamp */
#define IXP4XX_OSRT1_OFFSET 0x08 /* Timer 1 Reload */
#define IXP4XX_OST2_OFFSET 0x0C /* Timer 2 Timestamp */
#define IXP4XX_OSRT2_OFFSET 0x10 /* Timer 2 Reload */
#define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */
#define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */
#define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */
#define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */
/*
* Operating System Timer Register Definitions.
*/
#define IXP4XX_TIMER_REG(x) ((volatile u32 *)(IXP4XX_TIMER_BASE_VIRT+(x)))
#define IXP4XX_OSTS IXP4XX_TIMER_REG(IXP4XX_OSTS_OFFSET)
#define IXP4XX_OST1 IXP4XX_TIMER_REG(IXP4XX_OST1_OFFSET)
#define IXP4XX_OSRT1 IXP4XX_TIMER_REG(IXP4XX_OSRT1_OFFSET)
#define IXP4XX_OST2 IXP4XX_TIMER_REG(IXP4XX_OST2_OFFSET)
#define IXP4XX_OSRT2 IXP4XX_TIMER_REG(IXP4XX_OSRT2_OFFSET)
#define IXP4XX_OSWT IXP4XX_TIMER_REG(IXP4XX_OSWT_OFFSET)
#define IXP4XX_OSWE IXP4XX_TIMER_REG(IXP4XX_OSWE_OFFSET)
#define IXP4XX_OSWK IXP4XX_TIMER_REG(IXP4XX_OSWK_OFFSET)
#define IXP4XX_OSST IXP4XX_TIMER_REG(IXP4XX_OSST_OFFSET)
/*
* Timer register values and bit definitions
*/
#define IXP4XX_OST_ENABLE 0x00000001
#define IXP4XX_OST_ONE_SHOT 0x00000002
/* Low order bits of reload value ignored */
#define IXP4XX_OST_RELOAD_MASK 0x00000003
#define IXP4XX_OST_DISABLED 0x00000000
#define IXP4XX_OSST_TIMER_1_PEND 0x00000001
#define IXP4XX_OSST_TIMER_2_PEND 0x00000002
#define IXP4XX_OSST_TIMER_TS_PEND 0x00000004
#define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008
#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
#define IXP4XX_WDT_KEY 0x0000482E
#define IXP4XX_WDT_RESET_ENABLE 0x00000001
#define IXP4XX_WDT_IRQ_ENABLE 0x00000002
#define IXP4XX_WDT_COUNT_ENABLE 0x00000004
/*
* Constants to make it easy to access PCI Control/Status registers
*/
#define PCI_NP_AD_OFFSET 0x00
#define PCI_NP_CBE_OFFSET 0x04
#define PCI_NP_WDATA_OFFSET 0x08
#define PCI_NP_RDATA_OFFSET 0x0c
#define PCI_CRP_AD_CBE_OFFSET 0x10
#define PCI_CRP_WDATA_OFFSET 0x14
#define PCI_CRP_RDATA_OFFSET 0x18
#define PCI_CSR_OFFSET 0x1c
#define PCI_ISR_OFFSET 0x20
#define PCI_INTEN_OFFSET 0x24
#define PCI_DMACTRL_OFFSET 0x28
#define PCI_AHBMEMBASE_OFFSET 0x2c
#define PCI_AHBIOBASE_OFFSET 0x30
#define PCI_PCIMEMBASE_OFFSET 0x34
#define PCI_AHBDOORBELL_OFFSET 0x38
#define PCI_PCIDOORBELL_OFFSET 0x3C
#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
/*
* PCI Control/Status Registers
*/
#define IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE_VIRT+(x)))
#define PCI_NP_AD IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
#define PCI_NP_CBE IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
#define PCI_NP_WDATA IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
#define PCI_NP_RDATA IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
#define PCI_CRP_AD_CBE IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
#define PCI_CRP_WDATA IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
#define PCI_CRP_RDATA IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
#define PCI_CSR IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
#define PCI_ISR IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
#define PCI_INTEN IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
#define PCI_DMACTRL IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
#define PCI_AHBMEMBASE IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
#define PCI_AHBIOBASE IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
#define PCI_PCIMEMBASE IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
#define PCI_AHBDOORBELL IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
#define PCI_PCIDOORBELL IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
#define PCI_ATPDMA0_AHBADDR IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
#define PCI_ATPDMA0_PCIADDR IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
#define PCI_ATPDMA0_LENADDR IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
#define PCI_ATPDMA1_AHBADDR IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
#define PCI_ATPDMA1_PCIADDR IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
#define PCI_ATPDMA1_LENADDR IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
/*
* PCI register values and bit definitions
*/
/* CSR bit definitions */
#define PCI_CSR_HOST 0x00000001
#define PCI_CSR_ARBEN 0x00000002
#define PCI_CSR_ADS 0x00000004
#define PCI_CSR_PDS 0x00000008
#define PCI_CSR_ABE 0x00000010
#define PCI_CSR_DBT 0x00000020
#define PCI_CSR_ASE 0x00000100
#define PCI_CSR_IC 0x00008000
/* ISR (Interrupt status) Register bit definitions */
#define PCI_ISR_PSE 0x00000001
#define PCI_ISR_PFE 0x00000002
#define PCI_ISR_PPE 0x00000004
#define PCI_ISR_AHBE 0x00000008
#define PCI_ISR_APDC 0x00000010
#define PCI_ISR_PADC 0x00000020
#define PCI_ISR_ADB 0x00000040
#define PCI_ISR_PDB 0x00000080
/* INTEN (Interrupt Enable) Register bit definitions */
#define PCI_INTEN_PSE 0x00000001
#define PCI_INTEN_PFE 0x00000002
#define PCI_INTEN_PPE 0x00000004
#define PCI_INTEN_AHBE 0x00000008
#define PCI_INTEN_APDC 0x00000010
#define PCI_INTEN_PADC 0x00000020
#define PCI_INTEN_ADB 0x00000040
#define PCI_INTEN_PDB 0x00000080
/*
* Shift value for byte enable on NP cmd/byte enable register
*/
#define IXP4XX_PCI_NP_CBE_BESL 4
/*
* PCI commands supported by NP access unit
*/
#define NP_CMD_IOREAD 0x2
#define NP_CMD_IOWRITE 0x3
#define NP_CMD_CONFIGREAD 0xa
#define NP_CMD_CONFIGWRITE 0xb
#define NP_CMD_MEMREAD 0x6
#define NP_CMD_MEMWRITE 0x7
/*
* Constants for CRP access into local config space
*/
#define CRP_AD_CBE_BESL 20
#define CRP_AD_CBE_WRITE 0x00010000
/*
* USB Device Controller
*
* These are used by the USB gadget driver, so they don't follow the
* IXP4XX_ naming convetions.
*
*/
# define IXP4XX_USB_REG(x) (*((volatile u32 *)(x)))
/* UDC Undocumented - Reserved1 */
#define UDC_RES1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0004)
/* UDC Undocumented - Reserved2 */
#define UDC_RES2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0008)
/* UDC Undocumented - Reserved3 */
#define UDC_RES3 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x000C)
/* UDC Control Register */
#define UDCCR IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0000)
/* UDC Endpoint 0 Control/Status Register */
#define UDCCS0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0010)
/* UDC Endpoint 1 (IN) Control/Status Register */
#define UDCCS1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0014)
/* UDC Endpoint 2 (OUT) Control/Status Register */
#define UDCCS2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0018)
/* UDC Endpoint 3 (IN) Control/Status Register */
#define UDCCS3 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x001C)
/* UDC Endpoint 4 (OUT) Control/Status Register */
#define UDCCS4 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0020)
/* UDC Endpoint 5 (Interrupt) Control/Status Register */
#define UDCCS5 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0024)
/* UDC Endpoint 6 (IN) Control/Status Register */
#define UDCCS6 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0028)
/* UDC Endpoint 7 (OUT) Control/Status Register */
#define UDCCS7 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x002C)
/* UDC Endpoint 8 (IN) Control/Status Register */
#define UDCCS8 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0030)
/* UDC Endpoint 9 (OUT) Control/Status Register */
#define UDCCS9 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0034)
/* UDC Endpoint 10 (Interrupt) Control/Status Register */
#define UDCCS10 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0038)
/* UDC Endpoint 11 (IN) Control/Status Register */
#define UDCCS11 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x003C)
/* UDC Endpoint 12 (OUT) Control/Status Register */
#define UDCCS12 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0040)
/* UDC Endpoint 13 (IN) Control/Status Register */
#define UDCCS13 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0044)
/* UDC Endpoint 14 (OUT) Control/Status Register */
#define UDCCS14 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0048)
/* UDC Endpoint 15 (Interrupt) Control/Status Register */
#define UDCCS15 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x004C)
/* UDC Frame Number Register High */
#define UFNRH IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0060)
/* UDC Frame Number Register Low */
#define UFNRL IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0064)
/* UDC Byte Count Reg 2 */
#define UBCR2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0068)
/* UDC Byte Count Reg 4 */
#define UBCR4 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x006c)
/* UDC Byte Count Reg 7 */
#define UBCR7 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0070)
/* UDC Byte Count Reg 9 */
#define UBCR9 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0074)
/* UDC Byte Count Reg 12 */
#define UBCR12 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0078)
/* UDC Byte Count Reg 14 */
#define UBCR14 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x007c)
/* UDC Endpoint 0 Data Register */
#define UDDR0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0080)
/* UDC Endpoint 1 Data Register */
#define UDDR1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0100)
/* UDC Endpoint 2 Data Register */
#define UDDR2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0180)
/* UDC Endpoint 3 Data Register */
#define UDDR3 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0200)
/* UDC Endpoint 4 Data Register */
#define UDDR4 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0400)
/* UDC Endpoint 5 Data Register */
#define UDDR5 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x00A0)
/* UDC Endpoint 6 Data Register */
#define UDDR6 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0600)
/* UDC Endpoint 7 Data Register */
#define UDDR7 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0680)
/* UDC Endpoint 8 Data Register */
#define UDDR8 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0700)
/* UDC Endpoint 9 Data Register */
#define UDDR9 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0900)
/* UDC Endpoint 10 Data Register */
#define UDDR10 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x00C0)
/* UDC Endpoint 11 Data Register */
#define UDDR11 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0B00)
/* UDC Endpoint 12 Data Register */
#define UDDR12 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0B80)
/* UDC Endpoint 13 Data Register */
#define UDDR13 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0C00)
/* UDC Endpoint 14 Data Register */
#define UDDR14 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0E00)
/* UDC Endpoint 15 Data Register */
#define UDDR15 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x00E0)
/* UDC Interrupt Control Register 0 */
#define UICR0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0050)
/* UDC Interrupt Control Register 1 */
#define UICR1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0054)
/* UDC Status Interrupt Register 0 */
#define USIR0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0058)
/* UDC Status Interrupt Register 1 */
#define USIR1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x005C)
#define UDCCR_UDE (1 << 0) /* UDC enable */
#define UDCCR_UDA (1 << 1) /* UDC active */
#define UDCCR_RSM (1 << 2) /* Device resume */
#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */
#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */
#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */
#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */
#define UDCCR_REM (1 << 7) /* Reset interrupt mask */
#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
#define UDCCS0_IPR (1 << 1) /* IN packet ready */
#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */
#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */
#define UDCCS0_SST (1 << 4) /* Sent stall */
#define UDCCS0_FST (1 << 5) /* Force stall */
#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */
#define UDCCS0_SA (1 << 7) /* Setup active */
#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */
#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */
#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */
#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */
#define UDCCS_BI_SST (1 << 4) /* Sent stall */
#define UDCCS_BI_FST (1 << 5) /* Force stall */
#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */
#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */
#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */
#define UDCCS_BO_DME (1 << 3) /* DMA enable */
#define UDCCS_BO_SST (1 << 4) /* Sent stall */
#define UDCCS_BO_FST (1 << 5) /* Force stall */
#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */
#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */
#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */
#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */
#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */
#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */
#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */
#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */
#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */
#define UDCCS_IO_ROF (1 << 3) /* Receive overflow */
#define UDCCS_IO_DME (1 << 3) /* DMA enable */
#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */
#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */
#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */
#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */
#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */
#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */
#define UDCCS_INT_SST (1 << 4) /* Sent stall */
#define UDCCS_INT_FST (1 << 5) /* Force stall */
#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */
#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */
#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */
#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */
#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */
#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */
#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */
#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */
#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */
#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */
#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */
#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */
#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */
#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */
#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */
#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */
#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */
#define USIR0_IR0 (1 << 0) /* Interrupt request ep 0 */
#define USIR0_IR1 (1 << 1) /* Interrupt request ep 1 */
#define USIR0_IR2 (1 << 2) /* Interrupt request ep 2 */
#define USIR0_IR3 (1 << 3) /* Interrupt request ep 3 */
#define USIR0_IR4 (1 << 4) /* Interrupt request ep 4 */
#define USIR0_IR5 (1 << 5) /* Interrupt request ep 5 */
#define USIR0_IR6 (1 << 6) /* Interrupt request ep 6 */
#define USIR0_IR7 (1 << 7) /* Interrupt request ep 7 */
#define USIR1_IR8 (1 << 0) /* Interrupt request ep 8 */
#define USIR1_IR9 (1 << 1) /* Interrupt request ep 9 */
#define USIR1_IR10 (1 << 2) /* Interrupt request ep 10 */
#define USIR1_IR11 (1 << 3) /* Interrupt request ep 11 */
#define USIR1_IR12 (1 << 4) /* Interrupt request ep 12 */
#define USIR1_IR13 (1 << 5) /* Interrupt request ep 13 */
#define USIR1_IR14 (1 << 6) /* Interrupt request ep 14 */
#define USIR1_IR15 (1 << 7) /* Interrupt request ep 15 */
#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
/* "fuse" bits of IXP_EXP_CFG2 */
/* All IXP4xx CPUs */
#define IXP4XX_FEATURE_RCOMP (1 << 0)
#define IXP4XX_FEATURE_USB_DEVICE (1 << 1)
#define IXP4XX_FEATURE_HASH (1 << 2)
#define IXP4XX_FEATURE_AES (1 << 3)
#define IXP4XX_FEATURE_DES (1 << 4)
#define IXP4XX_FEATURE_HDLC (1 << 5)
#define IXP4XX_FEATURE_AAL (1 << 6)
#define IXP4XX_FEATURE_HSS (1 << 7)
#define IXP4XX_FEATURE_UTOPIA (1 << 8)
#define IXP4XX_FEATURE_NPEB_ETH0 (1 << 9)
#define IXP4XX_FEATURE_NPEC_ETH (1 << 10)
#define IXP4XX_FEATURE_RESET_NPEA (1 << 11)
#define IXP4XX_FEATURE_RESET_NPEB (1 << 12)
#define IXP4XX_FEATURE_RESET_NPEC (1 << 13)
#define IXP4XX_FEATURE_PCI (1 << 14)
#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
#define IXP4XX_FEATURE_XSCALE_MAX_FREQ (3 << 22)
#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP | \
IXP4XX_FEATURE_USB_DEVICE | \
IXP4XX_FEATURE_HASH | \
IXP4XX_FEATURE_AES | \
IXP4XX_FEATURE_DES | \
IXP4XX_FEATURE_HDLC | \
IXP4XX_FEATURE_AAL | \
IXP4XX_FEATURE_HSS | \
IXP4XX_FEATURE_UTOPIA | \
IXP4XX_FEATURE_NPEB_ETH0 | \
IXP4XX_FEATURE_NPEC_ETH | \
IXP4XX_FEATURE_RESET_NPEA | \
IXP4XX_FEATURE_RESET_NPEB | \
IXP4XX_FEATURE_RESET_NPEC | \
IXP4XX_FEATURE_PCI | \
IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
IXP4XX_FEATURE_XSCALE_MAX_FREQ)
/* IXP43x/46x CPUs */
#define IXP4XX_FEATURE_ECC_TIMESYNC (1 << 15)
#define IXP4XX_FEATURE_USB_HOST (1 << 18)
#define IXP4XX_FEATURE_NPEA_ETH (1 << 19)
#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK | \
IXP4XX_FEATURE_ECC_TIMESYNC | \
IXP4XX_FEATURE_USB_HOST | \
IXP4XX_FEATURE_NPEA_ETH)
/* IXP46x CPU (including IXP455) only */
#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3 (1 << 20)
#define IXP4XX_FEATURE_RSA (1 << 21)
#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK | \
IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \
IXP4XX_FEATURE_RSA)
#endif

View File

@@ -0,0 +1,29 @@
/*
* arch/arm/mach-ixp4xx/include/mach/memory.h
*
* Copyright (c) 2001-2004 MontaVista Software, Inc.
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
#include <asm/sizes.h>
/*
* Physical DRAM offset.
*/
#define PHYS_OFFSET UL(0x00000000)
#if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes);
#define arch_adjust_zones(node, size, holes) \
ixp4xx_adjust_zones(node, size, holes)
#define ISA_DMA_THRESHOLD (SZ_64M - 1)
#define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_64M)
#endif
#endif

View File

@@ -0,0 +1,52 @@
/*
* arch/arm/mach-ixp4xx/include/mach/nas100d.h
*
* NAS100D platform specific definitions
*
* Copyright (c) 2005 Tower Technologies
*
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* based on ixdp425.h:
* Copyright 2004 (c) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#define NAS100D_SDA_PIN 5
#define NAS100D_SCL_PIN 6
/*
* NAS100D PCI IRQs
*/
#define NAS100D_PCI_MAX_DEV 3
#define NAS100D_PCI_IRQ_LINES 3
/* PCI controller GPIO to IRQ pin mappings */
#define NAS100D_PCI_INTA_PIN 11
#define NAS100D_PCI_INTB_PIN 10
#define NAS100D_PCI_INTC_PIN 9
#define NAS100D_PCI_INTD_PIN 8
#define NAS100D_PCI_INTE_PIN 7
/* Buttons */
#define NAS100D_PB_GPIO 14 /* power button */
#define NAS100D_RB_GPIO 4 /* reset button */
/* Power control */
#define NAS100D_PO_GPIO 12 /* power off */
/* LEDs */
#define NAS100D_LED_WLAN_GPIO 0
#define NAS100D_LED_DISK_GPIO 3
#define NAS100D_LED_PWR_GPIO 15

View File

@@ -0,0 +1,39 @@
#ifndef __IXP4XX_NPE_H
#define __IXP4XX_NPE_H
#include <linux/kernel.h>
extern const char *npe_names[];
struct npe_regs {
u32 exec_addr, exec_data, exec_status_cmd, exec_count;
u32 action_points[4];
u32 watchpoint_fifo, watch_count;
u32 profile_count;
u32 messaging_status, messaging_control;
u32 mailbox_status, /*messaging_*/ in_out_fifo;
};
struct npe {
struct resource *mem_res;
struct npe_regs __iomem *regs;
u32 regs_phys;
int id;
int valid;
};
static inline const char *npe_name(struct npe *npe)
{
return npe_names[npe->id];
}
int npe_running(struct npe *npe);
int npe_send_message(struct npe *npe, const void *msg, const char *what);
int npe_recv_message(struct npe *npe, void *msg, const char *what);
int npe_send_recv_message(struct npe *npe, void *msg, const char *what);
int npe_load_firmware(struct npe *npe, const char *name, struct device *dev);
struct npe *npe_request(int id);
void npe_release(struct npe *npe);
#endif /* __IXP4XX_NPE_H */

View File

@@ -0,0 +1,55 @@
/*
* arch/arm/mach-ixp4xx/include/mach/nslu2.h
*
* NSLU2 platform specific definitions
*
* Author: Mark Rakes <mrakes AT mac.com>
* Maintainers: http://www.nslu2-linux.org
*
* based on ixdp425.h:
* Copyright 2004 (c) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#define NSLU2_SDA_PIN 7
#define NSLU2_SCL_PIN 6
/*
* NSLU2 PCI IRQs
*/
#define NSLU2_PCI_MAX_DEV 3
#define NSLU2_PCI_IRQ_LINES 3
/* PCI controller GPIO to IRQ pin mappings */
#define NSLU2_PCI_INTA_PIN 11
#define NSLU2_PCI_INTB_PIN 10
#define NSLU2_PCI_INTC_PIN 9
#define NSLU2_PCI_INTD_PIN 8
/* NSLU2 Timer */
#define NSLU2_FREQ 66000000
/* Buttons */
#define NSLU2_PB_GPIO 5 /* power button */
#define NSLU2_PO_GPIO 8 /* power off */
#define NSLU2_RB_GPIO 12 /* reset button */
/* Buzzer */
#define NSLU2_GPIO_BUZZ 4
/* LEDs */
#define NSLU2_LED_RED_GPIO 0
#define NSLU2_LED_GRN_GPIO 1
#define NSLU2_LED_DISK1_GPIO 3
#define NSLU2_LED_DISK2_GPIO 2

View File

@@ -0,0 +1,173 @@
/*
* arch/arm/mach-ixp4xx/include/mach/platform.h
*
* Constants and functions that are useful to IXP4xx platform-specific code
* and device drivers.
*
* Copyright (C) 2004 MontaVista Software, Inc.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#ifndef __ASSEMBLY__
#include <asm/types.h>
#ifndef __ARMEB__
#define REG_OFFSET 0
#else
#define REG_OFFSET 3
#endif
/*
* Expansion bus memory regions
*/
#define IXP4XX_EXP_BUS_BASE_PHYS (0x50000000)
/*
* The expansion bus on the IXP4xx can be configured for either 16 or
* 32MB windows and the CS offset for each region changes based on the
* current configuration. This means that we cannot simply hardcode
* each offset. ixp4xx_sys_init() looks at the expansion bus configuration
* as setup by the bootloader to determine our window size.
*/
extern unsigned long ixp4xx_exp_bus_size;
#define IXP4XX_EXP_BUS_BASE(region)\
(IXP4XX_EXP_BUS_BASE_PHYS + ((region) * ixp4xx_exp_bus_size))
#define IXP4XX_EXP_BUS_END(region)\
(IXP4XX_EXP_BUS_BASE(region) + ixp4xx_exp_bus_size - 1)
/* Those macros can be used to adjust timing and configure
* other features for each region.
*/
#define IXP4XX_EXP_BUS_RECOVERY_T(x) (((x) & 0x0f) << 16)
#define IXP4XX_EXP_BUS_HOLD_T(x) (((x) & 0x03) << 20)
#define IXP4XX_EXP_BUS_STROBE_T(x) (((x) & 0x0f) << 22)
#define IXP4XX_EXP_BUS_SETUP_T(x) (((x) & 0x03) << 26)
#define IXP4XX_EXP_BUS_ADDR_T(x) (((x) & 0x03) << 28)
#define IXP4XX_EXP_BUS_SIZE(x) (((x) & 0x0f) << 10)
#define IXP4XX_EXP_BUS_CYCLES(x) (((x) & 0x03) << 14)
#define IXP4XX_EXP_BUS_CS_EN (1L << 31)
#define IXP4XX_EXP_BUS_BYTE_RD16 (1L << 6)
#define IXP4XX_EXP_BUS_HRDY_POL (1L << 5)
#define IXP4XX_EXP_BUS_MUX_EN (1L << 4)
#define IXP4XX_EXP_BUS_SPLT_EN (1L << 3)
#define IXP4XX_EXP_BUS_WR_EN (1L << 1)
#define IXP4XX_EXP_BUS_BYTE_EN (1L << 0)
#define IXP4XX_EXP_BUS_CYCLES_INTEL 0x00
#define IXP4XX_EXP_BUS_CYCLES_MOTOROLA 0x01
#define IXP4XX_EXP_BUS_CYCLES_HPI 0x02
#define IXP4XX_FLASH_WRITABLE (0x2)
#define IXP4XX_FLASH_DEFAULT (0xbcd23c40)
#define IXP4XX_FLASH_WRITE (0xbcd23c42)
/*
* Clock Speed Definitions.
*/
#define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66Mhzi APB BUS */
#define IXP4XX_UART_XTAL 14745600
/*
* This structure provide a means for the board setup code
* to give information to th pata_ixp4xx driver. It is
* passed as platform_data.
*/
struct ixp4xx_pata_data {
volatile u32 *cs0_cfg;
volatile u32 *cs1_cfg;
unsigned long cs0_bits;
unsigned long cs1_bits;
void __iomem *cs0;
void __iomem *cs1;
};
struct sys_timer;
#define IXP4XX_ETH_NPEA 0x00
#define IXP4XX_ETH_NPEB 0x10
#define IXP4XX_ETH_NPEC 0x20
/* Information about built-in Ethernet MAC interfaces */
struct eth_plat_info {
u8 phy; /* MII PHY ID, 0 - 31 */
u8 rxq; /* configurable, currently 0 - 31 only */
u8 txreadyq;
u8 hwaddr[6];
};
/* Information about built-in HSS (synchronous serial) interfaces */
struct hss_plat_info {
int (*set_clock)(int port, unsigned int clock_type);
int (*open)(int port, void *pdev,
void (*set_carrier_cb)(void *pdev, int carrier));
void (*close)(int port, void *pdev);
u8 txreadyq;
};
/*
* Frequency of clock used for primary clocksource
*/
extern unsigned long ixp4xx_timer_freq;
/*
* Functions used by platform-level setup code
*/
extern void ixp4xx_map_io(void);
extern void ixp4xx_init_irq(void);
extern void ixp4xx_sys_init(void);
extern void ixp4xx_timer_init(void);
extern struct sys_timer ixp4xx_timer;
extern void ixp4xx_pci_preinit(void);
struct pci_sys_data;
extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
/*
* GPIO-functions
*/
/*
* The following converted to the real HW bits the gpio_line_config
*/
/* GPIO pin types */
#define IXP4XX_GPIO_OUT 0x1
#define IXP4XX_GPIO_IN 0x2
/* GPIO signal types */
#define IXP4XX_GPIO_LOW 0
#define IXP4XX_GPIO_HIGH 1
/* GPIO Clocks */
#define IXP4XX_GPIO_CLK_0 14
#define IXP4XX_GPIO_CLK_1 15
static inline void gpio_line_config(u8 line, u32 direction)
{
if (direction == IXP4XX_GPIO_IN)
*IXP4XX_GPIO_GPOER |= (1 << line);
else
*IXP4XX_GPIO_GPOER &= ~(1 << line);
}
static inline void gpio_line_get(u8 line, int *value)
{
*value = (*IXP4XX_GPIO_GPINR >> line) & 0x1;
}
static inline void gpio_line_set(u8 line, int value)
{
if (value == IXP4XX_GPIO_HIGH)
*IXP4XX_GPIO_GPOUTR |= (1 << line);
else if (value == IXP4XX_GPIO_LOW)
*IXP4XX_GPIO_GPOUTR &= ~(1 << line);
}
#endif // __ASSEMBLY__

View File

@@ -0,0 +1,33 @@
/*
* arch/arm/mach-ixp4xx/include/mach/prpmc1100.h
*
* Motorolla PrPMC1100 platform specific definitions
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2004 (c) MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#error "Do not include this directly, instead #include <mach/hardware.h>"
#endif
#define PRPMC1100_FLASH_BASE IXP4XX_EXP_BUS_CS0_BASE_PHYS
#define PRPMC1100_FLASH_SIZE IXP4XX_EXP_BUS_CSX_REGION_SIZE
#define PRPMC1100_PCI_MIN_DEVID 10
#define PRPMC1100_PCI_MAX_DEVID 16
#define PRPMC1100_PCI_IRQ_LINES 4
/* PCI controller GPIO to IRQ pin mappings */
#define PRPMC1100_PCI_INTA_PIN 11
#define PRPMC1100_PCI_INTB_PIN 10
#define PRPMC1100_PCI_INTC_PIN 9
#define PRPMC1100_PCI_INTD_PIN 8

View File

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*/
#ifndef IXP4XX_QMGR_H
#define IXP4XX_QMGR_H
#include <linux/io.h>
#include <linux/kernel.h>
#define DEBUG_QMGR 0
#define HALF_QUEUES 32
#define QUEUES 64
#define MAX_QUEUE_LENGTH 4 /* in dwords */
#define QUEUE_STAT1_EMPTY 1 /* queue status bits */
#define QUEUE_STAT1_NEARLY_EMPTY 2
#define QUEUE_STAT1_NEARLY_FULL 4
#define QUEUE_STAT1_FULL 8
#define QUEUE_STAT2_UNDERFLOW 1
#define QUEUE_STAT2_OVERFLOW 2
#define QUEUE_WATERMARK_0_ENTRIES 0
#define QUEUE_WATERMARK_1_ENTRY 1
#define QUEUE_WATERMARK_2_ENTRIES 2
#define QUEUE_WATERMARK_4_ENTRIES 3
#define QUEUE_WATERMARK_8_ENTRIES 4
#define QUEUE_WATERMARK_16_ENTRIES 5
#define QUEUE_WATERMARK_32_ENTRIES 6
#define QUEUE_WATERMARK_64_ENTRIES 7
/* queue interrupt request conditions */
#define QUEUE_IRQ_SRC_EMPTY 0
#define QUEUE_IRQ_SRC_NEARLY_EMPTY 1
#define QUEUE_IRQ_SRC_NEARLY_FULL 2
#define QUEUE_IRQ_SRC_FULL 3
#define QUEUE_IRQ_SRC_NOT_EMPTY 4
#define QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY 5
#define QUEUE_IRQ_SRC_NOT_NEARLY_FULL 6
#define QUEUE_IRQ_SRC_NOT_FULL 7
struct qmgr_regs {
u32 acc[QUEUES][MAX_QUEUE_LENGTH]; /* 0x000 - 0x3FF */
u32 stat1[4]; /* 0x400 - 0x40F */
u32 stat2[2]; /* 0x410 - 0x417 */
u32 statne_h; /* 0x418 - queue nearly empty */
u32 statf_h; /* 0x41C - queue full */
u32 irqsrc[4]; /* 0x420 - 0x42F IRC source */
u32 irqen[2]; /* 0x430 - 0x437 IRQ enabled */
u32 irqstat[2]; /* 0x438 - 0x43F - IRQ access only */
u32 reserved[1776];
u32 sram[2048]; /* 0x2000 - 0x3FFF - config and buffer */
};
void qmgr_set_irq(unsigned int queue, int src,
void (*handler)(void *pdev), void *pdev);
void qmgr_enable_irq(unsigned int queue);
void qmgr_disable_irq(unsigned int queue);
/* request_ and release_queue() must be called from non-IRQ context */
#if DEBUG_QMGR
extern char qmgr_queue_descs[QUEUES][32];
int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
unsigned int nearly_empty_watermark,
unsigned int nearly_full_watermark,
const char *desc_format, const char* name);
#else
int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
unsigned int nearly_empty_watermark,
unsigned int nearly_full_watermark);
#define qmgr_request_queue(queue, len, nearly_empty_watermark, \
nearly_full_watermark, desc_format, name) \
__qmgr_request_queue(queue, len, nearly_empty_watermark, \
nearly_full_watermark)
#endif
void qmgr_release_queue(unsigned int queue);
static inline void qmgr_put_entry(unsigned int queue, u32 val)
{
extern struct qmgr_regs __iomem *qmgr_regs;
#if DEBUG_QMGR
BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
printk(KERN_DEBUG "Queue %s(%i) put %X\n",
qmgr_queue_descs[queue], queue, val);
#endif
__raw_writel(val, &qmgr_regs->acc[queue][0]);
}
static inline u32 qmgr_get_entry(unsigned int queue)
{
u32 val;
extern struct qmgr_regs __iomem *qmgr_regs;
val = __raw_readl(&qmgr_regs->acc[queue][0]);
#if DEBUG_QMGR
BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
printk(KERN_DEBUG "Queue %s(%i) get %X\n",
qmgr_queue_descs[queue], queue, val);
#endif
return val;
}
static inline int __qmgr_get_stat1(unsigned int queue)
{
extern struct qmgr_regs __iomem *qmgr_regs;
return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
>> ((queue & 7) << 2)) & 0xF;
}
static inline int __qmgr_get_stat2(unsigned int queue)
{
extern struct qmgr_regs __iomem *qmgr_regs;
BUG_ON(queue >= HALF_QUEUES);
return (__raw_readl(&qmgr_regs->stat2[queue >> 4])
>> ((queue & 0xF) << 1)) & 0x3;
}
/**
* qmgr_stat_empty() - checks if a hardware queue is empty
* @queue: queue number
*
* Returns non-zero value if the queue is empty.
*/
static inline int qmgr_stat_empty(unsigned int queue)
{
BUG_ON(queue >= HALF_QUEUES);
return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY;
}
/**
* qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
* @queue: queue number
*
* Returns non-zero value if the queue is below low watermark.
*/
static inline int qmgr_stat_below_low_watermark(unsigned int queue)
{
extern struct qmgr_regs __iomem *qmgr_regs;
if (queue >= HALF_QUEUES)
return (__raw_readl(&qmgr_regs->statne_h) >>
(queue - HALF_QUEUES)) & 0x01;
return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
}
/**
* qmgr_stat_above_high_watermark() - checks if a queue is above high watermark
* @queue: queue number
*
* Returns non-zero value if the queue is above high watermark
*/
static inline int qmgr_stat_above_high_watermark(unsigned int queue)
{
BUG_ON(queue >= HALF_QUEUES);
return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL;
}
/**
* qmgr_stat_full() - checks if a hardware queue is full
* @queue: queue number
*
* Returns non-zero value if the queue is full.
*/
static inline int qmgr_stat_full(unsigned int queue)
{
extern struct qmgr_regs __iomem *qmgr_regs;
if (queue >= HALF_QUEUES)
return (__raw_readl(&qmgr_regs->statf_h) >>
(queue - HALF_QUEUES)) & 0x01;
return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
}
/**
* qmgr_stat_underflow() - checks if a hardware queue experienced underflow
* @queue: queue number
*
* Returns non-zero value if the queue experienced underflow.
*/
static inline int qmgr_stat_underflow(unsigned int queue)
{
return __qmgr_get_stat2(queue) & QUEUE_STAT2_UNDERFLOW;
}
/**
* qmgr_stat_overflow() - checks if a hardware queue experienced overflow
* @queue: queue number
*
* Returns non-zero value if the queue experienced overflow.
*/
static inline int qmgr_stat_overflow(unsigned int queue)
{
return __qmgr_get_stat2(queue) & QUEUE_STAT2_OVERFLOW;
}
#endif

View File

@@ -0,0 +1,44 @@
/*
* arch/arm/mach-ixp4xx/include/mach/system.h
*
* Copyright (C) 2002 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 <mach/hardware.h>
static inline void arch_idle(void)
{
/* ixp4xx does not implement the XScale PWRMODE register,
* so it must not call cpu_do_idle() here.
*/
#if 0
cpu_do_idle();
#endif
}
static inline void arch_reset(char mode, const char *cmd)
{
if ( 1 && mode == 's') {
/* Jump into ROM at address 0 */
cpu_reset(0);
} else {
/* Use on-chip reset capability */
/* set the "key" register to enable access to
* "timer" and "enable" registers
*/
*IXP4XX_OSWK = IXP4XX_WDT_KEY;
/* write 0 to the timer register for an immediate reset */
*IXP4XX_OSWT = 0;
*IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
}
}

View File

@@ -0,0 +1,15 @@
/*
* arch/arm/mach-ixp4xx/include/mach/timex.h
*
*/
#include <mach/hardware.h>
/*
* We use IXP425 General purpose timer for our timer needs, it runs at
* 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the
* timer register ignores the bottom 2 bits of the LATCH value.
*/
#define FREQ 66666666
#define CLOCK_TICK_RATE (((FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)

View File

@@ -0,0 +1,8 @@
/*
* arch/arm/mach-ixp4xx/include/mach/udc.h
*
*/
#include <asm/mach/udc_pxa2xx.h>
extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);

View File

@@ -0,0 +1,57 @@
/*
* arch/arm/mach-ixp4xx/include/mach/uncompress.h
*
* 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.
*
*/
#ifndef _ARCH_UNCOMPRESS_H_
#define _ARCH_UNCOMPRESS_H_
#include "ixp4xx-regs.h"
#include <asm/mach-types.h>
#include <linux/serial_reg.h>
#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
static volatile u32* uart_base;
static inline void putc(int c)
{
/* Check THRE and TEMT bits before we transmit the character.
*/
while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
barrier();
*uart_base = c;
}
static void flush(void)
{
}
static __inline__ void __arch_decomp_setup(unsigned long arch_id)
{
/*
* Some boards are using UART2 as console
*/
if (machine_is_adi_coyote() || machine_is_gtwx5715() ||
machine_is_gateway7001() || machine_is_wg302v2())
uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS;
else
uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS;
}
/*
* arch_id is a variable in decompress_kernel()
*/
#define arch_decomp_setup() __arch_decomp_setup(arch_id)
#define arch_decomp_wdog()
#endif

View File

@@ -0,0 +1,5 @@
/*
* arch/arm/mach-ixp4xx/include/mach/vmalloc.h
*/
#define VMALLOC_END (0xFF000000)

View File

@@ -0,0 +1,75 @@
/*
* arch/arm/mach-ixp4xx/ixdp425-pci.c
*
* IXDP425 board-level PCI initialization
*
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* 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/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/mach/pci.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
void __init ixdp425_pci_preinit(void)
{
set_irq_type(IRQ_IXDP425_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_IXDP425_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_IXDP425_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_IXDP425_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init ixdp425_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static int pci_irq_table[IXDP425_PCI_IRQ_LINES] = {
IRQ_IXDP425_PCI_INTA,
IRQ_IXDP425_PCI_INTB,
IRQ_IXDP425_PCI_INTC,
IRQ_IXDP425_PCI_INTD
};
int irq = -1;
if (slot >= 1 && slot <= IXDP425_PCI_MAX_DEV &&
pin >= 1 && pin <= IXDP425_PCI_IRQ_LINES) {
irq = pci_irq_table[(slot + pin - 2) % 4];
}
return irq;
}
struct hw_pci ixdp425_pci __initdata = {
.nr_controllers = 1,
.preinit = ixdp425_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = ixdp425_map_irq,
};
int __init ixdp425_pci_init(void)
{
if (machine_is_ixdp425() || machine_is_ixcdp1100() ||
machine_is_ixdp465() || machine_is_kixrp435())
pci_common_init(&ixdp425_pci);
return 0;
}
subsys_initcall(ixdp425_pci_init);

View File

@@ -0,0 +1,299 @@
/*
* arch/arm/mach-ixp4xx/ixdp425-setup.c
*
* IXDP425/IXCDP1100 board-setup
*
* Copyright (C) 2003-2005 MontaVista Software, Inc.
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>
#include <linux/i2c-gpio.h>
#include <linux/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/delay.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
static struct flash_platform_data ixdp425_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource ixdp425_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device ixdp425_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = {
.platform_data = &ixdp425_flash_data,
},
.num_resources = 1,
.resource = &ixdp425_flash_resource,
};
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
#ifdef CONFIG_MTD_PARTITIONS
const char *part_probes[] = { "cmdlinepart", NULL };
static struct mtd_partition ixdp425_partitions[] = {
{
.name = "ixp400 NAND FS 0",
.offset = 0,
.size = SZ_8M
}, {
.name = "ixp400 NAND FS 1",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL
},
};
#endif
static void
ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *this = mtd->priv;
int offset = (int)this->priv;
if (ctrl & NAND_CTRL_CHANGE) {
if (ctrl & NAND_NCE) {
gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW);
udelay(5);
} else
gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH);
offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0;
offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0;
this->priv = (void *)offset;
}
if (cmd != NAND_CMD_NONE)
writeb(cmd, this->IO_ADDR_W + offset);
}
static struct platform_nand_data ixdp425_flash_nand_data = {
.chip = {
.chip_delay = 30,
.options = NAND_NO_AUTOINCR,
#ifdef CONFIG_MTD_PARTITIONS
.part_probe_types = part_probes,
.partitions = ixdp425_partitions,
.nr_partitions = ARRAY_SIZE(ixdp425_partitions),
#endif
},
.ctrl = {
.cmd_ctrl = ixdp425_flash_nand_cmd_ctrl
}
};
static struct resource ixdp425_flash_nand_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device ixdp425_flash_nand = {
.name = "gen_nand",
.id = -1,
.dev = {
.platform_data = &ixdp425_flash_nand_data,
},
.num_resources = 1,
.resource = &ixdp425_flash_nand_resource,
};
#endif /* CONFIG_MTD_NAND_PLATFORM */
static struct i2c_gpio_platform_data ixdp425_i2c_gpio_data = {
.sda_pin = IXDP425_SDA_PIN,
.scl_pin = IXDP425_SCL_PIN,
};
static struct platform_device ixdp425_i2c_gpio = {
.name = "i2c-gpio",
.id = 0,
.dev = {
.platform_data = &ixdp425_i2c_gpio_data,
},
};
static struct resource ixdp425_uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM
}
};
static struct plat_serial8250_port ixdp425_uart_data[] = {
{
.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,
},
{
.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,
},
{ },
};
static struct platform_device ixdp425_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = ixdp425_uart_data,
.num_resources = 2,
.resource = ixdp425_uart_resources
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct eth_plat_info ixdp425_plat_eth[] = {
{
.phy = 0,
.rxq = 3,
.txreadyq = 20,
}, {
.phy = 1,
.rxq = 4,
.txreadyq = 21,
}
};
static struct platform_device ixdp425_eth[] = {
{
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = ixdp425_plat_eth,
}, {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEC,
.dev.platform_data = ixdp425_plat_eth + 1,
}
};
static struct platform_device *ixdp425_devices[] __initdata = {
&ixdp425_i2c_gpio,
&ixdp425_flash,
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
&ixdp425_flash_nand,
#endif
&ixdp425_uart,
&ixdp425_eth[0],
&ixdp425_eth[1],
};
static void __init ixdp425_init(void)
{
ixp4xx_sys_init();
ixdp425_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
ixdp425_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3),
ixdp425_flash_nand_resource.end = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1;
gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT);
/* Configure expansion bus for NAND Flash */
*IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN |
IXP4XX_EXP_BUS_STROBE_T(1) | /* extend by 1 clock */
IXP4XX_EXP_BUS_CYCLES(0) | /* Intel cycles */
IXP4XX_EXP_BUS_SIZE(0) | /* 512bytes addr space*/
IXP4XX_EXP_BUS_WR_EN |
IXP4XX_EXP_BUS_BYTE_EN; /* 8 bit data bus */
#endif
if (cpu_is_ixp43x()) {
ixdp425_uart.num_resources = 1;
ixdp425_uart_data[1].flags = 0;
}
platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
}
#ifdef CONFIG_ARCH_IXDP425
MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.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 = ixdp425_init,
MACHINE_END
#endif
#ifdef CONFIG_MACH_IXDP465
MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.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 = ixdp425_init,
MACHINE_END
#endif
#ifdef CONFIG_ARCH_PRPMC1100
MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.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 = ixdp425_init,
MACHINE_END
#endif
#ifdef CONFIG_MACH_KIXRP435
MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform")
/* Maintainer: MontaVista Software, Inc. */
.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 = ixdp425_init,
MACHINE_END
#endif

View File

@@ -0,0 +1,59 @@
/*
* arch/arm/mach-ixp4xx/ixdpg425-pci.c
*
* PCI setup routines for Intel IXDPG425 Platform
*
* Copyright (C) 2004 MontaVista Softwrae, Inc.
*
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* 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/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/mach/pci.h>
void __init ixdpg425_pci_preinit(void)
{
set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init ixdpg425_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
if (slot == 12 || slot == 13)
return IRQ_IXP4XX_GPIO7;
else if (slot == 14)
return IRQ_IXP4XX_GPIO6;
else return -1;
}
struct hw_pci ixdpg425_pci __initdata = {
.nr_controllers = 1,
.preinit = ixdpg425_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = ixdpg425_map_irq,
};
int __init ixdpg425_pci_init(void)
{
if (machine_is_ixdpg425())
pci_common_init(&ixdpg425_pci);
return 0;
}
subsys_initcall(ixdpg425_pci_init);

View File

@@ -0,0 +1,736 @@
/*
* Intel IXP4xx Network Processor Engine driver for Linux
*
* Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* The code is based on publicly available information:
* - Intel IXP4xx Developer's Manual and other e-papers
* - Intel IXP400 Access Library Software (BSD license)
* - previous works by Christian Hohnstaedt <chohnstaedt@innominate.com>
* Thanks, Christian.
*/
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <mach/npe.h>
#define DEBUG_MSG 0
#define DEBUG_FW 0
#define NPE_COUNT 3
#define MAX_RETRIES 1000 /* microseconds */
#define NPE_42X_DATA_SIZE 0x800 /* in dwords */
#define NPE_46X_DATA_SIZE 0x1000
#define NPE_A_42X_INSTR_SIZE 0x1000
#define NPE_B_AND_C_42X_INSTR_SIZE 0x800
#define NPE_46X_INSTR_SIZE 0x1000
#define REGS_SIZE 0x1000
#define NPE_PHYS_REG 32
#define FW_MAGIC 0xFEEDF00D
#define FW_BLOCK_TYPE_INSTR 0x0
#define FW_BLOCK_TYPE_DATA 0x1
#define FW_BLOCK_TYPE_EOF 0xF
/* NPE exec status (read) and command (write) */
#define CMD_NPE_STEP 0x01
#define CMD_NPE_START 0x02
#define CMD_NPE_STOP 0x03
#define CMD_NPE_CLR_PIPE 0x04
#define CMD_CLR_PROFILE_CNT 0x0C
#define CMD_RD_INS_MEM 0x10 /* instruction memory */
#define CMD_WR_INS_MEM 0x11
#define CMD_RD_DATA_MEM 0x12 /* data memory */
#define CMD_WR_DATA_MEM 0x13
#define CMD_RD_ECS_REG 0x14 /* exec access register */
#define CMD_WR_ECS_REG 0x15
#define STAT_RUN 0x80000000
#define STAT_STOP 0x40000000
#define STAT_CLEAR 0x20000000
#define STAT_ECS_K 0x00800000 /* pipeline clean */
#define NPE_STEVT 0x1B
#define NPE_STARTPC 0x1C
#define NPE_REGMAP 0x1E
#define NPE_CINDEX 0x1F
#define INSTR_WR_REG_SHORT 0x0000C000
#define INSTR_WR_REG_BYTE 0x00004000
#define INSTR_RD_FIFO 0x0F888220
#define INSTR_RESET_MBOX 0x0FAC8210
#define ECS_BG_CTXT_REG_0 0x00 /* Background Executing Context */
#define ECS_BG_CTXT_REG_1 0x01 /* Stack level */
#define ECS_BG_CTXT_REG_2 0x02
#define ECS_PRI_1_CTXT_REG_0 0x04 /* Priority 1 Executing Context */
#define ECS_PRI_1_CTXT_REG_1 0x05 /* Stack level */
#define ECS_PRI_1_CTXT_REG_2 0x06
#define ECS_PRI_2_CTXT_REG_0 0x08 /* Priority 2 Executing Context */
#define ECS_PRI_2_CTXT_REG_1 0x09 /* Stack level */
#define ECS_PRI_2_CTXT_REG_2 0x0A
#define ECS_DBG_CTXT_REG_0 0x0C /* Debug Executing Context */
#define ECS_DBG_CTXT_REG_1 0x0D /* Stack level */
#define ECS_DBG_CTXT_REG_2 0x0E
#define ECS_INSTRUCT_REG 0x11 /* NPE Instruction Register */
#define ECS_REG_0_ACTIVE 0x80000000 /* all levels */
#define ECS_REG_0_NEXTPC_MASK 0x1FFF0000 /* BG/PRI1/PRI2 levels */
#define ECS_REG_0_LDUR_BITS 8
#define ECS_REG_0_LDUR_MASK 0x00000700 /* all levels */
#define ECS_REG_1_CCTXT_BITS 16
#define ECS_REG_1_CCTXT_MASK 0x000F0000 /* all levels */
#define ECS_REG_1_SELCTXT_BITS 0
#define ECS_REG_1_SELCTXT_MASK 0x0000000F /* all levels */
#define ECS_DBG_REG_2_IF 0x00100000 /* debug level */
#define ECS_DBG_REG_2_IE 0x00080000 /* debug level */
/* NPE watchpoint_fifo register bit */
#define WFIFO_VALID 0x80000000
/* NPE messaging_status register bit definitions */
#define MSGSTAT_OFNE 0x00010000 /* OutFifoNotEmpty */
#define MSGSTAT_IFNF 0x00020000 /* InFifoNotFull */
#define MSGSTAT_OFNF 0x00040000 /* OutFifoNotFull */
#define MSGSTAT_IFNE 0x00080000 /* InFifoNotEmpty */
#define MSGSTAT_MBINT 0x00100000 /* Mailbox interrupt */
#define MSGSTAT_IFINT 0x00200000 /* InFifo interrupt */
#define MSGSTAT_OFINT 0x00400000 /* OutFifo interrupt */
#define MSGSTAT_WFINT 0x00800000 /* WatchFifo interrupt */
/* NPE messaging_control register bit definitions */
#define MSGCTL_OUT_FIFO 0x00010000 /* enable output FIFO */
#define MSGCTL_IN_FIFO 0x00020000 /* enable input FIFO */
#define MSGCTL_OUT_FIFO_WRITE 0x01000000 /* enable FIFO + WRITE */
#define MSGCTL_IN_FIFO_WRITE 0x02000000
/* NPE mailbox_status value for reset */
#define RESET_MBOX_STAT 0x0000F0F0
const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" };
#define print_npe(pri, npe, fmt, ...) \
printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
#if DEBUG_MSG
#define debug_msg(npe, fmt, ...) \
print_npe(KERN_DEBUG, npe, fmt, ## __VA_ARGS__)
#else
#define debug_msg(npe, fmt, ...)
#endif
static struct {
u32 reg, val;
} ecs_reset[] = {
{ ECS_BG_CTXT_REG_0, 0xA0000000 },
{ ECS_BG_CTXT_REG_1, 0x01000000 },
{ ECS_BG_CTXT_REG_2, 0x00008000 },
{ ECS_PRI_1_CTXT_REG_0, 0x20000080 },
{ ECS_PRI_1_CTXT_REG_1, 0x01000000 },
{ ECS_PRI_1_CTXT_REG_2, 0x00008000 },
{ ECS_PRI_2_CTXT_REG_0, 0x20000080 },
{ ECS_PRI_2_CTXT_REG_1, 0x01000000 },
{ ECS_PRI_2_CTXT_REG_2, 0x00008000 },
{ ECS_DBG_CTXT_REG_0, 0x20000000 },
{ ECS_DBG_CTXT_REG_1, 0x00000000 },
{ ECS_DBG_CTXT_REG_2, 0x001E0000 },
{ ECS_INSTRUCT_REG, 0x1003C00F },
};
static struct npe npe_tab[NPE_COUNT] = {
{
.id = 0,
.regs = (struct npe_regs __iomem *)IXP4XX_NPEA_BASE_VIRT,
.regs_phys = IXP4XX_NPEA_BASE_PHYS,
}, {
.id = 1,
.regs = (struct npe_regs __iomem *)IXP4XX_NPEB_BASE_VIRT,
.regs_phys = IXP4XX_NPEB_BASE_PHYS,
}, {
.id = 2,
.regs = (struct npe_regs __iomem *)IXP4XX_NPEC_BASE_VIRT,
.regs_phys = IXP4XX_NPEC_BASE_PHYS,
}
};
int npe_running(struct npe *npe)
{
return (__raw_readl(&npe->regs->exec_status_cmd) & STAT_RUN) != 0;
}
static void npe_cmd_write(struct npe *npe, u32 addr, int cmd, u32 data)
{
__raw_writel(data, &npe->regs->exec_data);
__raw_writel(addr, &npe->regs->exec_addr);
__raw_writel(cmd, &npe->regs->exec_status_cmd);
}
static u32 npe_cmd_read(struct npe *npe, u32 addr, int cmd)
{
__raw_writel(addr, &npe->regs->exec_addr);
__raw_writel(cmd, &npe->regs->exec_status_cmd);
/* Iintroduce extra read cycles after issuing read command to NPE
so that we read the register after the NPE has updated it.
This is to overcome race condition between XScale and NPE */
__raw_readl(&npe->regs->exec_data);
__raw_readl(&npe->regs->exec_data);
return __raw_readl(&npe->regs->exec_data);
}
static void npe_clear_active(struct npe *npe, u32 reg)
{
u32 val = npe_cmd_read(npe, reg, CMD_RD_ECS_REG);
npe_cmd_write(npe, reg, CMD_WR_ECS_REG, val & ~ECS_REG_0_ACTIVE);
}
static void npe_start(struct npe *npe)
{
/* ensure only Background Context Stack Level is active */
npe_clear_active(npe, ECS_PRI_1_CTXT_REG_0);
npe_clear_active(npe, ECS_PRI_2_CTXT_REG_0);
npe_clear_active(npe, ECS_DBG_CTXT_REG_0);
__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
__raw_writel(CMD_NPE_START, &npe->regs->exec_status_cmd);
}
static void npe_stop(struct npe *npe)
{
__raw_writel(CMD_NPE_STOP, &npe->regs->exec_status_cmd);
__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); /*FIXME?*/
}
static int __must_check npe_debug_instr(struct npe *npe, u32 instr, u32 ctx,
u32 ldur)
{
u32 wc;
int i;
/* set the Active bit, and the LDUR, in the debug level */
npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG,
ECS_REG_0_ACTIVE | (ldur << ECS_REG_0_LDUR_BITS));
/* set CCTXT at ECS DEBUG L3 to specify in which context to execute
the instruction, and set SELCTXT at ECS DEBUG Level to specify
which context store to access.
Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
*/
npe_cmd_write(npe, ECS_DBG_CTXT_REG_1, CMD_WR_ECS_REG,
(ctx << ECS_REG_1_CCTXT_BITS) |
(ctx << ECS_REG_1_SELCTXT_BITS));
/* clear the pipeline */
__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
/* load NPE instruction into the instruction register */
npe_cmd_write(npe, ECS_INSTRUCT_REG, CMD_WR_ECS_REG, instr);
/* we need this value later to wait for completion of NPE execution
step */
wc = __raw_readl(&npe->regs->watch_count);
/* issue a Step One command via the Execution Control register */
__raw_writel(CMD_NPE_STEP, &npe->regs->exec_status_cmd);
/* Watch Count register increments when NPE completes an instruction */
for (i = 0; i < MAX_RETRIES; i++) {
if (wc != __raw_readl(&npe->regs->watch_count))
return 0;
udelay(1);
}
print_npe(KERN_ERR, npe, "reset: npe_debug_instr(): timeout\n");
return -ETIMEDOUT;
}
static int __must_check npe_logical_reg_write8(struct npe *npe, u32 addr,
u8 val, u32 ctx)
{
/* here we build the NPE assembler instruction: mov8 d0, #0 */
u32 instr = INSTR_WR_REG_BYTE | /* OpCode */
addr << 9 | /* base Operand */
(val & 0x1F) << 4 | /* lower 5 bits to immediate data */
(val & ~0x1F) << (18 - 5);/* higher 3 bits to CoProc instr. */
return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
}
static int __must_check npe_logical_reg_write16(struct npe *npe, u32 addr,
u16 val, u32 ctx)
{
/* here we build the NPE assembler instruction: mov16 d0, #0 */
u32 instr = INSTR_WR_REG_SHORT | /* OpCode */
addr << 9 | /* base Operand */
(val & 0x1F) << 4 | /* lower 5 bits to immediate data */
(val & ~0x1F) << (18 - 5);/* higher 11 bits to CoProc instr. */
return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
}
static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr,
u32 val, u32 ctx)
{
/* write in 16 bit steps first the high and then the low value */
if (npe_logical_reg_write16(npe, addr, val >> 16, ctx))
return -ETIMEDOUT;
return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx);
}
static int npe_reset(struct npe *npe)
{
u32 val, ctl, exec_count, ctx_reg2;
int i;
ctl = (__raw_readl(&npe->regs->messaging_control) | 0x3F000000) &
0x3F3FFFFF;
/* disable parity interrupt */
__raw_writel(ctl & 0x3F00FFFF, &npe->regs->messaging_control);
/* pre exec - debug instruction */
/* turn off the halt bit by clearing Execution Count register. */
exec_count = __raw_readl(&npe->regs->exec_count);
__raw_writel(0, &npe->regs->exec_count);
/* ensure that IF and IE are on (temporarily), so that we don't end up
stepping forever */
ctx_reg2 = npe_cmd_read(npe, ECS_DBG_CTXT_REG_2, CMD_RD_ECS_REG);
npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2 |
ECS_DBG_REG_2_IF | ECS_DBG_REG_2_IE);
/* clear the FIFOs */
while (__raw_readl(&npe->regs->watchpoint_fifo) & WFIFO_VALID)
;
while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE)
/* read from the outFIFO until empty */
print_npe(KERN_DEBUG, npe, "npe_reset: read FIFO = 0x%X\n",
__raw_readl(&npe->regs->in_out_fifo));
while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)
/* step execution of the NPE intruction to read inFIFO using
the Debug Executing Context stack */
if (npe_debug_instr(npe, INSTR_RD_FIFO, 0, 0))
return -ETIMEDOUT;
/* reset the mailbox reg from the XScale side */
__raw_writel(RESET_MBOX_STAT, &npe->regs->mailbox_status);
/* from NPE side */
if (npe_debug_instr(npe, INSTR_RESET_MBOX, 0, 0))
return -ETIMEDOUT;
/* Reset the physical registers in the NPE register file */
for (val = 0; val < NPE_PHYS_REG; val++) {
if (npe_logical_reg_write16(npe, NPE_REGMAP, val >> 1, 0))
return -ETIMEDOUT;
/* address is either 0 or 4 */
if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0))
return -ETIMEDOUT;
}
/* Reset the context store = each context's Context Store registers */
/* Context 0 has no STARTPC. Instead, this value is used to set NextPC
for Background ECS, to set where NPE starts executing code */
val = npe_cmd_read(npe, ECS_BG_CTXT_REG_0, CMD_RD_ECS_REG);
val &= ~ECS_REG_0_NEXTPC_MASK;
val |= (0 /* NextPC */ << 16) & ECS_REG_0_NEXTPC_MASK;
npe_cmd_write(npe, ECS_BG_CTXT_REG_0, CMD_WR_ECS_REG, val);
for (i = 0; i < 16; i++) {
if (i) { /* Context 0 has no STEVT nor STARTPC */
/* STEVT = off, 0x80 */
if (npe_logical_reg_write8(npe, NPE_STEVT, 0x80, i))
return -ETIMEDOUT;
if (npe_logical_reg_write16(npe, NPE_STARTPC, 0, i))
return -ETIMEDOUT;
}
/* REGMAP = d0->p0, d8->p2, d16->p4 */
if (npe_logical_reg_write16(npe, NPE_REGMAP, 0x820, i))
return -ETIMEDOUT;
if (npe_logical_reg_write8(npe, NPE_CINDEX, 0, i))
return -ETIMEDOUT;
}
/* post exec */
/* clear active bit in debug level */
npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, 0);
/* clear the pipeline */
__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
/* restore previous values */
__raw_writel(exec_count, &npe->regs->exec_count);
npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2);
/* write reset values to Execution Context Stack registers */
for (val = 0; val < ARRAY_SIZE(ecs_reset); val++)
npe_cmd_write(npe, ecs_reset[val].reg, CMD_WR_ECS_REG,
ecs_reset[val].val);
/* clear the profile counter */
__raw_writel(CMD_CLR_PROFILE_CNT, &npe->regs->exec_status_cmd);
__raw_writel(0, &npe->regs->exec_count);
__raw_writel(0, &npe->regs->action_points[0]);
__raw_writel(0, &npe->regs->action_points[1]);
__raw_writel(0, &npe->regs->action_points[2]);
__raw_writel(0, &npe->regs->action_points[3]);
__raw_writel(0, &npe->regs->watch_count);
val = ixp4xx_read_feature_bits();
/* reset the NPE */
ixp4xx_write_feature_bits(val &
~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
/* deassert reset */
ixp4xx_write_feature_bits(val |
(IXP4XX_FEATURE_RESET_NPEA << npe->id));
for (i = 0; i < MAX_RETRIES; i++) {
if (ixp4xx_read_feature_bits() &
(IXP4XX_FEATURE_RESET_NPEA << npe->id))
break; /* NPE is back alive */
udelay(1);
}
if (i == MAX_RETRIES)
return -ETIMEDOUT;
npe_stop(npe);
/* restore NPE configuration bus Control Register - parity settings */
__raw_writel(ctl, &npe->regs->messaging_control);
return 0;
}
int npe_send_message(struct npe *npe, const void *msg, const char *what)
{
const u32 *send = msg;
int cycles = 0;
debug_msg(npe, "Trying to send message %s [%08X:%08X]\n",
what, send[0], send[1]);
if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) {
debug_msg(npe, "NPE input FIFO not empty\n");
return -EIO;
}
__raw_writel(send[0], &npe->regs->in_out_fifo);
if (!(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNF)) {
debug_msg(npe, "NPE input FIFO full\n");
return -EIO;
}
__raw_writel(send[1], &npe->regs->in_out_fifo);
while ((cycles < MAX_RETRIES) &&
(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)) {
udelay(1);
cycles++;
}
if (cycles == MAX_RETRIES) {
debug_msg(npe, "Timeout sending message\n");
return -ETIMEDOUT;
}
#if DEBUG_MSG > 1
debug_msg(npe, "Sending a message took %i cycles\n", cycles);
#endif
return 0;
}
int npe_recv_message(struct npe *npe, void *msg, const char *what)
{
u32 *recv = msg;
int cycles = 0, cnt = 0;
debug_msg(npe, "Trying to receive message %s\n", what);
while (cycles < MAX_RETRIES) {
if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) {
recv[cnt++] = __raw_readl(&npe->regs->in_out_fifo);
if (cnt == 2)
break;
} else {
udelay(1);
cycles++;
}
}
switch(cnt) {
case 1:
debug_msg(npe, "Received [%08X]\n", recv[0]);
break;
case 2:
debug_msg(npe, "Received [%08X:%08X]\n", recv[0], recv[1]);
break;
}
if (cycles == MAX_RETRIES) {
debug_msg(npe, "Timeout waiting for message\n");
return -ETIMEDOUT;
}
#if DEBUG_MSG > 1
debug_msg(npe, "Receiving a message took %i cycles\n", cycles);
#endif
return 0;
}
int npe_send_recv_message(struct npe *npe, void *msg, const char *what)
{
int result;
u32 *send = msg, recv[2];
if ((result = npe_send_message(npe, msg, what)) != 0)
return result;
if ((result = npe_recv_message(npe, recv, what)) != 0)
return result;
if ((recv[0] != send[0]) || (recv[1] != send[1])) {
debug_msg(npe, "Message %s: unexpected message received\n",
what);
return -EIO;
}
return 0;
}
int npe_load_firmware(struct npe *npe, const char *name, struct device *dev)
{
const struct firmware *fw_entry;
struct dl_block {
u32 type;
u32 offset;
} *blk;
struct dl_image {
u32 magic;
u32 id;
u32 size;
union {
u32 data[0];
struct dl_block blocks[0];
};
} *image;
struct dl_codeblock {
u32 npe_addr;
u32 size;
u32 data[0];
} *cb;
int i, j, err, data_size, instr_size, blocks, table_end;
u32 cmd;
if ((err = request_firmware(&fw_entry, name, dev)) != 0)
return err;
err = -EINVAL;
if (fw_entry->size < sizeof(struct dl_image)) {
print_npe(KERN_ERR, npe, "incomplete firmware file\n");
goto err;
}
image = (struct dl_image*)fw_entry->data;
#if DEBUG_FW
print_npe(KERN_DEBUG, npe, "firmware: %08X %08X %08X (0x%X bytes)\n",
image->magic, image->id, image->size, image->size * 4);
#endif
if (image->magic == swab32(FW_MAGIC)) { /* swapped file */
image->id = swab32(image->id);
image->size = swab32(image->size);
} else if (image->magic != FW_MAGIC) {
print_npe(KERN_ERR, npe, "bad firmware file magic: 0x%X\n",
image->magic);
goto err;
}
if ((image->size * 4 + sizeof(struct dl_image)) != fw_entry->size) {
print_npe(KERN_ERR, npe,
"inconsistent size of firmware file\n");
goto err;
}
if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) {
print_npe(KERN_ERR, npe, "firmware file NPE ID mismatch\n");
goto err;
}
if (image->magic == swab32(FW_MAGIC))
for (i = 0; i < image->size; i++)
image->data[i] = swab32(image->data[i]);
if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
print_npe(KERN_INFO, npe, "IXP43x/IXP46x firmware ignored on "
"IXP42x\n");
goto err;
}
if (npe_running(npe)) {
print_npe(KERN_INFO, npe, "unable to load firmware, NPE is "
"already running\n");
err = -EBUSY;
goto err;
}
#if 0
npe_stop(npe);
npe_reset(npe);
#endif
print_npe(KERN_INFO, npe, "firmware functionality 0x%X, "
"revision 0x%X:%X\n", (image->id >> 16) & 0xFF,
(image->id >> 8) & 0xFF, image->id & 0xFF);
if (cpu_is_ixp42x()) {
if (!npe->id)
instr_size = NPE_A_42X_INSTR_SIZE;
else
instr_size = NPE_B_AND_C_42X_INSTR_SIZE;
data_size = NPE_42X_DATA_SIZE;
} else {
instr_size = NPE_46X_INSTR_SIZE;
data_size = NPE_46X_DATA_SIZE;
}
for (blocks = 0; blocks * sizeof(struct dl_block) / 4 < image->size;
blocks++)
if (image->blocks[blocks].type == FW_BLOCK_TYPE_EOF)
break;
if (blocks * sizeof(struct dl_block) / 4 >= image->size) {
print_npe(KERN_INFO, npe, "firmware EOF block marker not "
"found\n");
goto err;
}
#if DEBUG_FW
print_npe(KERN_DEBUG, npe, "%i firmware blocks found\n", blocks);
#endif
table_end = blocks * sizeof(struct dl_block) / 4 + 1 /* EOF marker */;
for (i = 0, blk = image->blocks; i < blocks; i++, blk++) {
if (blk->offset > image->size - sizeof(struct dl_codeblock) / 4
|| blk->offset < table_end) {
print_npe(KERN_INFO, npe, "invalid offset 0x%X of "
"firmware block #%i\n", blk->offset, i);
goto err;
}
cb = (struct dl_codeblock*)&image->data[blk->offset];
if (blk->type == FW_BLOCK_TYPE_INSTR) {
if (cb->npe_addr + cb->size > instr_size)
goto too_big;
cmd = CMD_WR_INS_MEM;
} else if (blk->type == FW_BLOCK_TYPE_DATA) {
if (cb->npe_addr + cb->size > data_size)
goto too_big;
cmd = CMD_WR_DATA_MEM;
} else {
print_npe(KERN_INFO, npe, "invalid firmware block #%i "
"type 0x%X\n", i, blk->type);
goto err;
}
if (blk->offset + sizeof(*cb) / 4 + cb->size > image->size) {
print_npe(KERN_INFO, npe, "firmware block #%i doesn't "
"fit in firmware image: type %c, start 0x%X,"
" length 0x%X\n", i,
blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
cb->npe_addr, cb->size);
goto err;
}
for (j = 0; j < cb->size; j++)
npe_cmd_write(npe, cb->npe_addr + j, cmd, cb->data[j]);
}
npe_start(npe);
if (!npe_running(npe))
print_npe(KERN_ERR, npe, "unable to start\n");
release_firmware(fw_entry);
return 0;
too_big:
print_npe(KERN_INFO, npe, "firmware block #%i doesn't fit in NPE "
"memory: type %c, start 0x%X, length 0x%X\n", i,
blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
cb->npe_addr, cb->size);
err:
release_firmware(fw_entry);
return err;
}
struct npe *npe_request(int id)
{
if (id < NPE_COUNT)
if (npe_tab[id].valid)
if (try_module_get(THIS_MODULE))
return &npe_tab[id];
return NULL;
}
void npe_release(struct npe *npe)
{
module_put(THIS_MODULE);
}
static int __init npe_init_module(void)
{
int i, found = 0;
for (i = 0; i < NPE_COUNT; i++) {
struct npe *npe = &npe_tab[i];
if (!(ixp4xx_read_feature_bits() &
(IXP4XX_FEATURE_RESET_NPEA << i)))
continue; /* NPE already disabled or not present */
if (!(npe->mem_res = request_mem_region(npe->regs_phys,
REGS_SIZE,
npe_name(npe)))) {
print_npe(KERN_ERR, npe,
"failed to request memory region\n");
continue;
}
if (npe_reset(npe))
continue;
npe->valid = 1;
found++;
}
if (!found)
return -ENODEV;
return 0;
}
static void __exit npe_cleanup_module(void)
{
int i;
for (i = 0; i < NPE_COUNT; i++)
if (npe_tab[i].mem_res) {
npe_reset(&npe_tab[i]);
release_resource(npe_tab[i].mem_res);
}
}
module_init(npe_init_module);
module_exit(npe_cleanup_module);
MODULE_AUTHOR("Krzysztof Halasa");
MODULE_LICENSE("GPL v2");
EXPORT_SYMBOL(npe_names);
EXPORT_SYMBOL(npe_running);
EXPORT_SYMBOL(npe_request);
EXPORT_SYMBOL(npe_release);
EXPORT_SYMBOL(npe_load_firmware);
EXPORT_SYMBOL(npe_send_message);
EXPORT_SYMBOL(npe_recv_message);
EXPORT_SYMBOL(npe_send_recv_message);

View File

@@ -0,0 +1,381 @@
/*
* Intel IXP4xx Queue Manager driver for Linux
*
* Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*/
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <mach/qmgr.h>
struct qmgr_regs __iomem *qmgr_regs;
static struct resource *mem_res;
static spinlock_t qmgr_lock;
static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
static void (*irq_handlers[QUEUES])(void *pdev);
static void *irq_pdevs[QUEUES];
#if DEBUG_QMGR
char qmgr_queue_descs[QUEUES][32];
#endif
void qmgr_set_irq(unsigned int queue, int src,
void (*handler)(void *pdev), void *pdev)
{
unsigned long flags;
spin_lock_irqsave(&qmgr_lock, flags);
if (queue < HALF_QUEUES) {
u32 __iomem *reg;
int bit;
BUG_ON(src > QUEUE_IRQ_SRC_NOT_FULL);
reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */
bit = (queue % 8) * 4; /* 3 bits + 1 reserved bit per queue */
__raw_writel((__raw_readl(reg) & ~(7 << bit)) | (src << bit),
reg);
} else
/* IRQ source for queues 32-63 is fixed */
BUG_ON(src != QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY);
irq_handlers[queue] = handler;
irq_pdevs[queue] = pdev;
spin_unlock_irqrestore(&qmgr_lock, flags);
}
static irqreturn_t qmgr_irq1_a0(int irq, void *pdev)
{
int i, ret = 0;
u32 en_bitmap, src, stat;
/* ACK - it may clear any bits so don't rely on it */
__raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]);
en_bitmap = qmgr_regs->irqen[0];
while (en_bitmap) {
i = __fls(en_bitmap); /* number of the last "low" queue */
en_bitmap &= ~BIT(i);
src = qmgr_regs->irqsrc[i >> 3];
stat = qmgr_regs->stat1[i >> 3];
if (src & 4) /* the IRQ condition is inverted */
stat = ~stat;
if (stat & BIT(src & 3)) {
irq_handlers[i](irq_pdevs[i]);
ret = IRQ_HANDLED;
}
}
return ret;
}
static irqreturn_t qmgr_irq2_a0(int irq, void *pdev)
{
int i, ret = 0;
u32 req_bitmap;
/* ACK - it may clear any bits so don't rely on it */
__raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[1]);
req_bitmap = qmgr_regs->irqen[1] & qmgr_regs->statne_h;
while (req_bitmap) {
i = __fls(req_bitmap); /* number of the last "high" queue */
req_bitmap &= ~BIT(i);
irq_handlers[HALF_QUEUES + i](irq_pdevs[HALF_QUEUES + i]);
ret = IRQ_HANDLED;
}
return ret;
}
static irqreturn_t qmgr_irq(int irq, void *pdev)
{
int i, half = (irq == IRQ_IXP4XX_QM1 ? 0 : 1);
u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]);
if (!req_bitmap)
return 0;
__raw_writel(req_bitmap, &qmgr_regs->irqstat[half]); /* ACK */
while (req_bitmap) {
i = __fls(req_bitmap); /* number of the last queue */
req_bitmap &= ~BIT(i);
i += half * HALF_QUEUES;
irq_handlers[i](irq_pdevs[i]);
}
return IRQ_HANDLED;
}
void qmgr_enable_irq(unsigned int queue)
{
unsigned long flags;
int half = queue / 32;
u32 mask = 1 << (queue & (HALF_QUEUES - 1));
spin_lock_irqsave(&qmgr_lock, flags);
__raw_writel(__raw_readl(&qmgr_regs->irqen[half]) | mask,
&qmgr_regs->irqen[half]);
spin_unlock_irqrestore(&qmgr_lock, flags);
}
void qmgr_disable_irq(unsigned int queue)
{
unsigned long flags;
int half = queue / 32;
u32 mask = 1 << (queue & (HALF_QUEUES - 1));
spin_lock_irqsave(&qmgr_lock, flags);
__raw_writel(__raw_readl(&qmgr_regs->irqen[half]) & ~mask,
&qmgr_regs->irqen[half]);
__raw_writel(mask, &qmgr_regs->irqstat[half]); /* clear */
spin_unlock_irqrestore(&qmgr_lock, flags);
}
static inline void shift_mask(u32 *mask)
{
mask[3] = mask[3] << 1 | mask[2] >> 31;
mask[2] = mask[2] << 1 | mask[1] >> 31;
mask[1] = mask[1] << 1 | mask[0] >> 31;
mask[0] <<= 1;
}
#if DEBUG_QMGR
int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
unsigned int nearly_empty_watermark,
unsigned int nearly_full_watermark,
const char *desc_format, const char* name)
#else
int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
unsigned int nearly_empty_watermark,
unsigned int nearly_full_watermark)
#endif
{
u32 cfg, addr = 0, mask[4]; /* in 16-dwords */
int err;
BUG_ON(queue >= QUEUES);
if ((nearly_empty_watermark | nearly_full_watermark) & ~7)
return -EINVAL;
switch (len) {
case 16:
cfg = 0 << 24;
mask[0] = 0x1;
break;
case 32:
cfg = 1 << 24;
mask[0] = 0x3;
break;
case 64:
cfg = 2 << 24;
mask[0] = 0xF;
break;
case 128:
cfg = 3 << 24;
mask[0] = 0xFF;
break;
default:
return -EINVAL;
}
cfg |= nearly_empty_watermark << 26;
cfg |= nearly_full_watermark << 29;
len /= 16; /* in 16-dwords: 1, 2, 4 or 8 */
mask[1] = mask[2] = mask[3] = 0;
if (!try_module_get(THIS_MODULE))
return -ENODEV;
spin_lock_irq(&qmgr_lock);
if (__raw_readl(&qmgr_regs->sram[queue])) {
err = -EBUSY;
goto err;
}
while (1) {
if (!(used_sram_bitmap[0] & mask[0]) &&
!(used_sram_bitmap[1] & mask[1]) &&
!(used_sram_bitmap[2] & mask[2]) &&
!(used_sram_bitmap[3] & mask[3]))
break; /* found free space */
addr++;
shift_mask(mask);
if (addr + len > ARRAY_SIZE(qmgr_regs->sram)) {
printk(KERN_ERR "qmgr: no free SRAM space for"
" queue %i\n", queue);
err = -ENOMEM;
goto err;
}
}
used_sram_bitmap[0] |= mask[0];
used_sram_bitmap[1] |= mask[1];
used_sram_bitmap[2] |= mask[2];
used_sram_bitmap[3] |= mask[3];
__raw_writel(cfg | (addr << 14), &qmgr_regs->sram[queue]);
#if DEBUG_QMGR
snprintf(qmgr_queue_descs[queue], sizeof(qmgr_queue_descs[0]),
desc_format, name);
printk(KERN_DEBUG "qmgr: requested queue %s(%i) addr = 0x%02X\n",
qmgr_queue_descs[queue], queue, addr);
#endif
spin_unlock_irq(&qmgr_lock);
return 0;
err:
spin_unlock_irq(&qmgr_lock);
module_put(THIS_MODULE);
return err;
}
void qmgr_release_queue(unsigned int queue)
{
u32 cfg, addr, mask[4];
BUG_ON(queue >= QUEUES); /* not in valid range */
spin_lock_irq(&qmgr_lock);
cfg = __raw_readl(&qmgr_regs->sram[queue]);
addr = (cfg >> 14) & 0xFF;
BUG_ON(!addr); /* not requested */
switch ((cfg >> 24) & 3) {
case 0: mask[0] = 0x1; break;
case 1: mask[0] = 0x3; break;
case 2: mask[0] = 0xF; break;
case 3: mask[0] = 0xFF; break;
}
mask[1] = mask[2] = mask[3] = 0;
while (addr--)
shift_mask(mask);
#if DEBUG_QMGR
printk(KERN_DEBUG "qmgr: releasing queue %s(%i)\n",
qmgr_queue_descs[queue], queue);
qmgr_queue_descs[queue][0] = '\x0';
#endif
__raw_writel(0, &qmgr_regs->sram[queue]);
used_sram_bitmap[0] &= ~mask[0];
used_sram_bitmap[1] &= ~mask[1];
used_sram_bitmap[2] &= ~mask[2];
used_sram_bitmap[3] &= ~mask[3];
irq_handlers[queue] = NULL; /* catch IRQ bugs */
spin_unlock_irq(&qmgr_lock);
module_put(THIS_MODULE);
while ((addr = qmgr_get_entry(queue)))
printk(KERN_ERR "qmgr: released queue %i not empty: 0x%08X\n",
queue, addr);
}
static int qmgr_init(void)
{
int i, err;
irq_handler_t handler1, handler2;
mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS,
IXP4XX_QMGR_REGION_SIZE,
"IXP4xx Queue Manager");
if (mem_res == NULL)
return -EBUSY;
qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
if (qmgr_regs == NULL) {
err = -ENOMEM;
goto error_map;
}
/* reset qmgr registers */
for (i = 0; i < 4; i++) {
__raw_writel(0x33333333, &qmgr_regs->stat1[i]);
__raw_writel(0, &qmgr_regs->irqsrc[i]);
}
for (i = 0; i < 2; i++) {
__raw_writel(0, &qmgr_regs->stat2[i]);
__raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[i]); /* clear */
__raw_writel(0, &qmgr_regs->irqen[i]);
}
__raw_writel(0xFFFFFFFF, &qmgr_regs->statne_h);
__raw_writel(0, &qmgr_regs->statf_h);
for (i = 0; i < QUEUES; i++)
__raw_writel(0, &qmgr_regs->sram[i]);
if (cpu_is_ixp42x_rev_a0()) {
handler1 = qmgr_irq1_a0;
handler2 = qmgr_irq2_a0;
} else
handler1 = handler2 = qmgr_irq;
err = request_irq(IRQ_IXP4XX_QM1, handler1, 0, "IXP4xx Queue Manager",
NULL);
if (err) {
printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n",
IRQ_IXP4XX_QM1, err);
goto error_irq;
}
err = request_irq(IRQ_IXP4XX_QM2, handler2, 0, "IXP4xx Queue Manager",
NULL);
if (err) {
printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n",
IRQ_IXP4XX_QM2, err);
goto error_irq2;
}
used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
spin_lock_init(&qmgr_lock);
printk(KERN_INFO "IXP4xx Queue Manager initialized.\n");
return 0;
error_irq2:
free_irq(IRQ_IXP4XX_QM1, NULL);
error_irq:
iounmap(qmgr_regs);
error_map:
release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
return err;
}
static void qmgr_remove(void)
{
free_irq(IRQ_IXP4XX_QM1, NULL);
free_irq(IRQ_IXP4XX_QM2, NULL);
synchronize_irq(IRQ_IXP4XX_QM1);
synchronize_irq(IRQ_IXP4XX_QM2);
iounmap(qmgr_regs);
release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
}
module_init(qmgr_init);
module_exit(qmgr_remove);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Krzysztof Halasa");
EXPORT_SYMBOL(qmgr_regs);
EXPORT_SYMBOL(qmgr_set_irq);
EXPORT_SYMBOL(qmgr_enable_irq);
EXPORT_SYMBOL(qmgr_disable_irq);
#if DEBUG_QMGR
EXPORT_SYMBOL(qmgr_queue_descs);
EXPORT_SYMBOL(qmgr_request_queue);
#else
EXPORT_SYMBOL(__qmgr_request_queue);
#endif
EXPORT_SYMBOL(qmgr_release_queue);

View File

@@ -0,0 +1,71 @@
/*
* arch/arm/mach-ixp4xx/nas100d-pci.c
*
* NAS 100d board-level PCI initialization
*
* based on ixdp425-pci.c:
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*
* Maintainer: http://www.nslu2-linux.org/
*
* 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>
void __init nas100d_pci_preinit(void)
{
set_irq_type(IRQ_NAS100D_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_NAS100D_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_NAS100D_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_NAS100D_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_NAS100D_PCI_INTE, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init nas100d_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static int pci_irq_table[NAS100D_PCI_MAX_DEV][NAS100D_PCI_IRQ_LINES] =
{
{ IRQ_NAS100D_PCI_INTA, -1, -1 },
{ IRQ_NAS100D_PCI_INTB, -1, -1 },
{ IRQ_NAS100D_PCI_INTC, IRQ_NAS100D_PCI_INTD, IRQ_NAS100D_PCI_INTE },
};
int irq = -1;
if (slot >= 1 && slot <= NAS100D_PCI_MAX_DEV &&
pin >= 1 && pin <= NAS100D_PCI_IRQ_LINES)
irq = pci_irq_table[slot-1][pin-1];
return irq;
}
struct hw_pci __initdata nas100d_pci = {
.nr_controllers = 1,
.preinit = nas100d_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = nas100d_map_irq,
};
int __init nas100d_pci_init(void)
{
if (machine_is_nas100d())
pci_common_init(&nas100d_pci);
return 0;
}
subsys_initcall(nas100d_pci_init);

View File

@@ -0,0 +1,310 @@
/*
* arch/arm/mach-ixp4xx/nas100d-setup.c
*
* NAS 100d board-setup
*
* Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
*
* based on ixdp425-setup.c:
* Copyright (C) 2003-2004 MontaVista Software, Inc.
* based on nas100d-power.c:
* Copyright (C) 2005 Tower Technologies
* based on nas100d-io.c
* Copyright (C) 2004 Karen Spearel
*
* Author: Alessandro Zummo <a.zummo@towertech.it>
* Author: Rod Whitby <rod@whitby.id.au>
* Maintainers: http://www.nslu2-linux.org/
*
*/
#include <linux/if_ether.h>
#include <linux/irq.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/leds.h>
#include <linux/reboot.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/io.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/gpio.h>
static struct flash_platform_data nas100d_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource nas100d_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device nas100d_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev.platform_data = &nas100d_flash_data,
.num_resources = 1,
.resource = &nas100d_flash_resource,
};
static struct i2c_board_info __initdata nas100d_i2c_board_info [] = {
{
I2C_BOARD_INFO("pcf8563", 0x51),
},
};
static struct gpio_led nas100d_led_pins[] = {
{
.name = "nas100d:green:wlan",
.gpio = NAS100D_LED_WLAN_GPIO,
.active_low = true,
},
{
.name = "nas100d:blue:power", /* (off=flashing) */
.gpio = NAS100D_LED_PWR_GPIO,
.active_low = true,
},
{
.name = "nas100d:yellow:disk",
.gpio = NAS100D_LED_DISK_GPIO,
.active_low = true,
},
};
static struct gpio_led_platform_data nas100d_led_data = {
.num_leds = ARRAY_SIZE(nas100d_led_pins),
.leds = nas100d_led_pins,
};
static struct platform_device nas100d_leds = {
.name = "leds-gpio",
.id = -1,
.dev.platform_data = &nas100d_led_data,
};
static struct i2c_gpio_platform_data nas100d_i2c_gpio_data = {
.sda_pin = NAS100D_SDA_PIN,
.scl_pin = NAS100D_SCL_PIN,
};
static struct platform_device nas100d_i2c_gpio = {
.name = "i2c-gpio",
.id = 0,
.dev = {
.platform_data = &nas100d_i2c_gpio_data,
},
};
static struct resource nas100d_uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
}
};
static struct plat_serial8250_port nas100d_uart_data[] = {
{
.mapbase = IXP4XX_UART1_BASE_PHYS,
.membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART1,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{
.mapbase = IXP4XX_UART2_BASE_PHYS,
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART2,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{ }
};
static struct platform_device nas100d_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = nas100d_uart_data,
.num_resources = 2,
.resource = nas100d_uart_resources,
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct eth_plat_info nas100d_plat_eth[] = {
{
.phy = 0,
.rxq = 3,
.txreadyq = 20,
}
};
static struct platform_device nas100d_eth[] = {
{
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = nas100d_plat_eth,
}
};
static struct platform_device *nas100d_devices[] __initdata = {
&nas100d_i2c_gpio,
&nas100d_flash,
&nas100d_leds,
&nas100d_eth[0],
};
static void nas100d_power_off(void)
{
/* This causes the box to drop the power and go dead. */
/* enable the pwr cntl gpio */
gpio_line_config(NAS100D_PO_GPIO, IXP4XX_GPIO_OUT);
/* do the deed */
gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH);
}
/* This is used to make sure the power-button pusher is serious. The button
* must be held until the value of this counter reaches zero.
*/
static int power_button_countdown;
/* Must hold the button down for at least this many counts to be processed */
#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
static void nas100d_power_handler(unsigned long data);
static DEFINE_TIMER(nas100d_power_timer, nas100d_power_handler, 0, 0);
static void nas100d_power_handler(unsigned long data)
{
/* This routine is called twice per second to check the
* state of the power button.
*/
if (gpio_get_value(NAS100D_PB_GPIO)) {
/* IO Pin is 1 (button pushed) */
if (power_button_countdown > 0)
power_button_countdown--;
} else {
/* Done on button release, to allow for auto-power-on mods. */
if (power_button_countdown == 0) {
/* Signal init to do the ctrlaltdel action,
* this will bypass init if it hasn't started
* and do a kernel_restart.
*/
ctrl_alt_del();
/* Change the state of the power LED to "blink" */
gpio_line_set(NAS100D_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
} else {
power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
}
}
mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
}
static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
{
/* This is the paper-clip reset, it shuts the machine down directly. */
machine_power_off();
return IRQ_HANDLED;
}
static void __init nas100d_init(void)
{
uint8_t __iomem *f;
int i;
ixp4xx_sys_init();
/* gpio 14 and 15 are _not_ clocks */
*IXP4XX_GPIO_GPCLKR = 0;
nas100d_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
nas100d_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
i2c_register_board_info(0, nas100d_i2c_board_info,
ARRAY_SIZE(nas100d_i2c_board_info));
/*
* This is only useful on a modified machine, but it is valuable
* to have it first in order to see debug messages, and so that
* it does *not* get removed if platform_add_devices fails!
*/
(void)platform_device_register(&nas100d_uart);
platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
pm_power_off = nas100d_power_off;
if (request_irq(gpio_to_irq(NAS100D_RB_GPIO), &nas100d_reset_handler,
IRQF_DISABLED | IRQF_TRIGGER_LOW,
"NAS100D reset button", NULL) < 0) {
printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
gpio_to_irq(NAS100D_RB_GPIO));
}
/* The power button on the Iomega NAS100d is on GPIO 14, but
* it cannot handle interrupts on that GPIO line. So we'll
* have to poll it with a kernel timer.
*/
/* Make sure that the power button GPIO is set up as an input */
gpio_line_config(NAS100D_PB_GPIO, IXP4XX_GPIO_IN);
/* Set the initial value for the power button IRQ handler */
power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
/*
* Map in a portion of the flash and read the MAC address.
* Since it is stored in BE in the flash itself, we need to
* byteswap it if we're in LE mode.
*/
f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x1000000);
if (f) {
for (i = 0; i < 6; i++)
#ifdef __ARMEB__
nas100d_plat_eth[0].hwaddr[i] = readb(f + 0xFC0FD8 + i);
#else
nas100d_plat_eth[0].hwaddr[i] = readb(f + 0xFC0FD8 + (i^3));
#endif
iounmap(f);
}
printk(KERN_INFO "NAS100D: Using MAC address %pM for port 0\n",
nas100d_plat_eth[0].hwaddr);
}
MACHINE_START(NAS100D, "Iomega NAS 100d")
/* Maintainer: www.nslu2-linux.org */
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.init_machine = nas100d_init,
MACHINE_END

View File

@@ -0,0 +1,69 @@
/*
* arch/arm/mach-ixp4xx/nslu2-pci.c
*
* NSLU2 board-level PCI initialization
*
* based on ixdp425-pci.c:
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*
* Maintainer: http://www.nslu2-linux.org/
*
* 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>
void __init nslu2_pci_preinit(void)
{
set_irq_type(IRQ_NSLU2_PCI_INTA, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_NSLU2_PCI_INTB, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_NSLU2_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = {
IRQ_NSLU2_PCI_INTA,
IRQ_NSLU2_PCI_INTB,
IRQ_NSLU2_PCI_INTC,
};
int irq = -1;
if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV &&
pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) {
irq = pci_irq_table[(slot + pin - 2) % NSLU2_PCI_IRQ_LINES];
}
return irq;
}
struct hw_pci __initdata nslu2_pci = {
.nr_controllers = 1,
.preinit = nslu2_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = nslu2_map_irq,
};
int __init nslu2_pci_init(void) /* monkey see, monkey do */
{
if (machine_is_nslu2())
pci_common_init(&nslu2_pci);
return 0;
}
subsys_initcall(nslu2_pci_init);

View File

@@ -0,0 +1,291 @@
/*
* arch/arm/mach-ixp4xx/nslu2-setup.c
*
* NSLU2 board-setup
*
* Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
*
* based on ixdp425-setup.c:
* Copyright (C) 2003-2004 MontaVista Software, Inc.
* based on nslu2-power.c:
* Copyright (C) 2005 Tower Technologies
*
* Author: Mark Rakes <mrakes at mac.com>
* Author: Rod Whitby <rod@whitby.id.au>
* Author: Alessandro Zummo <a.zummo@towertech.it>
* Maintainers: http://www.nslu2-linux.org/
*
*/
#include <linux/if_ether.h>
#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/leds.h>
#include <linux/reboot.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/io.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/time.h>
#include <asm/gpio.h>
static struct flash_platform_data nslu2_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource nslu2_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device nslu2_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev.platform_data = &nslu2_flash_data,
.num_resources = 1,
.resource = &nslu2_flash_resource,
};
static struct i2c_gpio_platform_data nslu2_i2c_gpio_data = {
.sda_pin = NSLU2_SDA_PIN,
.scl_pin = NSLU2_SCL_PIN,
};
static struct i2c_board_info __initdata nslu2_i2c_board_info [] = {
{
I2C_BOARD_INFO("x1205", 0x6f),
},
};
static struct gpio_led nslu2_led_pins[] = {
{
.name = "nslu2:green:ready",
.gpio = NSLU2_LED_GRN_GPIO,
},
{
.name = "nslu2:red:status",
.gpio = NSLU2_LED_RED_GPIO,
},
{
.name = "nslu2:green:disk-1",
.gpio = NSLU2_LED_DISK1_GPIO,
.active_low = true,
},
{
.name = "nslu2:green:disk-2",
.gpio = NSLU2_LED_DISK2_GPIO,
.active_low = true,
},
};
static struct gpio_led_platform_data nslu2_led_data = {
.num_leds = ARRAY_SIZE(nslu2_led_pins),
.leds = nslu2_led_pins,
};
static struct platform_device nslu2_leds = {
.name = "leds-gpio",
.id = -1,
.dev.platform_data = &nslu2_led_data,
};
static struct platform_device nslu2_i2c_gpio = {
.name = "i2c-gpio",
.id = 0,
.dev = {
.platform_data = &nslu2_i2c_gpio_data,
},
};
static struct platform_device nslu2_beeper = {
.name = "ixp4xx-beeper",
.id = NSLU2_GPIO_BUZZ,
.num_resources = 0,
};
static struct resource nslu2_uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
}
};
static struct plat_serial8250_port nslu2_uart_data[] = {
{
.mapbase = IXP4XX_UART1_BASE_PHYS,
.membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART1,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{
.mapbase = IXP4XX_UART2_BASE_PHYS,
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART2,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{ }
};
static struct platform_device nslu2_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = nslu2_uart_data,
.num_resources = 2,
.resource = nslu2_uart_resources,
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct eth_plat_info nslu2_plat_eth[] = {
{
.phy = 1,
.rxq = 3,
.txreadyq = 20,
}
};
static struct platform_device nslu2_eth[] = {
{
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = nslu2_plat_eth,
}
};
static struct platform_device *nslu2_devices[] __initdata = {
&nslu2_i2c_gpio,
&nslu2_flash,
&nslu2_beeper,
&nslu2_leds,
&nslu2_eth[0],
};
static void nslu2_power_off(void)
{
/* This causes the box to drop the power and go dead. */
/* enable the pwr cntl gpio */
gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT);
/* do the deed */
gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
}
static irqreturn_t nslu2_power_handler(int irq, void *dev_id)
{
/* Signal init to do the ctrlaltdel action, this will bypass init if
* it hasn't started and do a kernel_restart.
*/
ctrl_alt_del();
return IRQ_HANDLED;
}
static irqreturn_t nslu2_reset_handler(int irq, void *dev_id)
{
/* This is the paper-clip reset, it shuts the machine down directly.
*/
machine_power_off();
return IRQ_HANDLED;
}
static void __init nslu2_timer_init(void)
{
/* The xtal on this machine is non-standard. */
ixp4xx_timer_freq = NSLU2_FREQ;
/* Call standard timer_init function. */
ixp4xx_timer_init();
}
static struct sys_timer nslu2_timer = {
.init = nslu2_timer_init,
};
static void __init nslu2_init(void)
{
uint8_t __iomem *f;
int i;
ixp4xx_sys_init();
nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
nslu2_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
i2c_register_board_info(0, nslu2_i2c_board_info,
ARRAY_SIZE(nslu2_i2c_board_info));
/*
* This is only useful on a modified machine, but it is valuable
* to have it first in order to see debug messages, and so that
* it does *not* get removed if platform_add_devices fails!
*/
(void)platform_device_register(&nslu2_uart);
platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
pm_power_off = nslu2_power_off;
if (request_irq(gpio_to_irq(NSLU2_RB_GPIO), &nslu2_reset_handler,
IRQF_DISABLED | IRQF_TRIGGER_LOW,
"NSLU2 reset button", NULL) < 0) {
printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
gpio_to_irq(NSLU2_RB_GPIO));
}
if (request_irq(gpio_to_irq(NSLU2_PB_GPIO), &nslu2_power_handler,
IRQF_DISABLED | IRQF_TRIGGER_HIGH,
"NSLU2 power button", NULL) < 0) {
printk(KERN_DEBUG "Power Button IRQ %d not available\n",
gpio_to_irq(NSLU2_PB_GPIO));
}
/*
* Map in a portion of the flash and read the MAC address.
* Since it is stored in BE in the flash itself, we need to
* byteswap it if we're in LE mode.
*/
f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x40000);
if (f) {
for (i = 0; i < 6; i++)
#ifdef __ARMEB__
nslu2_plat_eth[0].hwaddr[i] = readb(f + 0x3FFB0 + i);
#else
nslu2_plat_eth[0].hwaddr[i] = readb(f + 0x3FFB0 + (i^3));
#endif
iounmap(f);
}
printk(KERN_INFO "NSLU2: Using MAC address %pM for port 0\n",
nslu2_plat_eth[0].hwaddr);
}
MACHINE_START(NSLU2, "Linksys NSLU2")
/* Maintainer: www.nslu2-linux.org */
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &nslu2_timer,
.init_machine = nslu2_init,
MACHINE_END

View File

@@ -0,0 +1,63 @@
/*
* arch/arch/mach-ixp4xx/wg302v2-pci.c
*
* PCI setup routines for the Netgear WG302 v2 and WAG302 v2
*
* Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
*
* based on coyote-pci.c:
* Copyright (C) 2002 Jungo Software Technologies.
* Copyright (C) 2003 MontaVista Software, Inc.
*
* Maintainer: Imre Kaloz <kaloz@openwrt.org>
*
* 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/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/mach/pci.h>
void __init wg302v2_pci_preinit(void)
{
set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW);
set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
static int __init wg302v2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
if (slot == 1)
return IRQ_IXP4XX_GPIO8;
else if (slot == 2)
return IRQ_IXP4XX_GPIO9;
else return -1;
}
struct hw_pci wg302v2_pci __initdata = {
.nr_controllers = 1,
.preinit = wg302v2_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = wg302v2_map_irq,
};
int __init wg302v2_pci_init(void)
{
if (machine_is_wg302v2())
pci_common_init(&wg302v2_pci);
return 0;
}
subsys_initcall(wg302v2_pci_init);

View File

@@ -0,0 +1,109 @@
/*
* arch/arm/mach-ixp4xx/wg302-setup.c
*
* Board setup for the Netgear WG302 v2 and WAG302 v2
*
* Copyright (C) 2007 Imre Kaloz <Kaloz@openwrt.org>
*
* based on coyote-setup.c:
* Copyright (C) 2003-2005 MontaVista Software, Inc.
*
* Author: Imre Kaloz <kaloz@openwrt.org>
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
static struct flash_platform_data wg302v2_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource wg302v2_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device wg302v2_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev = {
.platform_data = &wg302v2_flash_data,
},
.num_resources = 1,
.resource = &wg302v2_flash_resource,
};
static struct resource wg302v2_uart_resource = {
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
};
static struct plat_serial8250_port wg302v2_uart_data[] = {
{
.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,
},
{ },
};
static struct platform_device wg302v2_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = wg302v2_uart_data,
},
.num_resources = 1,
.resource = &wg302v2_uart_resource,
};
static struct platform_device *wg302v2_devices[] __initdata = {
&wg302v2_flash,
&wg302v2_uart,
};
static void __init wg302v2_init(void)
{
ixp4xx_sys_init();
wg302v2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
wg302v2_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
platform_add_devices(wg302v2_devices, ARRAY_SIZE(wg302v2_devices));
}
#ifdef CONFIG_MACH_WG302V2
MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2")
/* Maintainer: Imre Kaloz <kaloz@openwrt.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 = wg302v2_init,
MACHINE_END
#endif