Commit c65f2abf authored by Rob Herring's avatar Rob Herring

ARM: remove ixp23xx and ixp2000 platforms

ixp2xxx platforms have had no real changes since ~2006 and the maintainer
has said on irc that they can be removed:

13:05 < nico> do you still care about ixp2000?
13:22 < lennert> not really, no
13:58 < nico> do you think we could remove it from the kernel tree?
14:01 < lennert> go for it, and remove ixp23xx too while you're at it

Removing will help simplify ARM consolidation in general and PCI re-work
specifically.
Signed-off-by: default avatarRob Herring <rob.herring@calxeda.com>
Cc: Randy Dunlap <rdunlap@xenotime.net>
Acked-by: default avatarLennert Buytenhek <buytenh@wantstofly.org>
parent dd775ae2
......@@ -4,8 +4,6 @@ Booting
- requirements for booting
Interrupts
- ARM Interrupt subsystem documentation
IXP2000
- Release Notes for Linux on Intel's IXP2000 Network Processor
msm
- MSM specific documentation
Netwinder
......
-------------------------------------------------------------------------
Release Notes for Linux on Intel's IXP2000 Network Processor
Maintained by Deepak Saxena <dsaxena@plexity.net>
-------------------------------------------------------------------------
1. Overview
Intel's IXP2000 family of NPUs (IXP2400, IXP2800, IXP2850) is designed
for high-performance network applications such high-availability
telecom systems. In addition to an XScale core, it contains up to 8
"MicroEngines" that run special code, several high-end networking
interfaces (UTOPIA, SPI, etc), a PCI host bridge, one serial port,
flash interface, and some other odds and ends. For more information, see:
http://developer.intel.com
2. Linux Support
Linux currently supports the following features on the IXP2000 NPUs:
- On-chip serial
- PCI
- Flash (MTD/JFFS2)
- I2C through GPIO
- Timers (watchdog, OS)
That is about all we can support under Linux ATM b/c the core networking
components of the chip are accessed via Intel's closed source SDK.
Please contact Intel directly on issues with using those. There is
also a mailing list run by some folks at Princeton University that might
be of help: https://lists.cs.princeton.edu/mailman/listinfo/ixp2xxx
WHATEVER YOU DO, DO NOT POST EMAIL TO THE LINUX-ARM OR LINUX-ARM-KERNEL
MAILING LISTS REGARDING THE INTEL SDK.
3. Supported Platforms
- Intel IXDP2400 Reference Platform
- Intel IXDP2800 Reference Platform
- Intel IXDP2401 Reference Platform
- Intel IXDP2801 Reference Platform
- RadiSys ENP-2611
4. Usage Notes
- The IXP2000 platforms usually have rather complex PCI bus topologies
with large memory space requirements. In addition, b/c of the way the
Intel SDK is designed, devices are enumerated in a very specific
way. B/c of this this, we use "pci=firmware" option in the kernel
command line so that we do not re-enumerate the bus.
- IXDP2x01 systems have variable clock tick rates that we cannot determine
via HW registers. The "ixdp2x01_clk=XXX" cmd line options allow you
to pass the clock rate to the board port.
5. Thanks
The IXP2000 work has been funded by Intel Corp. and MontaVista Software, Inc.
The following people have contributed patches/comments/etc:
Naeem F. Afzal
Lennert Buytenhek
Jeffrey Daly
-------------------------------------------------------------------------
Last Update: 8/09/2004
......@@ -640,13 +640,6 @@ S: Maintained
F: drivers/amba/
F: include/linux/amba/bus.h
ARM/ADI ROADRUNNER MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-ixp23xx/
F: arch/arm/mach-ixp23xx/include/mach/
ARM/ADS SPHERE MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
......@@ -859,21 +852,11 @@ M: Dan Williams <dan.j.williams@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
ARM/INTEL IXP2000 ARM ARCHITECTURE
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
ARM/INTEL IXDP2850 MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
ARM/INTEL IXP23XX ARM ARCHITECTURE
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
ARM/INTEL IXP4XX ARM ARCHITECTURE
M: Imre Kaloz <kaloz@openwrt.org>
M: Krzysztof Halasa <khc@pm.waw.pl>
......
......@@ -527,28 +527,6 @@ config ARCH_IOP33X
help
Support for Intel's IOP33X (XScale) family of processors.
config ARCH_IXP23XX
bool "IXP23XX-based"
depends on MMU
select CPU_XSC3
select PCI
select ARCH_USES_GETTIMEOFFSET
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
help
Support for Intel's IXP23xx (XScale) family of processors.
config ARCH_IXP2000
bool "IXP2400/2800-based"
depends on MMU
select CPU_XSCALE
select PCI
select ARCH_USES_GETTIMEOFFSET
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
help
Support for Intel's IXP2400/2800 (XScale) family of processors.
config ARCH_IXP4XX
bool "IXP4xx-based"
depends on MMU
......@@ -1045,10 +1023,6 @@ source "arch/arm/mach-iop13xx/Kconfig"
source "arch/arm/mach-ixp4xx/Kconfig"
source "arch/arm/mach-ixp2000/Kconfig"
source "arch/arm/mach-ixp23xx/Kconfig"
source "arch/arm/mach-kirkwood/Kconfig"
source "arch/arm/mach-ks8695/Kconfig"
......
......@@ -149,8 +149,6 @@ machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
machine-$(CONFIG_ARCH_IOP32X) := iop32x
machine-$(CONFIG_ARCH_IOP33X) := iop33x
machine-$(CONFIG_ARCH_IXP2000) := ixp2000
machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
machine-$(CONFIG_ARCH_KS8695) := ks8695
......
......@@ -32,10 +32,3 @@ __XScale_start:
bic r0, r0, #0x1000 @ clear Icache
mcr p15, 0, r0, c1, c0, 0
#ifdef CONFIG_ARCH_IXP2000
mov r1, #-1
mov r0, #0xd6000000
str r1, [r0, #0x14]
str r1, [r0, #0x18]
#endif
......@@ -11,7 +11,5 @@ obj-$(CONFIG_DMABOUNCE) += dmabounce.o
obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_ARCH_IXP2000) += uengine.o
obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
/*
* Generic library functions for the microengines found on the Intel
* IXP2000 series of network processors.
*
* Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
* Dedicated to Marija Kulikova.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/hardware/uengine.h>
#if defined(CONFIG_ARCH_IXP2000)
#define IXP_UENGINE_CSR_VIRT_BASE IXP2000_UENGINE_CSR_VIRT_BASE
#define IXP_PRODUCT_ID IXP2000_PRODUCT_ID
#define IXP_MISC_CONTROL IXP2000_MISC_CONTROL
#define IXP_RESET1 IXP2000_RESET1
#else
#if defined(CONFIG_ARCH_IXP23XX)
#define IXP_UENGINE_CSR_VIRT_BASE IXP23XX_UENGINE_CSR_VIRT_BASE
#define IXP_PRODUCT_ID IXP23XX_PRODUCT_ID
#define IXP_MISC_CONTROL IXP23XX_MISC_CONTROL
#define IXP_RESET1 IXP23XX_RESET1
#else
#error unknown platform
#endif
#endif
#define USTORE_ADDRESS 0x000
#define USTORE_DATA_LOWER 0x004
#define USTORE_DATA_UPPER 0x008
#define CTX_ENABLES 0x018
#define CC_ENABLE 0x01c
#define CSR_CTX_POINTER 0x020
#define INDIRECT_CTX_STS 0x040
#define ACTIVE_CTX_STS 0x044
#define INDIRECT_CTX_SIG_EVENTS 0x048
#define INDIRECT_CTX_WAKEUP_EVENTS 0x050
#define NN_PUT 0x080
#define NN_GET 0x084
#define TIMESTAMP_LOW 0x0c0
#define TIMESTAMP_HIGH 0x0c4
#define T_INDEX_BYTE_INDEX 0x0f4
#define LOCAL_CSR_STATUS 0x180
u32 ixp2000_uengine_mask;
static void *ixp2000_uengine_csr_area(int uengine)
{
return ((void *)IXP_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
}
/*
* LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR
* space means that the microengine we tried to access was also trying
* to access its own CSR space on the same clock cycle as we did. When
* this happens, we lose the arbitration process by default, and the
* read or write we tried to do was not actually performed, so we try
* again until it succeeds.
*/
u32 ixp2000_uengine_csr_read(int uengine, int offset)
{
void *uebase;
u32 *local_csr_status;
u32 *reg;
u32 value;
uebase = ixp2000_uengine_csr_area(uengine);
local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
reg = (u32 *)(uebase + offset);
do {
value = ixp2000_reg_read(reg);
} while (ixp2000_reg_read(local_csr_status) & 1);
return value;
}
EXPORT_SYMBOL(ixp2000_uengine_csr_read);
void ixp2000_uengine_csr_write(int uengine, int offset, u32 value)
{
void *uebase;
u32 *local_csr_status;
u32 *reg;
uebase = ixp2000_uengine_csr_area(uengine);
local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
reg = (u32 *)(uebase + offset);
do {
ixp2000_reg_write(reg, value);
} while (ixp2000_reg_read(local_csr_status) & 1);
}
EXPORT_SYMBOL(ixp2000_uengine_csr_write);
void ixp2000_uengine_reset(u32 uengine_mask)
{
u32 value;
value = ixp2000_reg_read(IXP_RESET1) & ~ixp2000_uengine_mask;
uengine_mask &= ixp2000_uengine_mask;
ixp2000_reg_wrb(IXP_RESET1, value | uengine_mask);
ixp2000_reg_wrb(IXP_RESET1, value);
}
EXPORT_SYMBOL(ixp2000_uengine_reset);
void ixp2000_uengine_set_mode(int uengine, u32 mode)
{
/*
* CTL_STR_PAR_EN: unconditionally enable parity checking on
* control store.
*/
mode |= 0x10000000;
ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode);
/*
* Enable updating of condition codes.
*/
ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000);
/*
* Initialise other per-microengine registers.
*/
ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00);
ixp2000_uengine_csr_write(uengine, NN_GET, 0x00);
ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0);
}
EXPORT_SYMBOL(ixp2000_uengine_set_mode);
static int make_even_parity(u32 x)
{
return hweight32(x) & 1;
}
static void ustore_write(int uengine, u64 insn)
{
/*
* Generate even parity for top and bottom 20 bits.
*/
insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41;
insn |= (u64)make_even_parity(insn & 0x000fffff) << 40;
/*
* Write to microstore. The second write auto-increments
* the USTORE_ADDRESS index register.
*/
ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn);
ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32));
}
void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns)
{
int i;
/*
* Start writing to microstore at address 0.
*/
ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000);
for (i = 0; i < insns; i++) {
u64 insn;
insn = (((u64)ucode[0]) << 32) |
(((u64)ucode[1]) << 24) |
(((u64)ucode[2]) << 16) |
(((u64)ucode[3]) << 8) |
((u64)ucode[4]);
ucode += 5;
ustore_write(uengine, insn);
}
/*
* Pad with a few NOPs at the end (to avoid the microengine
* aborting as it prefetches beyond the last instruction), unless
* we run off the end of the instruction store first, at which
* point the address register will wrap back to zero.
*/
for (i = 0; i < 4; i++) {
u32 addr;
addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS);
if (addr == 0x80000000)
break;
ustore_write(uengine, 0xf0000c0300ULL);
}
/*
* End programming.
*/
ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000);
}
EXPORT_SYMBOL(ixp2000_uengine_load_microcode);
void ixp2000_uengine_init_context(int uengine, int context, int pc)
{
/*
* Select the right context for indirect access.
*/
ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context);
/*
* Initialise signal masks to immediately go to Ready state.
*/
ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1);
ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1);
/*
* Set program counter.
*/
ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc);
}
EXPORT_SYMBOL(ixp2000_uengine_init_context);
void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask)
{
u32 mask;
/*
* Enable the specified context to go to Executing state.
*/
mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
mask |= ctx_mask << 8;
ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
}
EXPORT_SYMBOL(ixp2000_uengine_start_contexts);
void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask)
{
u32 mask;
/*
* Disable the Ready->Executing transition. Note that this
* does not stop the context until it voluntarily yields.
*/
mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
mask &= ~(ctx_mask << 8);
ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
}
EXPORT_SYMBOL(ixp2000_uengine_stop_contexts);
static int check_ixp_type(struct ixp2000_uengine_code *c)
{
u32 product_id;
u32 rev;
product_id = ixp2000_reg_read(IXP_PRODUCT_ID);
if (((product_id >> 16) & 0x1f) != 0)
return 0;
switch ((product_id >> 8) & 0xff) {
#ifdef CONFIG_ARCH_IXP2000
case 0: /* IXP2800 */
if (!(c->cpu_model_bitmask & 4))
return 0;
break;
case 1: /* IXP2850 */
if (!(c->cpu_model_bitmask & 8))
return 0;
break;
case 2: /* IXP2400 */
if (!(c->cpu_model_bitmask & 2))
return 0;
break;
#endif
#ifdef CONFIG_ARCH_IXP23XX
case 4: /* IXP23xx */
if (!(c->cpu_model_bitmask & 0x3f0))
return 0;
break;
#endif
default:
return 0;
}
rev = product_id & 0xff;
if (rev < c->cpu_min_revision || rev > c->cpu_max_revision)
return 0;
return 1;
}
static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
{
int offset;
int i;
offset = 0;
for (i = 0; i < 128; i++) {
u8 b3;
u8 b2;
u8 b1;
u8 b0;
b3 = (gpr_a[i] >> 24) & 0xff;
b2 = (gpr_a[i] >> 16) & 0xff;
b1 = (gpr_a[i] >> 8) & 0xff;
b0 = gpr_a[i] & 0xff;
/* immed[@ai, (b1 << 8) | b0] */
/* 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII */
ucode[offset++] = 0xf0;
ucode[offset++] = (b1 >> 4);
ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6);
ucode[offset++] = (b0 << 2);
ucode[offset++] = 0x80 | i;
/* immed_w1[@ai, (b3 << 8) | b2] */
/* 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII */
ucode[offset++] = 0xf4;
ucode[offset++] = 0x40 | (b3 >> 4);
ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6);
ucode[offset++] = (b2 << 2);
ucode[offset++] = 0x80 | i;
}
for (i = 0; i < 128; i++) {
u8 b3;
u8 b2;
u8 b1;
u8 b0;
b3 = (gpr_b[i] >> 24) & 0xff;
b2 = (gpr_b[i] >> 16) & 0xff;
b1 = (gpr_b[i] >> 8) & 0xff;
b0 = gpr_b[i] & 0xff;
/* immed[@bi, (b1 << 8) | b0] */
/* 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV */
ucode[offset++] = 0xf0;
ucode[offset++] = (b1 >> 4);
ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6);
ucode[offset++] = (i << 2) | 0x03;
ucode[offset++] = b0;
/* immed_w1[@bi, (b3 << 8) | b2] */
/* 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV */
ucode[offset++] = 0xf4;
ucode[offset++] = 0x40 | (b3 >> 4);
ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6);
ucode[offset++] = (i << 2) | 0x03;
ucode[offset++] = b2;
}
/* ctx_arb[kill] */
ucode[offset++] = 0xe0;
ucode[offset++] = 0x00;
ucode[offset++] = 0x01;
ucode[offset++] = 0x00;
ucode[offset++] = 0x00;
}
static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
{
int per_ctx_regs;
u32 *gpr_a;
u32 *gpr_b;
u8 *ucode;
int i;
gpr_a = kzalloc(128 * sizeof(u32), GFP_KERNEL);
gpr_b = kzalloc(128 * sizeof(u32), GFP_KERNEL);
ucode = kmalloc(513 * 5, GFP_KERNEL);
if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) {
kfree(ucode);
kfree(gpr_b);
kfree(gpr_a);
return 1;
}
per_ctx_regs = 16;
if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
per_ctx_regs = 32;
for (i = 0; i < 256; i++) {
struct ixp2000_reg_value *r = c->initial_reg_values + i;
u32 *bank;
int inc;
int j;
if (r->reg == -1)
break;
bank = (r->reg & 0x400) ? gpr_b : gpr_a;
inc = (r->reg & 0x80) ? 128 : per_ctx_regs;
j = r->reg & 0x7f;
while (j < 128) {
bank[j] = r->value;
j += inc;
}
}
generate_ucode(ucode, gpr_a, gpr_b);
ixp2000_uengine_load_microcode(uengine, ucode, 513);
ixp2000_uengine_init_context(uengine, 0, 0);
ixp2000_uengine_start_contexts(uengine, 0x01);
for (i = 0; i < 100; i++) {
u32 status;
status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS);
if (!(status & 0x80000000))
break;
}
ixp2000_uengine_stop_contexts(uengine, 0x01);
kfree(ucode);
kfree(gpr_b);
kfree(gpr_a);
return !!(i == 100);
}
int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c)
{
int ctx;
if (!check_ixp_type(c))
return 1;
if (!(ixp2000_uengine_mask & (1 << uengine)))
return 1;
ixp2000_uengine_reset(1 << uengine);
ixp2000_uengine_set_mode(uengine, c->uengine_parameters);
if (set_initial_registers(uengine, c))
return 1;
ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns);
for (ctx = 0; ctx < 8; ctx++)
ixp2000_uengine_init_context(uengine, ctx, 0);
return 0;
}
EXPORT_SYMBOL(ixp2000_uengine_load);
static int __init ixp2000_uengine_init(void)
{
int uengine;
u32 value;
/*
* Determine number of microengines present.
*/
switch ((ixp2000_reg_read(IXP_PRODUCT_ID) >> 8) & 0x1fff) {
#ifdef CONFIG_ARCH_IXP2000
case 0: /* IXP2800 */
case 1: /* IXP2850 */
ixp2000_uengine_mask = 0x00ff00ff;
break;
case 2: /* IXP2400 */
ixp2000_uengine_mask = 0x000f000f;
break;
#endif
#ifdef CONFIG_ARCH_IXP23XX
case 4: /* IXP23xx */
ixp2000_uengine_mask = (*IXP23XX_EXP_CFG_FUSE >> 8) & 0xf;
break;
#endif
default:
printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
(unsigned int)ixp2000_reg_read(IXP_PRODUCT_ID));
ixp2000_uengine_mask = 0x00000000;
break;
}
/*
* Reset microengines.
*/
ixp2000_uengine_reset(ixp2000_uengine_mask);
/*
* Synchronise timestamp counters across all microengines.
*/
value = ixp2000_reg_read(IXP_MISC_CONTROL);
ixp2000_reg_wrb(IXP_MISC_CONTROL, value & ~0x80);
for (uengine = 0; uengine < 32; uengine++) {
if (ixp2000_uengine_mask & (1 << uengine)) {
ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
}
}
ixp2000_reg_wrb(IXP_MISC_CONTROL, value | 0x80);
return 0;
}
subsys_initcall(ixp2000_uengine_init);
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_HOTPLUG is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_ARCH_IXP2000=y
CONFIG_ARCH_ENP2611=y
CONFIG_ARCH_IXDP2400=y
CONFIG_ARCH_IXDP2800=y
CONFIG_ARCH_IXDP2401=y
CONFIG_ARCH_IXDP2801=y
# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
# CONFIG_ARM_THUMB is not set
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0"
CONFIG_FPE_NWFPE=y
CONFIG_FPE_NWFPE_XP=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_SYN_COOKIES=y
CONFIG_IPV6=y
# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_IPV6_SIT is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_IXP2000=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_EEPROM_LEGACY=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_NET_ETHERNET=y
CONFIG_NET_PCI=y
CONFIG_CS89x0=y
CONFIG_E100=y
CONFIG_ENP2611_MSF_NET=y
CONFIG_WAN=y
CONFIG_HDLC=y
CONFIG_HDLC_RAW=y
CONFIG_HDLC_CISCO=y
CONFIG_HDLC_FR=y
CONFIG_HDLC_PPP=y
CONFIG_DLCI=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=3
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_IXP2000=y
CONFIG_WATCHDOG=y
CONFIG_IXP2000_WATCHDOG=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_INOTIFY=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_ARCH_IXP23XX=y
CONFIG_MACH_ESPRESSO=y
CONFIG_MACH_IXDP2351=y
CONFIG_MACH_ROADRUNNER=y
# CONFIG_ARM_THUMB is not set
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp"
CONFIG_FPE_NWFPE=y
CONFIG_FPE_NWFPE_XP=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_SYN_COOKIES=y
CONFIG_IPV6=y
# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_IPV6_SIT is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_EEPROM_LEGACY=y
CONFIG_IDE=y
CONFIG_BLK_DEV_SIIMAGE=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_NET_ETHERNET=y
CONFIG_NET_PCI=y
CONFIG_E100=y
CONFIG_E1000=y
CONFIG_WAN=y
CONFIG_HDLC=y
CONFIG_HDLC_RAW=y
CONFIG_HDLC_CISCO=y
CONFIG_HDLC_FR=y
CONFIG_HDLC_PPP=y
CONFIG_DLCI=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_WATCHDOG=y
# CONFIG_USB_HID is not set
CONFIG_USB=y
CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_INOTIFY=y
CONFIG_MSDOS_FS=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
/*
* Generic library functions for the microengines found on the Intel
* IXP2000 series of network processors.
*
* Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
* Dedicated to Marija Kulikova.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*/
#ifndef __IXP2000_UENGINE_H
#define __IXP2000_UENGINE_H
extern u32 ixp2000_uengine_mask;
struct ixp2000_uengine_code
{
u32 cpu_model_bitmask;
u8 cpu_min_revision;
u8 cpu_max_revision;
u32 uengine_parameters;
struct ixp2000_reg_value {
int reg;
u32 value;
} *initial_reg_values;
int num_insns;
u8 *insns;
};
u32 ixp2000_uengine_csr_read(int uengine, int offset);
void ixp2000_uengine_csr_write(int uengine, int offset, u32 value);
void ixp2000_uengine_reset(u32 uengine_mask);
void ixp2000_uengine_set_mode(int uengine, u32 mode);
void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns);
void ixp2000_uengine_init_context(int uengine, int context, int pc);
void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask);
void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask);
int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c);
#define IXP2000_UENGINE_8_CONTEXTS 0x00000000
#define IXP2000_UENGINE_4_CONTEXTS 0x80000000
#define IXP2000_UENGINE_PRN_UPDATE_EVERY 0x40000000
#define IXP2000_UENGINE_PRN_UPDATE_ON_ACCESS 0x00000000
#define IXP2000_UENGINE_NN_FROM_SELF 0x00100000
#define IXP2000_UENGINE_NN_FROM_PREVIOUS 0x00000000
#define IXP2000_UENGINE_ASSERT_EMPTY_AT_3 0x000c0000
#define IXP2000_UENGINE_ASSERT_EMPTY_AT_2 0x00080000
#define IXP2000_UENGINE_ASSERT_EMPTY_AT_1 0x00040000
#define IXP2000_UENGINE_ASSERT_EMPTY_AT_0 0x00000000
#define IXP2000_UENGINE_LM_ADDR1_GLOBAL 0x00020000
#define IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT 0x00000000
#define IXP2000_UENGINE_LM_ADDR0_GLOBAL 0x00010000
#define IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT 0x00000000
#endif
if ARCH_IXP2000
config ARCH_SUPPORTS_BIG_ENDIAN
bool
default y
menu "Intel IXP2400/2800 Implementation Options"
comment "IXP2400/2800 Platforms"
config ARCH_ENP2611
bool "Support Radisys ENP-2611"
help
Say 'Y' here if you want your kernel to support the Radisys
ENP2611 PCI network processing card. For more information on
this card, see <file:Documentation/arm/IXP2000>.
config ARCH_IXDP2400
bool "Support Intel IXDP2400"
help
Say 'Y' here if you want your kernel to support the Intel
IXDP2400 reference platform. For more information on
this platform, see <file:Documentation/arm/IXP2000>.
config ARCH_IXDP2800
bool "Support Intel IXDP2800"
help
Say 'Y' here if you want your kernel to support the Intel
IXDP2800 reference platform. For more information on
this platform, see <file:Documentation/arm/IXP2000>.
config ARCH_IXDP2X00
bool
depends on ARCH_IXDP2400 || ARCH_IXDP2800
default y
config ARCH_IXDP2401
bool "Support Intel IXDP2401"
help
Say 'Y' here if you want your kernel to support the Intel
IXDP2401 reference platform. For more information on
this platform, see <file:Documentation/arm/IXP2000>.
config ARCH_IXDP2801
bool "Support Intel IXDP2801 and IXDP28x5"
help
Say 'Y' here if you want your kernel to support the Intel
IXDP2801/2805/2855 reference platforms. For more information on
this platform, see <file:Documentation/arm/IXP2000>.
config MACH_IXDP28X5
bool
depends on ARCH_IXDP2801
default y
config ARCH_IXDP2X01
bool
depends on ARCH_IXDP2401 || ARCH_IXDP2801
default y
config IXP2000_SUPPORT_BROKEN_PCI_IO
bool "Support broken PCI I/O on older IXP2000s"
default y
help
Say 'N' here if you only intend to run your kernel on an
IXP2000 B0 or later model and do not need the PCI I/O
byteswap workaround. Say 'Y' otherwise.
endmenu
endif
#
# Makefile for the linux kernel.
#
obj-y := core.o pci.o
obj-m :=
obj-n :=
obj- :=
obj-$(CONFIG_ARCH_ENP2611) += enp2611.o
obj-$(CONFIG_ARCH_IXDP2400) += ixdp2400.o
obj-$(CONFIG_ARCH_IXDP2800) += ixdp2800.o
obj-$(CONFIG_ARCH_IXDP2X00) += ixdp2x00.o
obj-$(CONFIG_ARCH_IXDP2X01) += ixdp2x01.o
zreladdr-y += 0x00008000
params_phys-y := 0x00000100
/*
* arch/arm/mach-ixp2000/core.c
*
* Common routines used by all IXP2400/2800 based platforms.
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2004 (C) MontaVista Software, Inc.
*
* Based on work Copyright (C) 2002-2003 Intel Corporation
*
* 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/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/bitops.h>
#include <linux/serial_8250.h>
#include <linux/mm.h>
#include <linux/export.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
#include <mach/gpio-ixp2000.h>
static DEFINE_SPINLOCK(ixp2000_slowport_lock);
static unsigned long ixp2000_slowport_irq_flags;
/*************************************************************************
* Slowport access routines
*************************************************************************/
void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg)
{
spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags);
old_cfg->CCR = *IXP2000_SLOWPORT_CCR;
old_cfg->WTC = *IXP2000_SLOWPORT_WTC2;
old_cfg->RTC = *IXP2000_SLOWPORT_RTC2;
old_cfg->PCR = *IXP2000_SLOWPORT_PCR;
old_cfg->ADC = *IXP2000_SLOWPORT_ADC;
ixp2000_reg_write(IXP2000_SLOWPORT_CCR, new_cfg->CCR);
ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC);
ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC);
ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR);
ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
}
void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
{
ixp2000_reg_write(IXP2000_SLOWPORT_CCR, old_cfg->CCR);
ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC);
ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC);
ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR);
ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, old_cfg->ADC);
spin_unlock_irqrestore(&ixp2000_slowport_lock,
ixp2000_slowport_irq_flags);
}
/*************************************************************************
* Chip specific mappings shared by all IXP2000 systems
*************************************************************************/
static struct map_desc ixp2000_io_desc[] __initdata = {
{
.virtual = IXP2000_CAP_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
.length = IXP2000_CAP_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_INTCTL_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
.length = IXP2000_INTCTL_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_PCI_CREG_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
.length = IXP2000_PCI_CREG_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_PCI_CSR_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
.length = IXP2000_PCI_CSR_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_MSF_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
.length = IXP2000_MSF_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_SCRATCH_RING_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE),
.length = IXP2000_SCRATCH_RING_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_SRAM0_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE),
.length = IXP2000_SRAM0_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_PCI_IO_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
.length = IXP2000_PCI_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_PCI_CFG0_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
.length = IXP2000_PCI_CFG0_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IXP2000_PCI_CFG1_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
.length = IXP2000_PCI_CFG1_SIZE,
.type = MT_DEVICE,
}
};
void __init ixp2000_map_io(void)
{
iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
/* Set slowport to 8-bit mode. */
ixp2000_reg_wrb(IXP2000_SLOWPORT_FRM, 1);
}
/*************************************************************************
* Serial port support for IXP2000
*************************************************************************/
static struct plat_serial8250_port ixp2000_serial_port[] = {
{
.mapbase = IXP2000_UART_PHYS_BASE,
.membase = (char *)(IXP2000_UART_VIRT_BASE + 3),
.irq = IRQ_IXP2000_UART,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 50000000,
},
{ },
};
static struct resource ixp2000_uart_resource = {
.start = IXP2000_UART_PHYS_BASE,
.end = IXP2000_UART_PHYS_BASE + 0x1f,
.flags = IORESOURCE_MEM,
};
static struct platform_device ixp2000_serial_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = ixp2000_serial_port,
},
.num_resources = 1,
.resource = &ixp2000_uart_resource,
};
void __init ixp2000_uart_init(void)
{
platform_device_register(&ixp2000_serial_device);
}
/*************************************************************************
* Timer-tick functions for IXP2000
*************************************************************************/
static unsigned ticks_per_jiffy;
static unsigned ticks_per_usec;
static unsigned next_jiffy_time;
static volatile unsigned long *missing_jiffy_timer_csr;
unsigned long ixp2000_gettimeoffset (void)
{
unsigned long offset;
offset = next_jiffy_time - *missing_jiffy_timer_csr;
return offset / ticks_per_usec;
}
static irqreturn_t ixp2000_timer_interrupt(int irq, void *dev_id)
{
/* clear timer 1 */
ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
while ((signed long)(next_jiffy_time - *missing_jiffy_timer_csr)
>= ticks_per_jiffy) {
timer_tick();
next_jiffy_time -= ticks_per_jiffy;
}
return IRQ_HANDLED;
}
static struct irqaction ixp2000_timer_irq = {
.name = "IXP2000 Timer Tick",
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ixp2000_timer_interrupt,
};
void __init ixp2000_init_time(unsigned long tick_rate)
{
ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
ticks_per_usec = tick_rate / 1000000;
/*
* We use timer 1 as our timer interrupt.
*/
ixp2000_reg_write(IXP2000_T1_CLR, 0);
ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1);
ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
/*
* We use a second timer as a monotonic counter for tracking
* missed jiffies. The IXP2000 has four timers, but if we're
* on an A-step IXP2800, timer 2 and 3 don't work, so on those
* chips we use timer 4. Timer 4 is the only timer that can
* be used for the watchdog, so we use timer 2 if we're on a
* non-buggy chip.
*/
if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
printk(KERN_INFO "Enabling IXP2800 erratum #25 workaround\n");
ixp2000_reg_write(IXP2000_T4_CLR, 0);
ixp2000_reg_write(IXP2000_T4_CLD, -1);
ixp2000_reg_wrb(IXP2000_T4_CTL, (1 << 7));
missing_jiffy_timer_csr = IXP2000_T4_CSR;
} else {
ixp2000_reg_write(IXP2000_T2_CLR, 0);
ixp2000_reg_write(IXP2000_T2_CLD, -1);
ixp2000_reg_wrb(IXP2000_T2_CTL, (1 << 7));
missing_jiffy_timer_csr = IXP2000_T2_CSR;
}
next_jiffy_time = 0xffffffff;
/* register for interrupt */
setup_irq(IRQ_IXP2000_TIMER1, &ixp2000_timer_irq);
}
/*************************************************************************
* GPIO helpers
*************************************************************************/
static unsigned long GPIO_IRQ_falling_edge;
static unsigned long GPIO_IRQ_rising_edge;
static unsigned long GPIO_IRQ_level_low;
static unsigned long GPIO_IRQ_level_high;
static void update_gpio_int_csrs(void)
{
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
ixp2000_reg_wrb(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
}
void gpio_line_config(int line, int direction)
{
unsigned long flags;
local_irq_save(flags);
if (direction == GPIO_OUT) {
/* if it's an output, it ain't an interrupt anymore */
GPIO_IRQ_falling_edge &= ~(1 << line);
GPIO_IRQ_rising_edge &= ~(1 << line);
GPIO_IRQ_level_low &= ~(1 << line);
GPIO_IRQ_level_high &= ~(1 << line);
update_gpio_int_csrs();
ixp2000_reg_wrb(IXP2000_GPIO_PDSR, 1 << line);
} else if (direction == GPIO_IN) {
ixp2000_reg_wrb(IXP2000_GPIO_PDCR, 1 << line);
}
local_irq_restore(flags);
}
EXPORT_SYMBOL(gpio_line_config);
/*************************************************************************
* IRQ handling IXP2000
*************************************************************************/
static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irq_desc *desc)
{
int i;
unsigned long status = *IXP2000_GPIO_INST;
for (i = 0; i <= 7; i++) {
if (status & (1<<i)) {
generic_handle_irq(i + IRQ_IXP2000_GPIO0);
}
}
}
static int ixp2000_GPIO_irq_type(struct irq_data *d, unsigned int type)
{
int line = d->irq - IRQ_IXP2000_GPIO0;
/*
* First, configure this GPIO line as an input.
*/
ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
/*
* Then, set the proper trigger type.
*/
if (type & IRQ_TYPE_EDGE_FALLING)
GPIO_IRQ_falling_edge |= 1 << line;
else
GPIO_IRQ_falling_edge &= ~(1 << line);
if (type & IRQ_TYPE_EDGE_RISING)
GPIO_IRQ_rising_edge |= 1 << line;
else
GPIO_IRQ_rising_edge &= ~(1 << line);
if (type & IRQ_TYPE_LEVEL_LOW)
GPIO_IRQ_level_low |= 1 << line;
else
GPIO_IRQ_level_low &= ~(1 << line);
if (type & IRQ_TYPE_LEVEL_HIGH)
GPIO_IRQ_level_high |= 1 << line;
else
GPIO_IRQ_level_high &= ~(1 << line);
update_gpio_int_csrs();
return 0;
}
static void ixp2000_GPIO_irq_mask_ack(struct irq_data *d)
{
unsigned int irq = d->irq;
ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
}
static void ixp2000_GPIO_irq_mask(struct irq_data *d)
{
unsigned int irq = d->irq;
ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
}
static void ixp2000_GPIO_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq;
ixp2000_reg_write(IXP2000_GPIO_INSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
}
static struct irq_chip ixp2000_GPIO_irq_chip = {
.irq_ack = ixp2000_GPIO_irq_mask_ack,
.irq_mask = ixp2000_GPIO_irq_mask,
.irq_unmask = ixp2000_GPIO_irq_unmask,
.irq_set_type = ixp2000_GPIO_irq_type,
};
static void ixp2000_pci_irq_mask(struct irq_data *d)
{
unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
if (d->irq == IRQ_IXP2000_PCIA)
ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
else if (d->irq == IRQ_IXP2000_PCIB)
ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
}
static void ixp2000_pci_irq_unmask(struct irq_data *d)
{
unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
if (d->irq == IRQ_IXP2000_PCIA)
ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 26)));
else if (d->irq == IRQ_IXP2000_PCIB)
ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27)));
}
/*
* Error interrupts. These are used extensively by the microengine drivers
*/
static void ixp2000_err_irq_handler(unsigned int irq, struct irq_desc *desc)
{
int i;
unsigned long status = *IXP2000_IRQ_ERR_STATUS;
for(i = 31; i >= 0; i--) {
if(status & (1 << i)) {
generic_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i);
}
}
}
static void ixp2000_err_irq_mask(struct irq_data *d)
{
ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR,
(1 << (d->irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
}
static void ixp2000_err_irq_unmask(struct irq_data *d)
{
ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET,
(1 << (d->irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
}
static struct irq_chip ixp2000_err_irq_chip = {
.irq_ack = ixp2000_err_irq_mask,
.irq_mask = ixp2000_err_irq_mask,
.irq_unmask = ixp2000_err_irq_unmask
};
static struct irq_chip ixp2000_pci_irq_chip = {
.irq_ack = ixp2000_pci_irq_mask,
.irq_mask = ixp2000_pci_irq_mask,
.irq_unmask = ixp2000_pci_irq_unmask
};
static void ixp2000_irq_mask(struct irq_data *d)
{
ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << d->irq));
}
static void ixp2000_irq_unmask(struct irq_data *d)
{
ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << d->irq));
}
static struct irq_chip ixp2000_irq_chip = {
.irq_ack = ixp2000_irq_mask,
.irq_mask = ixp2000_irq_mask,
.irq_unmask = ixp2000_irq_unmask
};
void __init ixp2000_init_irq(void)
{
int irq;
/*
* Mask all sources
*/
ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, 0xffffffff);
ixp2000_reg_write(IXP2000_FIQ_ENABLE_CLR, 0xffffffff);
/* clear all GPIO edge/level detects */
ixp2000_reg_write(IXP2000_GPIO_REDR, 0);
ixp2000_reg_write(IXP2000_GPIO_FEDR, 0);
ixp2000_reg_write(IXP2000_GPIO_LSHR, 0);
ixp2000_reg_write(IXP2000_GPIO_LSLR, 0);
ixp2000_reg_write(IXP2000_GPIO_INCR, -1);
/* clear PCI interrupt sources */
ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
/*
* Certain bits in the IRQ status register of the
* IXP2000 are reserved. Instead of trying to map
* things non 1:1 from bit position to IRQ number,
* we mark the reserved IRQs as invalid. This makes
* our mask/unmask code much simpler.
*/
for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
if ((1 << irq) & IXP2000_VALID_IRQ_MASK) {
irq_set_chip_and_handler(irq, &ixp2000_irq_chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
} else set_irq_flags(irq, 0);
}
for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) {
if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) &
IXP2000_VALID_ERR_IRQ_MASK) {
irq_set_chip_and_handler(irq, &ixp2000_err_irq_chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
else
set_irq_flags(irq, 0);
}
irq_set_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler);
for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
irq_set_chip_and_handler(irq, &ixp2000_GPIO_irq_chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
irq_set_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler);
/*
* Enable PCI irqs. The actual PCI[AB] decoding is done in
* entry-macro.S, so we don't need a chained handler for the
* PCI interrupt source.
*/
ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI));
for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) {
irq_set_chip_and_handler(irq, &ixp2000_pci_irq_chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
}
void ixp2000_restart(char mode, const char *cmd)
{
ixp2000_reg_wrb(IXP2000_RESET0, RSTALL);
}
/*
* arch/arm/mach-ixp2000/enp2611.c
*
* Radisys ENP-2611 support.
*
* Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The
* original version carries the following notices:
*
* Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002-2003 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/pci.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
/*************************************************************************
* ENP-2611 timer tick configuration
*************************************************************************/
static void __init enp2611_timer_init(void)
{
ixp2000_init_time(50 * 1000 * 1000);
}
static struct sys_timer enp2611_timer = {
.init = enp2611_timer_init,
.offset = ixp2000_gettimeoffset,
};
/*************************************************************************
* ENP-2611 I/O
*************************************************************************/
static struct map_desc enp2611_io_desc[] __initdata = {
{
.virtual = ENP2611_CALEB_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE),
.length = ENP2611_CALEB_SIZE,
.type = MT_DEVICE,
}, {
.virtual = ENP2611_PM3386_0_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE),
.length = ENP2611_PM3386_0_SIZE,
.type = MT_DEVICE,
}, {
.virtual = ENP2611_PM3386_1_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE),
.length = ENP2611_PM3386_1_SIZE,
.type = MT_DEVICE,
}
};
void __init enp2611_map_io(void)
{
ixp2000_map_io();
iotable_init(enp2611_io_desc, ARRAY_SIZE(enp2611_io_desc));
}
/*************************************************************************
* ENP-2611 PCI
*************************************************************************/
static int enp2611_pci_setup(int nr, struct pci_sys_data *sys)
{
sys->mem_offset = 0xe0000000;
ixp2000_pci_setup(nr, sys);
return 1;
}
static void __init enp2611_pci_preinit(void)
{
ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
ixp2000_pci_preinit();
pcibios_setup("firmware");
}
static inline int enp2611_pci_valid_device(struct pci_bus *bus,
unsigned int devfn)
{
/* The 82559 ethernet controller appears at both PCI:1:0:0 and
* PCI:1:2:0, so let's pretend the second one isn't there.
*/
if (bus->number == 0x01 && devfn == 0x10)
return 0;
return 1;
}
static int enp2611_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *value)
{
if (enp2611_pci_valid_device(bus, devfn))
return ixp2000_pci_read_config(bus, devfn, where, size, value);
return PCIBIOS_DEVICE_NOT_FOUND;
}
static int enp2611_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value)
{
if (enp2611_pci_valid_device(bus, devfn))
return ixp2000_pci_write_config(bus, devfn, where, size, value);
return PCIBIOS_DEVICE_NOT_FOUND;
}
static struct pci_ops enp2611_pci_ops = {
.read = enp2611_pci_read_config,
.write = enp2611_pci_write_config
};
static struct pci_bus * __init enp2611_pci_scan_bus(int nr,
struct pci_sys_data *sys)
{
return pci_scan_root_bus(NULL, sys->busnr, &enp2611_pci_ops, sys,
&sys->resources);
}
static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot,
u8 pin)
{
int irq;
if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 0) {
/* IXP2400. */
irq = IRQ_IXP2000_PCIA;
} else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 1) {
/* 21555 non-transparent bridge. */
irq = IRQ_IXP2000_PCIB;
} else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 4) {
/* PCI2050B transparent bridge. */
irq = -1;
} else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 0) {
/* 82559 ethernet. */
irq = IRQ_IXP2000_PCIA;
} else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 1) {
/* SPI-3 option board. */
irq = IRQ_IXP2000_PCIB;
} else {
printk(KERN_ERR "enp2611_pci_map_irq() called for unknown "
"device PCI:%d:%d:%d\n", dev->bus->number,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
irq = -1;
}
return irq;
}
struct hw_pci enp2611_pci __initdata = {
.nr_controllers = 1,
.setup = enp2611_pci_setup,
.preinit = enp2611_pci_preinit,
.scan = enp2611_pci_scan_bus,
.map_irq = enp2611_pci_map_irq,
};
int __init enp2611_pci_init(void)
{
if (machine_is_enp2611())
pci_common_init(&enp2611_pci);
return 0;
}
subsys_initcall(enp2611_pci_init);
/*************************************************************************
* ENP-2611 Machine Initialization
*************************************************************************/
static struct flash_platform_data enp2611_flash_platform_data = {
.map_name = "cfi_probe",
.width = 1,
};
static struct ixp2000_flash_data enp2611_flash_data = {
.platform_data = &enp2611_flash_platform_data,
.nr_banks = 1
};
static struct resource enp2611_flash_resource = {
.start = 0xc4000000,
.end = 0xc4000000 + 0x00ffffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device enp2611_flash = {
.name = "IXP2000-Flash",
.id = 0,
.dev = {
.platform_data = &enp2611_flash_data,
},
.num_resources = 1,
.resource = &enp2611_flash_resource,
};
static struct ixp2000_i2c_pins enp2611_i2c_gpio_pins = {
.sda_pin = ENP2611_GPIO_SDA,
.scl_pin = ENP2611_GPIO_SCL,
};
static struct platform_device enp2611_i2c_controller = {
.name = "IXP2000-I2C",
.id = 0,
.dev = {
.platform_data = &enp2611_i2c_gpio_pins
},
.num_resources = 0
};
static struct platform_device *enp2611_devices[] __initdata = {
&enp2611_flash,
&enp2611_i2c_controller
};
static void __init enp2611_init_machine(void)
{
platform_add_devices(enp2611_devices, ARRAY_SIZE(enp2611_devices));
ixp2000_uart_init();
}
MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
.atag_offset = 0x100,
.map_io = enp2611_map_io,
.init_irq = ixp2000_init_irq,
.timer = &enp2611_timer,
.init_machine = enp2611_init_machine,
.restart = ixp2000_restart,
MACHINE_END
/* arch/arm/mach-ixp2000/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, rp, rv, tmp
mov \rp, #0x00030000
#ifdef __ARMEB__
orr \rp, \rp, #0x00000003
#endif
orr \rv, \rp, #0xfe000000 @ virtual base
orr \rv, \rv, #0x00f00000
orr \rp, \rp, #0xc0000000 @ Physical base
.endm
#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>
/*
* arch/arm/mach-ixp2000/include/mach/enp2611.h
*
* Register and other defines for Radisys ENP-2611
*
* Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The
* original version carries the following notices:
*
* Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef __ENP2611_H
#define __ENP2611_H
#define ENP2611_CALEB_PHYS_BASE 0xc5000000
#define ENP2611_CALEB_VIRT_BASE 0xfe000000
#define ENP2611_CALEB_SIZE 0x00100000
#define ENP2611_PM3386_0_PHYS_BASE 0xc6000000
#define ENP2611_PM3386_0_VIRT_BASE 0xfe100000
#define ENP2611_PM3386_0_SIZE 0x00100000
#define ENP2611_PM3386_1_PHYS_BASE 0xc6400000
#define ENP2611_PM3386_1_VIRT_BASE 0xfe200000
#define ENP2611_PM3386_1_SIZE 0x00100000
#define ENP2611_GPIO_SCL 7
#define ENP2611_GPIO_SDA 6
#define IRQ_ENP2611_THERMAL IRQ_IXP2000_GPIO4
#define IRQ_ENP2611_OPTION_BOARD IRQ_IXP2000_GPIO3
#define IRQ_ENP2611_CALEB IRQ_IXP2000_GPIO2
#define IRQ_ENP2611_PM3386_1 IRQ_IXP2000_GPIO1
#define IRQ_ENP2611_PM3386_0 IRQ_IXP2000_GPIO0
#endif
/*
* arch/arm/mach-ixp2000/include/mach/entry-macro.S
*
* Low-level IRQ helper macros for IXP2000-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/irqs.h>
.macro get_irqnr_preamble, base, tmp
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \irqnr, #0x0 @clear out irqnr as default
mov \base, #0xfe000000
orr \base, \base, #0x00e00000
orr \base, \base, #0x08
ldr \irqstat, [\base] @ get interrupts
cmp \irqstat, #0
beq 1001f
clz \irqnr, \irqstat
mov \base, #31
subs \irqnr, \base, \irqnr
/*
* We handle PCIA and PCIB here so we don't have an
* extra layer of code just to check these two bits.
*/
cmp \irqnr, #IRQ_IXP2000_PCI
bne 1001f
mov \base, #0xfe000000
orr \base, \base, #0x00c00000
orr \base, \base, #0x00000100
orr \base, \base, #0x00000058
ldr \irqstat, [\base]
mov \tmp, #(1<<26)
tst \irqstat, \tmp
movne \irqnr, #IRQ_IXP2000_PCIA
bne 1001f
mov \tmp, #(1<<27)
tst \irqstat, \tmp
movne \irqnr, #IRQ_IXP2000_PCIB
1001:
.endm
/*
* arch/arm/mach-ixp2000/include/mach/gpio.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.
*/
/*
* IXP2000 GPIO in/out, edge/level detection for IRQs:
* IRQs are generated on Falling-edge, Rising-Edge, Level-low, Level-High
* or both Falling-edge and Rising-edge.
* This must be called *before* the corresponding IRQ is registerd.
* Use this instead of directly setting the GPIO registers.
* GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
*/
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H
#ifndef __ASSEMBLY__
#define GPIO_IN 0
#define GPIO_OUT 1
#define IXP2000_GPIO_LOW 0
#define IXP2000_GPIO_HIGH 1
extern void gpio_line_config(int line, int direction);
static inline int gpio_line_get(int line)
{
return (((*IXP2000_GPIO_PLR) >> line) & 1);
}
static inline void gpio_line_set(int line, int value)
{
if (value == IXP2000_GPIO_HIGH) {
ixp2000_reg_write(IXP2000_GPIO_POSR, 1 << line);
} else if (value == IXP2000_GPIO_LOW) {
ixp2000_reg_write(IXP2000_GPIO_POCR, 1 << line);
}
}
#endif /* !__ASSEMBLY__ */
#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
/*
* arch/arm/mach-ixp2000/include/mach/hardware.h
*
* Hardware definitions for IXP2400/2800 based systems
*
* Original Author: Naeem M Afzal <naeem.m.afzal@intel.com>
*
* Maintainer: Deepak Saxena <dsaxena@mvista.com>
*
* Copyright (C) 2001-2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef __ASM_ARCH_HARDWARE_H__
#define __ASM_ARCH_HARDWARE_H__
#include "ixp2000-regs.h" /* Chipset Registers */
/*
* Platform helper functions
*/
#include "platform.h"
/*
* Platform-specific bits
*/
#include "enp2611.h" /* ENP-2611 */
#include "ixdp2x00.h" /* IXDP2400/2800 */
#include "ixdp2x01.h" /* IXDP2401/2801 */
#endif /* _ASM_ARCH_HARDWARE_H__ */
/*
* arch/arm/mach-ixp2000/include/mach/io.h
*
* Original Author: Naeem M Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corp.
* Copyrgiht (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_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#include <mach/hardware.h>
#define IO_SPACE_LIMIT 0xffffffff
/*
* The A? revisions of the IXP2000s assert byte lanes for PCI I/O
* transactions the other way round (MEM transactions don't have this
* issue), so if we want to support those models, we need to override
* the standard I/O functions.
*
* B0 and later have a bit that can be set to 1 to get the proper
* behavior for I/O transactions, which then allows us to use the
* standard I/O functions. This is what we do if the user does not
* explicitly ask for support for pre-B0.
*/
#ifdef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
#define ___io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
#define alignb(addr) (void __iomem *)((unsigned long)(addr) ^ 3)
#define alignw(addr) (void __iomem *)((unsigned long)(addr) ^ 2)
#define outb(v,p) __raw_writeb((v),alignb(___io(p)))
#define outw(v,p) __raw_writew((v),alignw(___io(p)))
#define outl(v,p) __raw_writel((v),___io(p))
#define inb(p) ({ unsigned int __v = __raw_readb(alignb(___io(p))); __v; })
#define inw(p) \
({ unsigned int __v = (__raw_readw(alignw(___io(p)))); __v; })
#define inl(p) \
({ unsigned int __v = (__raw_readl(___io(p))); __v; })
#define outsb(p,d,l) __raw_writesb(alignb(___io(p)),d,l)
#define outsw(p,d,l) __raw_writesw(alignw(___io(p)),d,l)
#define outsl(p,d,l) __raw_writesl(___io(p),d,l)
#define insb(p,d,l) __raw_readsb(alignb(___io(p)),d,l)
#define insw(p,d,l) __raw_readsw(alignw(___io(p)),d,l)
#define insl(p,d,l) __raw_readsl(___io(p),d,l)
#define __is_io_address(p) ((((unsigned long)(p)) & ~(IXP2000_PCI_IO_SIZE - 1)) == IXP2000_PCI_IO_VIRT_BASE)
#define ioread8(p) \
({ \
unsigned int __v; \
\
if (__is_io_address(p)) { \
__v = __raw_readb(alignb(p)); \
} else { \
__v = __raw_readb(p); \
} \
\
__v; \
}) \
#define ioread16(p) \
({ \
unsigned int __v; \
\
if (__is_io_address(p)) { \
__v = __raw_readw(alignw(p)); \
} else { \
__v = le16_to_cpu(__raw_readw(p)); \
} \
\
__v; \
})
#define ioread32(p) \
({ \
unsigned int __v; \
\
if (__is_io_address(p)) { \
__v = __raw_readl(p); \
} else { \
__v = le32_to_cpu(__raw_readl(p)); \
} \
\
__v; \
})
#define iowrite8(v,p) \
({ \
if (__is_io_address(p)) { \
__raw_writeb((v), alignb(p)); \
} else { \
__raw_writeb((v), p); \
} \
})
#define iowrite16(v,p) \
({ \
if (__is_io_address(p)) { \
__raw_writew((v), alignw(p)); \
} else { \
__raw_writew(cpu_to_le16(v), p); \
} \
})
#define iowrite32(v,p) \
({ \
if (__is_io_address(p)) { \
__raw_writel((v), p); \
} else { \
__raw_writel(cpu_to_le32(v), p); \
} \
})
#define ioport_map(port, nr) ___io(port)
#define ioport_unmap(addr)
#else
#define __io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
#endif
#endif
/*
* arch/arm/mach-ixp2000/include/mach/irqs.h
*
* Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corp.
* 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 _IRQS_H
#define _IRQS_H
/*
* Do NOT add #ifdef MACHINE_FOO in here.
* Simpy add your machine IRQs here and increase NR_IRQS if needed to
* hold your machine's IRQ table.
*/
/*
* Some interrupt numbers go unused b/c the IRQ mask/ummask/status
* register has those bit reserved. We just mark those interrupts
* as invalid and this allows us to do mask/unmask with a single
* shift operation instead of having to map the IRQ number to
* a HW IRQ number.
*/
#define IRQ_IXP2000_SOFT_INT 0 /* soft interrupt */
#define IRQ_IXP2000_ERRSUM 1 /* OR of all bits in ErrorStatus reg*/
#define IRQ_IXP2000_UART 2
#define IRQ_IXP2000_GPIO 3
#define IRQ_IXP2000_TIMER1 4
#define IRQ_IXP2000_TIMER2 5
#define IRQ_IXP2000_TIMER3 6
#define IRQ_IXP2000_TIMER4 7
#define IRQ_IXP2000_PMU 8
#define IRQ_IXP2000_SPF 9 /* Slow port framer IRQ */
#define IRQ_IXP2000_DMA1 10
#define IRQ_IXP2000_DMA2 11
#define IRQ_IXP2000_DMA3 12
#define IRQ_IXP2000_PCI_DOORBELL 13
#define IRQ_IXP2000_ME_ATTN 14
#define IRQ_IXP2000_PCI 15 /* PCI INTA or INTB */
#define IRQ_IXP2000_THDA0 16 /* thread 0-31A */
#define IRQ_IXP2000_THDA1 17 /* thread 32-63A, IXP2800 only */
#define IRQ_IXP2000_THDA2 18 /* thread 64-95A */
#define IRQ_IXP2000_THDA3 19 /* thread 96-127A, IXP2800 only */
#define IRQ_IXP2000_THDB0 24 /* thread 0-31B */
#define IRQ_IXP2000_THDB1 25 /* thread 32-63B, IXP2800 only */
#define IRQ_IXP2000_THDB2 26 /* thread 64-95B */
#define IRQ_IXP2000_THDB3 27 /* thread 96-127B, IXP2800 only */
/* define generic GPIOs */
#define IRQ_IXP2000_GPIO0 32
#define IRQ_IXP2000_GPIO1 33
#define IRQ_IXP2000_GPIO2 34
#define IRQ_IXP2000_GPIO3 35
#define IRQ_IXP2000_GPIO4 36
#define IRQ_IXP2000_GPIO5 37
#define IRQ_IXP2000_GPIO6 38
#define IRQ_IXP2000_GPIO7 39
/* split off the 2 PCI sources */
#define IRQ_IXP2000_PCIA 40
#define IRQ_IXP2000_PCIB 41
/* Int sources from IRQ_ERROR_STATUS */
#define IRQ_IXP2000_DRAM0_MIN_ERR 42
#define IRQ_IXP2000_DRAM0_MAJ_ERR 43
#define IRQ_IXP2000_DRAM1_MIN_ERR 44
#define IRQ_IXP2000_DRAM1_MAJ_ERR 45
#define IRQ_IXP2000_DRAM2_MIN_ERR 46
#define IRQ_IXP2000_DRAM2_MAJ_ERR 47
/* 48-57 reserved */
#define IRQ_IXP2000_SRAM0_ERR 58
#define IRQ_IXP2000_SRAM1_ERR 59
#define IRQ_IXP2000_SRAM2_ERR 60
#define IRQ_IXP2000_SRAM3_ERR 61
/* 62-65 reserved */
#define IRQ_IXP2000_MEDIA_ERR 66
#define IRQ_IXP2000_PCI_ERR 67
#define IRQ_IXP2000_SP_INT 68
#define NR_IXP2000_IRQS 69
#define IXP2000_BOARD_IRQ(x) (NR_IXP2000_IRQS + (x))
#define IXP2000_BOARD_IRQ_MASK(irq) (1 << (irq - NR_IXP2000_IRQS))
#define IXP2000_ERR_IRQ_MASK(irq) ( 1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR))
#define IXP2000_VALID_ERR_IRQ_MASK (\
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MIN_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MAJ_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MIN_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MAJ_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MIN_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MAJ_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM0_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM1_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM2_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM3_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_MEDIA_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_PCI_ERR) | \
IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SP_INT) )
/*
* This allows for all the on-chip sources plus up to 32 CPLD based
* IRQs. Should be more than enough.
*/
#define IXP2000_BOARD_IRQS 32
#define NR_IRQS (NR_IXP2000_IRQS + IXP2000_BOARD_IRQS)
/*
* IXDP2400 specific IRQs
*/
#define IRQ_IXDP2400_INGRESS_NPU IXP2000_BOARD_IRQ(0)
#define IRQ_IXDP2400_ENET IXP2000_BOARD_IRQ(1)
#define IRQ_IXDP2400_MEDIA_PCI IXP2000_BOARD_IRQ(2)
#define IRQ_IXDP2400_MEDIA_SP IXP2000_BOARD_IRQ(3)
#define IRQ_IXDP2400_SF_PCI IXP2000_BOARD_IRQ(4)
#define IRQ_IXDP2400_SF_SP IXP2000_BOARD_IRQ(5)
#define IRQ_IXDP2400_PMC IXP2000_BOARD_IRQ(6)
#define IRQ_IXDP2400_TVM IXP2000_BOARD_IRQ(7)
#define NR_IXDP2400_IRQS ((IRQ_IXDP2400_TVM)+1)
#define IXDP2400_NR_IRQS NR_IXDP2400_IRQS - NR_IXP2000_IRQS
/* IXDP2800 specific IRQs */
#define IRQ_IXDP2800_EGRESS_ENET IXP2000_BOARD_IRQ(0)
#define IRQ_IXDP2800_INGRESS_NPU IXP2000_BOARD_IRQ(1)
#define IRQ_IXDP2800_PMC IXP2000_BOARD_IRQ(2)
#define IRQ_IXDP2800_FABRIC_PCI IXP2000_BOARD_IRQ(3)
#define IRQ_IXDP2800_FABRIC IXP2000_BOARD_IRQ(4)
#define IRQ_IXDP2800_MEDIA IXP2000_BOARD_IRQ(5)
#define NR_IXDP2800_IRQS ((IRQ_IXDP2800_MEDIA)+1)
#define IXDP2800_NR_IRQS NR_IXDP2800_IRQS - NR_IXP2000_IRQS
/*
* IRQs on both IXDP2x01 boards
*/
#define IRQ_IXDP2X01_SPCI_DB_0 IXP2000_BOARD_IRQ(2)
#define IRQ_IXDP2X01_SPCI_DB_1 IXP2000_BOARD_IRQ(3)
#define IRQ_IXDP2X01_SPCI_PMC_INTA IXP2000_BOARD_IRQ(4)
#define IRQ_IXDP2X01_SPCI_PMC_INTB IXP2000_BOARD_IRQ(5)
#define IRQ_IXDP2X01_SPCI_PMC_INTC IXP2000_BOARD_IRQ(6)
#define IRQ_IXDP2X01_SPCI_PMC_INTD IXP2000_BOARD_IRQ(7)
#define IRQ_IXDP2X01_SPCI_FIC_INT IXP2000_BOARD_IRQ(8)
#define IRQ_IXDP2X01_IPMI_FROM IXP2000_BOARD_IRQ(16)
#define IRQ_IXDP2X01_125US IXP2000_BOARD_IRQ(17)
#define IRQ_IXDP2X01_DB_0_ADD IXP2000_BOARD_IRQ(18)
#define IRQ_IXDP2X01_DB_1_ADD IXP2000_BOARD_IRQ(19)
#define IRQ_IXDP2X01_UART1 IXP2000_BOARD_IRQ(21)
#define IRQ_IXDP2X01_UART2 IXP2000_BOARD_IRQ(22)
#define IRQ_IXDP2X01_FIC_ADD_INT IXP2000_BOARD_IRQ(24)
#define IRQ_IXDP2X01_CS8900 IXP2000_BOARD_IRQ(25)
#define IRQ_IXDP2X01_BBSRAM IXP2000_BOARD_IRQ(26)
#define IXDP2X01_VALID_IRQ_MASK ( \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_DB_0) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_DB_1) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTA) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTB) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTC) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTD) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_FIC_INT) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_IPMI_FROM) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_125US) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_DB_0_ADD) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_DB_1_ADD) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_UART1) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_UART2) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_FIC_ADD_INT) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_CS8900) | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_BBSRAM) )
/*
* IXDP2401 specific IRQs
*/
#define IRQ_IXDP2401_INTA_82546 IXP2000_BOARD_IRQ(0)
#define IRQ_IXDP2401_INTB_82546 IXP2000_BOARD_IRQ(1)
#define IXDP2401_VALID_IRQ_MASK ( \
IXDP2X01_VALID_IRQ_MASK | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2401_INTA_82546) |\
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2401_INTB_82546))
/*
* IXDP2801-specific IRQs
*/
#define IRQ_IXDP2801_RIV IXP2000_BOARD_IRQ(0)
#define IRQ_IXDP2801_CNFG_MEDIA IXP2000_BOARD_IRQ(27)
#define IRQ_IXDP2801_CLOCK_REF IXP2000_BOARD_IRQ(28)
#define IXDP2801_VALID_IRQ_MASK ( \
IXDP2X01_VALID_IRQ_MASK | \
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_RIV) |\
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_CNFG_MEDIA) |\
IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_CLOCK_REF))
#define NR_IXDP2X01_IRQS ((IRQ_IXDP2801_CLOCK_REF) + 1)
#endif /*_IRQS_H*/
/*
* arch/arm/mach-ixp2000/include/mach/ixdp2x00.h
*
* Register and other defines for IXDP2[48]00 platforms
*
* Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef _IXDP2X00_H_
#define _IXDP2X00_H_
/*
* On board CPLD memory map
*/
#define IXDP2X00_PHYS_CPLD_BASE 0xc7000000
#define IXDP2X00_VIRT_CPLD_BASE 0xfe000000
#define IXDP2X00_CPLD_SIZE 0x00100000
#define IXDP2X00_CPLD_REG(x) \
(volatile unsigned long *)(IXDP2X00_VIRT_CPLD_BASE | x)
/*
* IXDP2400 CPLD registers
*/
#define IXDP2400_CPLD_SYSLED IXDP2X00_CPLD_REG(0x0)
#define IXDP2400_CPLD_DISP_DATA IXDP2X00_CPLD_REG(0x4)
#define IXDP2400_CPLD_CLOCK_SPEED IXDP2X00_CPLD_REG(0x8)
#define IXDP2400_CPLD_INT_STAT IXDP2X00_CPLD_REG(0xc)
#define IXDP2400_CPLD_REV IXDP2X00_CPLD_REG(0x10)
#define IXDP2400_CPLD_SYS_CLK_M IXDP2X00_CPLD_REG(0x14)
#define IXDP2400_CPLD_SYS_CLK_N IXDP2X00_CPLD_REG(0x18)
#define IXDP2400_CPLD_INT_MASK IXDP2X00_CPLD_REG(0x48)
/*
* IXDP2800 CPLD registers
*/
#define IXDP2800_CPLD_INT_STAT IXDP2X00_CPLD_REG(0x0)
#define IXDP2800_CPLD_INT_MASK IXDP2X00_CPLD_REG(0x140)
#define IXDP2X00_GPIO_I2C_ENABLE 0x02
#define IXDP2X00_GPIO_SCL 0x07
#define IXDP2X00_GPIO_SDA 0x06
/*
* PCI devfns for on-board devices. We need these to be able to
* properly translate IRQs and for device removal.
*/
#define IXDP2400_SLAVE_ENET_DEVFN 0x18 /* Bus 1 */
#define IXDP2400_MASTER_ENET_DEVFN 0x20 /* Bus 1 */
#define IXDP2400_MEDIA_DEVFN 0x28 /* Bus 1 */
#define IXDP2400_SWITCH_FABRIC_DEVFN 0x30 /* Bus 1 */
#define IXDP2800_SLAVE_ENET_DEVFN 0x20 /* Bus 1 */
#define IXDP2800_MASTER_ENET_DEVFN 0x18 /* Bus 1 */
#define IXDP2800_SWITCH_FABRIC_DEVFN 0x30 /* Bus 1 */
#define IXDP2X00_P2P_DEVFN 0x20 /* Bus 0 */
#define IXDP2X00_21555_DEVFN 0x30 /* Bus 0 */
#define IXDP2X00_SLAVE_NPU_DEVFN 0x28 /* Bus 1 */
#define IXDP2X00_PMC_DEVFN 0x38 /* Bus 1 */
#define IXDP2X00_MASTER_NPU_DEVFN 0x38 /* Bus 1 */
#ifndef __ASSEMBLY__
/*
* The master NPU is always PCI master.
*/
static inline unsigned int ixdp2x00_master_npu(void)
{
return !!ixp2000_is_pcimaster();
}
/*
* Helper functions used by ixdp2400 and ixdp2800 specific code
*/
void ixdp2x00_init_irq(volatile unsigned long*, volatile unsigned long *, unsigned long);
void ixdp2x00_slave_pci_postinit(void);
void ixdp2x00_init_machine(void);
void ixdp2x00_map_io(void);
#endif
#endif /*_IXDP2X00_H_ */
/*
* arch/arm/mach-ixp2000/include/mach/ixdp2x01.h
*
* Platform definitions for IXDP2X01 && IXDP2801 systems
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2004 (c) MontaVista Software, Inc.
*
* Based on original code Copyright (c) 2002-2003 Intel Corporation
*
* 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 __IXDP2X01_H__
#define __IXDP2X01_H__
#define IXDP2X01_PHYS_CPLD_BASE 0xc6024000
#define IXDP2X01_VIRT_CPLD_BASE 0xfe000000
#define IXDP2X01_CPLD_REGION_SIZE 0x00100000
#define IXDP2X01_CPLD_VIRT_REG(reg) (volatile unsigned long*)(IXDP2X01_VIRT_CPLD_BASE | reg)
#define IXDP2X01_CPLD_PHYS_REG(reg) (IXDP2X01_PHYS_CPLD_BASE | reg)
#define IXDP2X01_UART1_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x40)
#define IXDP2X01_UART1_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x40)
#define IXDP2X01_UART2_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x60)
#define IXDP2X01_UART2_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x60)
#define IXDP2X01_CS8900_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x80)
#define IXDP2X01_CS8900_VIRT_END (IXDP2X01_CS8900_VIRT_BASE + 16)
#define IXDP2X01_CPLD_RESET_REG IXDP2X01_CPLD_VIRT_REG(0x00)
#define IXDP2X01_INT_MASK_SET_REG IXDP2X01_CPLD_VIRT_REG(0x08)
#define IXDP2X01_INT_STAT_REG IXDP2X01_CPLD_VIRT_REG(0x0C)
#define IXDP2X01_INT_RAW_REG IXDP2X01_CPLD_VIRT_REG(0x10)
#define IXDP2X01_INT_MASK_CLR_REG IXDP2X01_INT_RAW_REG
#define IXDP2X01_INT_SIM_REG IXDP2X01_CPLD_VIRT_REG(0x14)
#define IXDP2X01_CPLD_FLASH_REG IXDP2X01_CPLD_VIRT_REG(0x20)
#define IXDP2X01_CPLD_FLASH_INTERN 0x8000
#define IXDP2X01_CPLD_FLASH_BANK_MASK 0xF
#define IXDP2X01_FLASH_WINDOW_BITS 25
#define IXDP2X01_FLASH_WINDOW_SIZE (1 << IXDP2X01_FLASH_WINDOW_BITS)
#define IXDP2X01_FLASH_WINDOW_MASK (IXDP2X01_FLASH_WINDOW_SIZE - 1)
#define IXDP2X01_UART_CLK 1843200
#define IXDP2X01_GPIO_I2C_ENABLE 0x02
#define IXDP2X01_GPIO_SCL 0x07
#define IXDP2X01_GPIO_SDA 0x06
#endif /* __IXDP2x01_H__ */
/*
* arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h
*
* Chipset register definitions for IXP2400/2800 based systems.
*
* Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
*
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef _IXP2000_REGS_H_
#define _IXP2000_REGS_H_
/*
* IXP2000 linux memory map:
*
* virt phys size
* fb000000 db000000 16M PCI CFG1
* fc000000 da000000 16M PCI CFG0
* fd000000 d8000000 16M PCI I/O
* fe[0-7]00000 8M per-platform mappings
* fe900000 80000000 1M SRAM #0 (first MB)
* fea00000 cb400000 1M SCRATCH ring get/put
* feb00000 c8000000 1M MSF
* fec00000 df000000 1M PCI CSRs
* fed00000 de000000 1M PCI CREG
* fee00000 d6000000 1M INTCTL
* fef00000 c0000000 1M CAP
*/
/*
* Static I/O regions.
*
* Most of the registers are clumped in 4K regions spread throughout
* the 0xc0000000 -> 0xc0100000 address range, but we just map in
* the whole range using a single 1 MB section instead of small
* 4K pages.
*
* CAP stands for CSR Access Proxy.
*
* If you change the virtual address of this mapping, please propagate
* the change to arch/arm/kernel/debug.S, which hardcodes the virtual
* address of the UART located in this region.
*/
#define IXP2000_CAP_PHYS_BASE 0xc0000000
#define IXP2000_CAP_VIRT_BASE 0xfef00000
#define IXP2000_CAP_SIZE 0x00100000
/*
* Addresses for specific on-chip peripherals.
*/
#define IXP2000_SLOWPORT_CSR_VIRT_BASE 0xfef80000
#define IXP2000_GLOBAL_REG_VIRT_BASE 0xfef04000
#define IXP2000_UART_PHYS_BASE 0xc0030000
#define IXP2000_UART_VIRT_BASE 0xfef30000
#define IXP2000_TIMER_VIRT_BASE 0xfef20000
#define IXP2000_UENGINE_CSR_VIRT_BASE 0xfef18000
#define IXP2000_GPIO_VIRT_BASE 0xfef10000
/*
* Devices outside of the 0xc0000000 -> 0xc0100000 range. The virtual
* addresses of the INTCTL and PCI_CSR mappings are hardcoded in
* entry-macro.S, so if you ever change these please propagate
* the change.
*/
#define IXP2000_INTCTL_PHYS_BASE 0xd6000000
#define IXP2000_INTCTL_VIRT_BASE 0xfee00000
#define IXP2000_INTCTL_SIZE 0x00100000
#define IXP2000_PCI_CREG_PHYS_BASE 0xde000000
#define IXP2000_PCI_CREG_VIRT_BASE 0xfed00000
#define IXP2000_PCI_CREG_SIZE 0x00100000
#define IXP2000_PCI_CSR_PHYS_BASE 0xdf000000
#define IXP2000_PCI_CSR_VIRT_BASE 0xfec00000
#define IXP2000_PCI_CSR_SIZE 0x00100000
#define IXP2000_MSF_PHYS_BASE 0xc8000000
#define IXP2000_MSF_VIRT_BASE 0xfeb00000
#define IXP2000_MSF_SIZE 0x00100000
#define IXP2000_SCRATCH_RING_PHYS_BASE 0xcb400000
#define IXP2000_SCRATCH_RING_VIRT_BASE 0xfea00000
#define IXP2000_SCRATCH_RING_SIZE 0x00100000
#define IXP2000_SRAM0_PHYS_BASE 0x80000000
#define IXP2000_SRAM0_VIRT_BASE 0xfe900000
#define IXP2000_SRAM0_SIZE 0x00100000
#define IXP2000_PCI_IO_PHYS_BASE 0xd8000000
#define IXP2000_PCI_IO_VIRT_BASE 0xfd000000
#define IXP2000_PCI_IO_SIZE 0x01000000
#define IXP2000_PCI_CFG0_PHYS_BASE 0xda000000
#define IXP2000_PCI_CFG0_VIRT_BASE 0xfc000000
#define IXP2000_PCI_CFG0_SIZE 0x01000000
#define IXP2000_PCI_CFG1_PHYS_BASE 0xdb000000
#define IXP2000_PCI_CFG1_VIRT_BASE 0xfb000000
#define IXP2000_PCI_CFG1_SIZE 0x01000000
/*
* Timers
*/
#define IXP2000_TIMER_REG(x) ((volatile unsigned long*)(IXP2000_TIMER_VIRT_BASE | (x)))
/* Timer control */
#define IXP2000_T1_CTL IXP2000_TIMER_REG(0x00)
#define IXP2000_T2_CTL IXP2000_TIMER_REG(0x04)
#define IXP2000_T3_CTL IXP2000_TIMER_REG(0x08)
#define IXP2000_T4_CTL IXP2000_TIMER_REG(0x0c)
/* Store initial value */
#define IXP2000_T1_CLD IXP2000_TIMER_REG(0x10)
#define IXP2000_T2_CLD IXP2000_TIMER_REG(0x14)
#define IXP2000_T3_CLD IXP2000_TIMER_REG(0x18)
#define IXP2000_T4_CLD IXP2000_TIMER_REG(0x1c)
/* Read current value */
#define IXP2000_T1_CSR IXP2000_TIMER_REG(0x20)
#define IXP2000_T2_CSR IXP2000_TIMER_REG(0x24)
#define IXP2000_T3_CSR IXP2000_TIMER_REG(0x28)
#define IXP2000_T4_CSR IXP2000_TIMER_REG(0x2c)
/* Clear associated timer interrupt */
#define IXP2000_T1_CLR IXP2000_TIMER_REG(0x30)
#define IXP2000_T2_CLR IXP2000_TIMER_REG(0x34)
#define IXP2000_T3_CLR IXP2000_TIMER_REG(0x38)
#define IXP2000_T4_CLR IXP2000_TIMER_REG(0x3c)
/* Timer watchdog enable for T4 */
#define IXP2000_TWDE IXP2000_TIMER_REG(0x40)
#define WDT_ENABLE 0x00000001
#define TIMER_DIVIDER_256 0x00000008
#define TIMER_ENABLE 0x00000080
#define IRQ_MASK_TIMER1 (1 << 4)
/*
* Interrupt controller registers
*/
#define IXP2000_INTCTL_REG(x) (volatile unsigned long*)(IXP2000_INTCTL_VIRT_BASE | (x))
#define IXP2000_IRQ_STATUS IXP2000_INTCTL_REG(0x08)
#define IXP2000_IRQ_ENABLE IXP2000_INTCTL_REG(0x10)
#define IXP2000_IRQ_ENABLE_SET IXP2000_INTCTL_REG(0x10)
#define IXP2000_IRQ_ENABLE_CLR IXP2000_INTCTL_REG(0x18)
#define IXP2000_FIQ_ENABLE_CLR IXP2000_INTCTL_REG(0x14)
#define IXP2000_IRQ_ERR_STATUS IXP2000_INTCTL_REG(0x24)
#define IXP2000_IRQ_ERR_ENABLE_SET IXP2000_INTCTL_REG(0x2c)
#define IXP2000_FIQ_ERR_ENABLE_CLR IXP2000_INTCTL_REG(0x30)
#define IXP2000_IRQ_ERR_ENABLE_CLR IXP2000_INTCTL_REG(0x34)
#define IXP2000_IRQ_THD_RAW_STATUS_A_0 IXP2000_INTCTL_REG(0x60)
#define IXP2000_IRQ_THD_RAW_STATUS_A_1 IXP2000_INTCTL_REG(0x64)
#define IXP2000_IRQ_THD_RAW_STATUS_A_2 IXP2000_INTCTL_REG(0x68)
#define IXP2000_IRQ_THD_RAW_STATUS_A_3 IXP2000_INTCTL_REG(0x6c)
#define IXP2000_IRQ_THD_RAW_STATUS_B_0 IXP2000_INTCTL_REG(0x80)
#define IXP2000_IRQ_THD_RAW_STATUS_B_1 IXP2000_INTCTL_REG(0x84)
#define IXP2000_IRQ_THD_RAW_STATUS_B_2 IXP2000_INTCTL_REG(0x88)
#define IXP2000_IRQ_THD_RAW_STATUS_B_3 IXP2000_INTCTL_REG(0x8c)
#define IXP2000_IRQ_THD_STATUS_A_0 IXP2000_INTCTL_REG(0xe0)
#define IXP2000_IRQ_THD_STATUS_A_1 IXP2000_INTCTL_REG(0xe4)
#define IXP2000_IRQ_THD_STATUS_A_2 IXP2000_INTCTL_REG(0xe8)
#define IXP2000_IRQ_THD_STATUS_A_3 IXP2000_INTCTL_REG(0xec)
#define IXP2000_IRQ_THD_STATUS_B_0 IXP2000_INTCTL_REG(0x100)
#define IXP2000_IRQ_THD_STATUS_B_1 IXP2000_INTCTL_REG(0x104)
#define IXP2000_IRQ_THD_STATUS_B_2 IXP2000_INTCTL_REG(0x108)
#define IXP2000_IRQ_THD_STATUS_B_3 IXP2000_INTCTL_REG(0x10c)
#define IXP2000_IRQ_THD_ENABLE_SET_A_0 IXP2000_INTCTL_REG(0x160)
#define IXP2000_IRQ_THD_ENABLE_SET_A_1 IXP2000_INTCTL_REG(0x164)
#define IXP2000_IRQ_THD_ENABLE_SET_A_2 IXP2000_INTCTL_REG(0x168)
#define IXP2000_IRQ_THD_ENABLE_SET_A_3 IXP2000_INTCTL_REG(0x16c)
#define IXP2000_IRQ_THD_ENABLE_SET_B_0 IXP2000_INTCTL_REG(0x180)
#define IXP2000_IRQ_THD_ENABLE_SET_B_1 IXP2000_INTCTL_REG(0x184)
#define IXP2000_IRQ_THD_ENABLE_SET_B_2 IXP2000_INTCTL_REG(0x188)
#define IXP2000_IRQ_THD_ENABLE_SET_B_3 IXP2000_INTCTL_REG(0x18c)
#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_0 IXP2000_INTCTL_REG(0x1e0)
#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_1 IXP2000_INTCTL_REG(0x1e4)
#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_2 IXP2000_INTCTL_REG(0x1e8)
#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_3 IXP2000_INTCTL_REG(0x1ec)
#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_0 IXP2000_INTCTL_REG(0x200)
#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_1 IXP2000_INTCTL_REG(0x204)
#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_2 IXP2000_INTCTL_REG(0x208)
#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_3 IXP2000_INTCTL_REG(0x20c)
/*
* Mask of valid IRQs in the 32-bit IRQ register. We use
* this to mark certain IRQs as being invalid.
*/
#define IXP2000_VALID_IRQ_MASK 0x0f0fffff
/*
* PCI config register access from core
*/
#define IXP2000_PCI_CREG(x) (volatile unsigned long*)(IXP2000_PCI_CREG_VIRT_BASE | (x))
#define IXP2000_PCI_CMDSTAT IXP2000_PCI_CREG(0x04)
#define IXP2000_PCI_CSR_BAR IXP2000_PCI_CREG(0x10)
#define IXP2000_PCI_SRAM_BAR IXP2000_PCI_CREG(0x14)
#define IXP2000_PCI_SDRAM_BAR IXP2000_PCI_CREG(0x18)
/*
* PCI CSRs
*/
#define IXP2000_PCI_CSR(x) (volatile unsigned long*)(IXP2000_PCI_CSR_VIRT_BASE | (x))
/*
* PCI outbound interrupts
*/
#define IXP2000_PCI_OUT_INT_STATUS IXP2000_PCI_CSR(0x30)
#define IXP2000_PCI_OUT_INT_MASK IXP2000_PCI_CSR(0x34)
/*
* PCI communications
*/
#define IXP2000_PCI_MAILBOX0 IXP2000_PCI_CSR(0x50)
#define IXP2000_PCI_MAILBOX1 IXP2000_PCI_CSR(0x54)
#define IXP2000_PCI_MAILBOX2 IXP2000_PCI_CSR(0x58)
#define IXP2000_PCI_MAILBOX3 IXP2000_PCI_CSR(0x5C)
#define IXP2000_XSCALE_DOORBELL IXP2000_PCI_CSR(0x60)
#define IXP2000_XSCALE_DOORBELL_SETUP IXP2000_PCI_CSR(0x64)
#define IXP2000_PCI_DOORBELL IXP2000_PCI_CSR(0x70)
#define IXP2000_PCI_DOORBELL_SETUP IXP2000_PCI_CSR(0x74)
/*
* DMA engines
*/
#define IXP2000_PCI_CH1_BYTE_CNT IXP2000_PCI_CSR(0x80)
#define IXP2000_PCI_CH1_ADDR IXP2000_PCI_CSR(0x84)
#define IXP2000_PCI_CH1_DRAM_ADDR IXP2000_PCI_CSR(0x88)
#define IXP2000_PCI_CH1_DESC_PTR IXP2000_PCI_CSR(0x8C)
#define IXP2000_PCI_CH1_CNTRL IXP2000_PCI_CSR(0x90)
#define IXP2000_PCI_CH1_ME_PARAM IXP2000_PCI_CSR(0x94)
#define IXP2000_PCI_CH2_BYTE_CNT IXP2000_PCI_CSR(0xA0)
#define IXP2000_PCI_CH2_ADDR IXP2000_PCI_CSR(0xA4)
#define IXP2000_PCI_CH2_DRAM_ADDR IXP2000_PCI_CSR(0xA8)
#define IXP2000_PCI_CH2_DESC_PTR IXP2000_PCI_CSR(0xAC)
#define IXP2000_PCI_CH2_CNTRL IXP2000_PCI_CSR(0xB0)
#define IXP2000_PCI_CH2_ME_PARAM IXP2000_PCI_CSR(0xB4)
#define IXP2000_PCI_CH3_BYTE_CNT IXP2000_PCI_CSR(0xC0)
#define IXP2000_PCI_CH3_ADDR IXP2000_PCI_CSR(0xC4)
#define IXP2000_PCI_CH3_DRAM_ADDR IXP2000_PCI_CSR(0xC8)
#define IXP2000_PCI_CH3_DESC_PTR IXP2000_PCI_CSR(0xCC)
#define IXP2000_PCI_CH3_CNTRL IXP2000_PCI_CSR(0xD0)
#define IXP2000_PCI_CH3_ME_PARAM IXP2000_PCI_CSR(0xD4)
#define IXP2000_DMA_INF_MODE IXP2000_PCI_CSR(0xE0)
/*
* Size masks for BARs
*/
#define IXP2000_PCI_SRAM_BASE_ADDR_MASK IXP2000_PCI_CSR(0xFC)
#define IXP2000_PCI_DRAM_BASE_ADDR_MASK IXP2000_PCI_CSR(0x100)
/*
* Control and uEngine related
*/
#define IXP2000_PCI_CONTROL IXP2000_PCI_CSR(0x13C)
#define IXP2000_PCI_ADDR_EXT IXP2000_PCI_CSR(0x140)
#define IXP2000_PCI_ME_PUSH_STATUS IXP2000_PCI_CSR(0x148)
#define IXP2000_PCI_ME_PUSH_EN IXP2000_PCI_CSR(0x14C)
#define IXP2000_PCI_ERR_STATUS IXP2000_PCI_CSR(0x150)
#define IXP2000_PCI_ERR_ENABLE IXP2000_PCI_CSR(0x154)
/*
* Inbound PCI interrupt control
*/
#define IXP2000_PCI_XSCALE_INT_STATUS IXP2000_PCI_CSR(0x158)
#define IXP2000_PCI_XSCALE_INT_ENABLE IXP2000_PCI_CSR(0x15C)
#define IXP2000_PCICNTL_PNR (1<<17) /* PCI not Reset bit of PCI_CONTROL */
#define IXP2000_PCICNTL_PCF (1<<28) /* PCI Central function bit */
#define IXP2000_XSCALE_INT (1<<1) /* Interrupt from XScale to PCI */
/* These are from the IRQ register in the PCI ISR register */
#define PCI_CONTROL_BE_DEO (1 << 22) /* Big Endian Data Enable Out */
#define PCI_CONTROL_BE_DEI (1 << 21) /* Big Endian Data Enable In */
#define PCI_CONTROL_BE_BEO (1 << 20) /* Big Endian Byte Enable Out */
#define PCI_CONTROL_BE_BEI (1 << 19) /* Big Endian Byte Enable In */
#define PCI_CONTROL_IEE (1 << 17) /* I/O cycle Endian swap Enable */
#define IXP2000_PCI_RST_REL (1 << 2)
#define CFG_RST_DIR (*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF)
#define CFG_PCI_BOOT_HOST (1 << 2)
#define CFG_BOOT_PROM (1 << 1)
/*
* SlowPort CSRs
*
* The slowport is used to access things like flash, SONET framer control
* ports, slave microprocessors, CPLDs, and others of chip memory mapped
* peripherals.
*/
#define SLOWPORT_CSR(x) (volatile unsigned long*)(IXP2000_SLOWPORT_CSR_VIRT_BASE | (x))
#define IXP2000_SLOWPORT_CCR SLOWPORT_CSR(0x00)
#define IXP2000_SLOWPORT_WTC1 SLOWPORT_CSR(0x04)
#define IXP2000_SLOWPORT_WTC2 SLOWPORT_CSR(0x08)
#define IXP2000_SLOWPORT_RTC1 SLOWPORT_CSR(0x0c)
#define IXP2000_SLOWPORT_RTC2 SLOWPORT_CSR(0x10)
#define IXP2000_SLOWPORT_FSR SLOWPORT_CSR(0x14)
#define IXP2000_SLOWPORT_PCR SLOWPORT_CSR(0x18)
#define IXP2000_SLOWPORT_ADC SLOWPORT_CSR(0x1C)
#define IXP2000_SLOWPORT_FAC SLOWPORT_CSR(0x20)
#define IXP2000_SLOWPORT_FRM SLOWPORT_CSR(0x24)
#define IXP2000_SLOWPORT_FIN SLOWPORT_CSR(0x28)
/*
* CCR values.
* The CCR configures the clock division for the slowport interface.
*/
#define SLOWPORT_CCR_DIV_1 0x00
#define SLOWPORT_CCR_DIV_2 0x01
#define SLOWPORT_CCR_DIV_4 0x02
#define SLOWPORT_CCR_DIV_6 0x03
#define SLOWPORT_CCR_DIV_8 0x04
#define SLOWPORT_CCR_DIV_10 0x05
#define SLOWPORT_CCR_DIV_12 0x06
#define SLOWPORT_CCR_DIV_14 0x07
#define SLOWPORT_CCR_DIV_16 0x08
#define SLOWPORT_CCR_DIV_18 0x09
#define SLOWPORT_CCR_DIV_20 0x0a
#define SLOWPORT_CCR_DIV_22 0x0b
#define SLOWPORT_CCR_DIV_24 0x0c
#define SLOWPORT_CCR_DIV_26 0x0d
#define SLOWPORT_CCR_DIV_28 0x0e
#define SLOWPORT_CCR_DIV_30 0x0f
/*
* PCR values. PCR configure the mode of the interface.
*/
#define SLOWPORT_MODE_FLASH 0x00
#define SLOWPORT_MODE_LUCENT 0x01
#define SLOWPORT_MODE_PMC_SIERRA 0x02
#define SLOWPORT_MODE_INTEL_UP 0x03
#define SLOWPORT_MODE_MOTOROLA_UP 0x04
/*
* ADC values. Defines data and address bus widths.
*/
#define SLOWPORT_ADDR_WIDTH_8 0x00
#define SLOWPORT_ADDR_WIDTH_16 0x01
#define SLOWPORT_ADDR_WIDTH_24 0x02
#define SLOWPORT_ADDR_WIDTH_32 0x03
#define SLOWPORT_DATA_WIDTH_8 0x00
#define SLOWPORT_DATA_WIDTH_16 0x10
#define SLOWPORT_DATA_WIDTH_24 0x20
#define SLOWPORT_DATA_WIDTH_32 0x30
/*
* Masks and shifts for various fields in the WTC and RTC registers.
*/
#define SLOWPORT_WRTC_MASK_HD 0x0003
#define SLOWPORT_WRTC_MASK_PW 0x003c
#define SLOWPORT_WRTC_MASK_SU 0x03c0
#define SLOWPORT_WRTC_SHIFT_HD 0x00
#define SLOWPORT_WRTC_SHIFT_SU 0x02
#define SLOWPORT_WRTC_SHFIT_PW 0x06
/*
* GPIO registers & GPIO interface.
*/
#define IXP2000_GPIO_REG(x) ((volatile unsigned long*)(IXP2000_GPIO_VIRT_BASE+(x)))
#define IXP2000_GPIO_PLR IXP2000_GPIO_REG(0x00)
#define IXP2000_GPIO_PDPR IXP2000_GPIO_REG(0x04)
#define IXP2000_GPIO_PDSR IXP2000_GPIO_REG(0x08)
#define IXP2000_GPIO_PDCR IXP2000_GPIO_REG(0x0c)
#define IXP2000_GPIO_POPR IXP2000_GPIO_REG(0x10)
#define IXP2000_GPIO_POSR IXP2000_GPIO_REG(0x14)
#define IXP2000_GPIO_POCR IXP2000_GPIO_REG(0x18)
#define IXP2000_GPIO_REDR IXP2000_GPIO_REG(0x1c)
#define IXP2000_GPIO_FEDR IXP2000_GPIO_REG(0x20)
#define IXP2000_GPIO_EDSR IXP2000_GPIO_REG(0x24)
#define IXP2000_GPIO_LSHR IXP2000_GPIO_REG(0x28)
#define IXP2000_GPIO_LSLR IXP2000_GPIO_REG(0x2c)
#define IXP2000_GPIO_LDSR IXP2000_GPIO_REG(0x30)
#define IXP2000_GPIO_INER IXP2000_GPIO_REG(0x34)
#define IXP2000_GPIO_INSR IXP2000_GPIO_REG(0x38)
#define IXP2000_GPIO_INCR IXP2000_GPIO_REG(0x3c)
#define IXP2000_GPIO_INST IXP2000_GPIO_REG(0x40)
/*
* "Global" registers...whatever that's supposed to mean.
*/
#define GLOBAL_REG_BASE (IXP2000_GLOBAL_REG_VIRT_BASE + 0x0a00)
#define GLOBAL_REG(x) (volatile unsigned long*)(GLOBAL_REG_BASE | (x))
#define IXP2000_MAJ_PROD_TYPE_MASK 0x001F0000
#define IXP2000_MAJ_PROD_TYPE_IXP2000 0x00000000
#define IXP2000_MIN_PROD_TYPE_MASK 0x0000FF00
#define IXP2000_MIN_PROD_TYPE_IXP2400 0x00000200
#define IXP2000_MIN_PROD_TYPE_IXP2850 0x00000100
#define IXP2000_MIN_PROD_TYPE_IXP2800 0x00000000
#define IXP2000_MAJ_REV_MASK 0x000000F0
#define IXP2000_MIN_REV_MASK 0x0000000F
#define IXP2000_PROD_ID_MASK 0xFFFFFFFF
#define IXP2000_PRODUCT_ID GLOBAL_REG(0x00)
#define IXP2000_MISC_CONTROL GLOBAL_REG(0x04)
#define IXP2000_MSF_CLK_CNTRL GLOBAL_REG(0x08)
#define IXP2000_RESET0 GLOBAL_REG(0x0c)
#define IXP2000_RESET1 GLOBAL_REG(0x10)
#define IXP2000_CCR GLOBAL_REG(0x14)
#define IXP2000_STRAP_OPTIONS GLOBAL_REG(0x18)
#define RSTALL (1 << 16)
#define WDT_RESET_ENABLE 0x01000000
/*
* MSF registers. The IXP2400 and IXP2800 have somewhat different MSF
* units, but the registers that differ between the two don't overlap,
* so we can have one register list for both.
*/
#define IXP2000_MSF_REG(x) ((volatile unsigned long*)(IXP2000_MSF_VIRT_BASE + (x)))
#define IXP2000_MSF_RX_CONTROL IXP2000_MSF_REG(0x0000)
#define IXP2000_MSF_TX_CONTROL IXP2000_MSF_REG(0x0004)
#define IXP2000_MSF_INTERRUPT_STATUS IXP2000_MSF_REG(0x0008)
#define IXP2000_MSF_INTERRUPT_ENABLE IXP2000_MSF_REG(0x000c)
#define IXP2000_MSF_CSIX_TYPE_MAP IXP2000_MSF_REG(0x0010)
#define IXP2000_MSF_FC_EGRESS_STATUS IXP2000_MSF_REG(0x0014)
#define IXP2000_MSF_FC_INGRESS_STATUS IXP2000_MSF_REG(0x0018)
#define IXP2000_MSF_HWM_CONTROL IXP2000_MSF_REG(0x0024)
#define IXP2000_MSF_FC_STATUS_OVERRIDE IXP2000_MSF_REG(0x0028)
#define IXP2000_MSF_CLOCK_CONTROL IXP2000_MSF_REG(0x002c)
#define IXP2000_MSF_RX_PORT_MAP IXP2000_MSF_REG(0x0040)
#define IXP2000_MSF_RBUF_ELEMENT_DONE IXP2000_MSF_REG(0x0044)
#define IXP2000_MSF_RX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0048)
#define IXP2000_MSF_RX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0048)
#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_0 IXP2000_MSF_REG(0x0050)
#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_1 IXP2000_MSF_REG(0x0054)
#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_2 IXP2000_MSF_REG(0x0058)
#define IXP2000_MSF_TX_SEQUENCE_0 IXP2000_MSF_REG(0x0060)
#define IXP2000_MSF_TX_SEQUENCE_1 IXP2000_MSF_REG(0x0064)
#define IXP2000_MSF_TX_SEQUENCE_2 IXP2000_MSF_REG(0x0068)
#define IXP2000_MSF_TX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0070)
#define IXP2000_MSF_TX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0070)
#define IXP2000_MSF_RX_UP_CONTROL_0 IXP2000_MSF_REG(0x0080)
#define IXP2000_MSF_RX_UP_CONTROL_1 IXP2000_MSF_REG(0x0084)
#define IXP2000_MSF_RX_UP_CONTROL_2 IXP2000_MSF_REG(0x0088)
#define IXP2000_MSF_RX_UP_CONTROL_3 IXP2000_MSF_REG(0x008c)
#define IXP2000_MSF_TX_UP_CONTROL_0 IXP2000_MSF_REG(0x0090)
#define IXP2000_MSF_TX_UP_CONTROL_1 IXP2000_MSF_REG(0x0094)
#define IXP2000_MSF_TX_UP_CONTROL_2 IXP2000_MSF_REG(0x0098)
#define IXP2000_MSF_TX_UP_CONTROL_3 IXP2000_MSF_REG(0x009c)
#define IXP2000_MSF_TRAIN_DATA IXP2000_MSF_REG(0x00a0)
#define IXP2000_MSF_TRAIN_CALENDAR IXP2000_MSF_REG(0x00a4)
#define IXP2000_MSF_TRAIN_FLOW_CONTROL IXP2000_MSF_REG(0x00a8)
#define IXP2000_MSF_TX_CALENDAR_0 IXP2000_MSF_REG(0x1000)
#define IXP2000_MSF_RX_PORT_CALENDAR_STATUS IXP2000_MSF_REG(0x1400)
#endif /* _IXP2000_H_ */
/*
* arch/arm/mach-ixp2000/include/mach/memory.h
*
* Copyright (c) 2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
#define PLAT_PHYS_OFFSET UL(0x00000000)
#include <mach/ixp2000-regs.h>
#define IXP2000_PCI_SDRAM_OFFSET (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)
#define __phys_to_bus(x) ((x) + (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET))
#define __bus_to_phys(x) ((x) - (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET))
#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v))
#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b))
#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p))
#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b))
#endif
/*
* arch/arm/mach-ixp2000/include/mach/platform.h
*
* Various bits of code used by platform-level code.
*
* 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 __ASSEMBLY__
static inline unsigned long ixp2000_reg_read(volatile void *reg)
{
return *((volatile unsigned long *)reg);
}
static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
{
*((volatile unsigned long *)reg) = val;
}
/*
* On the IXP2400, we can't use XCB=000 due to chip bugs. We use
* XCB=101 instead, but that makes all I/O accesses bufferable. This
* is not a problem in general, but we do have to be slightly more
* careful because I/O writes are no longer automatically flushed out
* of the write buffer.
*
* In cases where we want to make sure that a write has been flushed
* out of the write buffer before we proceed, for example when masking
* a device interrupt before re-enabling IRQs in CPSR, we can use this
* function, ixp2000_reg_wrb, which performs a write, a readback, and
* issues a dummy instruction dependent on the value of the readback
* (mov rX, rX) to make sure that the readback has completed before we
* continue.
*/
static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
{
unsigned long dummy;
*((volatile unsigned long *)reg) = val;
dummy = *((volatile unsigned long *)reg);
__asm__ __volatile__("mov %0, %0" : "+r" (dummy));
}
/*
* Boards may multiplex different devices on the 2nd channel of
* the slowport interface that each need different configuration
* settings. For example, the IXDP2400 uses channel 2 on the interface
* to access the CPLD, the switch fabric card, and the media card. Each
* one needs a different mode so drivers must save/restore the mode
* before and after each operation.
*
* acquire_slowport(&your_config);
* ...
* do slowport operations
* ...
* release_slowport();
*
* Note that while you have the slowport, you are holding a spinlock,
* so your code should be written as if you explicitly acquired a lock.
*
* The configuration only affects device 2 on the slowport, so the
* MTD map driver does not acquire/release the slowport.
*/
struct slowport_cfg {
unsigned long CCR; /* Clock divide */
unsigned long WTC; /* Write Timing Control */
unsigned long RTC; /* Read Timing Control */
unsigned long PCR; /* Protocol Control Register */
unsigned long ADC; /* Address/Data Width Control */
};
void ixp2000_acquire_slowport(struct slowport_cfg *, struct slowport_cfg *);
void ixp2000_release_slowport(struct slowport_cfg *);
/*
* IXP2400 A0/A1 and IXP2800 A0/A1/A2 have broken slowport that requires
* tweaking of addresses in the MTD driver.
*/
static inline unsigned ixp2000_has_broken_slowport(void)
{
unsigned long id = *IXP2000_PRODUCT_ID;
unsigned long id_prod = id & (IXP2000_MAJ_PROD_TYPE_MASK |
IXP2000_MIN_PROD_TYPE_MASK);
return (((id_prod ==
/* fixed in IXP2400-B0 */
(IXP2000_MAJ_PROD_TYPE_IXP2000 |
IXP2000_MIN_PROD_TYPE_IXP2400)) &&
((id & IXP2000_MAJ_REV_MASK) == 0)) ||
((id_prod ==
/* fixed in IXP2800-B0 */
(IXP2000_MAJ_PROD_TYPE_IXP2000 |
IXP2000_MIN_PROD_TYPE_IXP2800)) &&
((id & IXP2000_MAJ_REV_MASK) == 0)) ||
((id_prod ==
/* fixed in IXP2850-B0 */
(IXP2000_MAJ_PROD_TYPE_IXP2000 |
IXP2000_MIN_PROD_TYPE_IXP2850)) &&
((id & IXP2000_MAJ_REV_MASK) == 0)));
}
static inline unsigned int ixp2000_has_flash(void)
{
return ((*IXP2000_STRAP_OPTIONS) & (CFG_BOOT_PROM));
}
static inline unsigned int ixp2000_is_pcimaster(void)
{
return ((*IXP2000_STRAP_OPTIONS) & (CFG_PCI_BOOT_HOST));
}
void ixp2000_map_io(void);
void ixp2000_uart_init(void);
void ixp2000_init_irq(void);
void ixp2000_init_time(unsigned long);
void ixp2000_restart(char, const char *);
unsigned long ixp2000_gettimeoffset(void);
struct pci_sys_data;
u32 *ixp2000_pci_config_addr(unsigned int bus, unsigned int devfn, int where);
void ixp2000_pci_preinit(void);
int ixp2000_pci_setup(int, struct pci_sys_data*);
struct pci_bus* ixp2000_pci_scan_bus(int, struct pci_sys_data*);
int ixp2000_pci_read_config(struct pci_bus*, unsigned int, int, int, u32 *);
int ixp2000_pci_write_config(struct pci_bus*, unsigned int, int, int, u32);
/*
* Several of the IXP2000 systems have banked flash so we need to extend the
* flash_platform_data structure with some private pointers
*/
struct ixp2000_flash_data {
struct flash_platform_data *platform_data;
int nr_banks;
unsigned long (*bank_setup)(unsigned long);
};
struct ixp2000_i2c_pins {
unsigned long sda_pin;
unsigned long scl_pin;
};
#endif /* !__ASSEMBLY__ */
/*
* arch/arm/mach-ixp2000/include/mach/timex.h
*
* IXP2000 architecture timex specifications
*/
/*
* Default clock is 50MHz APB, but platform code can override this
*/
#define CLOCK_TICK_RATE 50000000
/*
* arch/arm/mach-ixp2000/include/mach/uncompress.h
*
*
* Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2002 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/serial_reg.h>
#define UART_BASE 0xc0030000
#define PHYS(x) ((volatile unsigned long *)(UART_BASE + x))
#define UARTDR PHYS(0x00) /* Transmit reg dlab=0 */
#define UARTDLL PHYS(0x00) /* Divisor Latch reg dlab=1*/
#define UARTDLM PHYS(0x04) /* Divisor Latch reg dlab=1*/
#define UARTIER PHYS(0x04) /* Interrupt enable reg */
#define UARTFCR PHYS(0x08) /* FIFO control reg dlab =0*/
#define UARTLCR PHYS(0x0c) /* Control reg */
#define UARTSR PHYS(0x14) /* Status reg */
static inline void putc(int c)
{
int j = 0x1000;
while (--j && !(*UARTSR & UART_LSR_THRE))
barrier();
*UARTDR = c;
}
static inline void flush(void)
{
}
#define arch_decomp_setup()
#define arch_decomp_wdog()
/*
* arch/arm/mach-ixp2000/ixdp2400.c
*
* IXDP2400 platform support
*
* Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/pci.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/flash.h>
#include <asm/mach/arch.h>
/*************************************************************************
* IXDP2400 timer tick
*************************************************************************/
static void __init ixdp2400_timer_init(void)
{
int numerator, denominator;
int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8};
numerator = (*(IXDP2400_CPLD_SYS_CLK_M) & 0xFF) *2;
denominator = denom_array[(*(IXDP2400_CPLD_SYS_CLK_N) & 0x7)];
ixp2000_init_time(((3125000 * numerator) / (denominator)) / 2);
}
static struct sys_timer ixdp2400_timer = {
.init = ixdp2400_timer_init,
.offset = ixp2000_gettimeoffset,
};
/*************************************************************************
* IXDP2400 PCI
*************************************************************************/
void __init ixdp2400_pci_preinit(void)
{
ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
ixp2000_pci_preinit();
pcibios_setup("firmware");
}
int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys)
{
sys->mem_offset = 0xe0000000;
ixp2000_pci_setup(nr, sys);
return 1;
}
static int __init ixdp2400_pci_map_irq(const struct pci_dev *dev, u8 slot,
u8 pin)
{
if (ixdp2x00_master_npu()) {
/*
* Root bus devices. Slave NPU is only one with interrupt.
* Everything else, we just return -1 b/c nothing else
* on the root bus has interrupts.
*/
if(!dev->bus->self) {
if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN )
return IRQ_IXDP2400_INGRESS_NPU;
return -1;
}
/*
* Bridge behind the PMC slot.
* NOTE: Only INTA from the PMC slot is routed. VERY BAD.
*/
if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN &&
dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN &&
!dev->bus->parent->self->bus->parent)
return IRQ_IXDP2400_PMC;
/*
* Device behind the first bridge
*/
if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) {
switch(dev->devfn) {
case IXDP2400_MASTER_ENET_DEVFN:
return IRQ_IXDP2400_ENET;
case IXDP2400_MEDIA_DEVFN:
return IRQ_IXDP2400_MEDIA_PCI;
case IXDP2400_SWITCH_FABRIC_DEVFN:
return IRQ_IXDP2400_SF_PCI;
case IXDP2X00_PMC_DEVFN:
return IRQ_IXDP2400_PMC;
}
}
return -1;
} else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
}
static void ixdp2400_pci_postinit(void)
{
struct pci_dev *dev;
if (ixdp2x00_master_npu()) {
dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN);
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
} else {
dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN);
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
ixdp2x00_slave_pci_postinit();
}
}
static struct hw_pci ixdp2400_pci __initdata = {
.nr_controllers = 1,
.setup = ixdp2400_pci_setup,
.preinit = ixdp2400_pci_preinit,
.postinit = ixdp2400_pci_postinit,
.scan = ixp2000_pci_scan_bus,
.map_irq = ixdp2400_pci_map_irq,
};
int __init ixdp2400_pci_init(void)
{
if (machine_is_ixdp2400())
pci_common_init(&ixdp2400_pci);
return 0;
}
subsys_initcall(ixdp2400_pci_init);
void __init ixdp2400_init_irq(void)
{
ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS);
}
MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.atag_offset = 0x100,
.map_io = ixdp2x00_map_io,
.init_irq = ixdp2400_init_irq,
.timer = &ixdp2400_timer,
.init_machine = ixdp2x00_init_machine,
.restart = ixp2000_restart,
MACHINE_END
/*
* arch/arm/mach-ixp2000/ixdp2800.c
*
* IXDP2800 platform support
*
* Original Author: Jeffrey Daly <jeffrey.daly@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/pci.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/flash.h>
#include <asm/mach/arch.h>
/*************************************************************************
* IXDP2800 timer tick
*************************************************************************/
static void __init ixdp2800_timer_init(void)
{
ixp2000_init_time(50000000);
}
static struct sys_timer ixdp2800_timer = {
.init = ixdp2800_timer_init,
.offset = ixp2000_gettimeoffset,
};
/*************************************************************************
* IXDP2800 PCI
*************************************************************************/
static void __init ixdp2800_slave_disable_pci_master(void)
{
*IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
}
static void __init ixdp2800_master_wait_for_slave(void)
{
volatile u32 *addr;
printk(KERN_INFO "IXDP2800: waiting for slave NPU to configure "
"its BAR sizes\n");
addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
PCI_BASE_ADDRESS_1);
do {
*addr = 0xffffffff;
cpu_relax();
} while (*addr != 0xfe000008);
addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
PCI_BASE_ADDRESS_2);
do {
*addr = 0xffffffff;
cpu_relax();
} while (*addr != 0xc0000008);
/*
* Configure the slave's SDRAM BAR by hand.
*/
*addr = 0x40000008;
}
static void __init ixdp2800_slave_wait_for_master_enable(void)
{
printk(KERN_INFO "IXDP2800: waiting for master NPU to enable us\n");
while ((*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER) == 0)
cpu_relax();
}
void __init ixdp2800_pci_preinit(void)
{
printk("ixdp2x00_pci_preinit called\n");
*IXP2000_PCI_ADDR_EXT = 0x0001e000;
if (!ixdp2x00_master_npu())
ixdp2800_slave_disable_pci_master();
*IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff;
*IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
ixp2000_pci_preinit();
if (ixdp2x00_master_npu()) {
/*
* Wait until the slave set its SRAM/SDRAM BAR sizes
* correctly before we proceed to scan and enumerate
* the bus.
*/
ixdp2800_master_wait_for_slave();
/*
* We configure the SDRAM BARs by hand because they
* are 1G and fall outside of the regular allocated
* PCI address space.
*/
*IXP2000_PCI_SDRAM_BAR = 0x00000008;
} else {
/*
* Wait for the master to complete scanning the bus
* and assigning resources before we proceed to scan
* the bus ourselves. Set pci=firmware to honor the
* master's resource assignment.
*/
ixdp2800_slave_wait_for_master_enable();
pcibios_setup("firmware");
}
}
/*
* We assign the SDRAM BARs for the two IXP2800 CPUs by hand, outside
* of the regular PCI window, because there's only 512M of outbound PCI
* memory window on each IXP, while we need 1G for each of the BARs.
*/
static void __devinit ixp2800_pci_fixup(struct pci_dev *dev)
{
if (machine_is_ixdp2800()) {
dev->resource[2].start = 0;
dev->resource[2].end = 0;
dev->resource[2].flags = 0;
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup);
static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys)
{
sys->mem_offset = 0x00000000;
ixp2000_pci_setup(nr, sys);
return 1;
}
static int __init ixdp2800_pci_map_irq(const struct pci_dev *dev, u8 slot,
u8 pin)
{
if (ixdp2x00_master_npu()) {
/*
* Root bus devices. Slave NPU is only one with interrupt.
* Everything else, we just return -1 which is invalid.
*/
if(!dev->bus->self) {
if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN )
return IRQ_IXDP2800_INGRESS_NPU;
return -1;
}
/*
* Bridge behind the PMC slot.
*/
if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN &&
dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN &&
!dev->bus->parent->self->bus->parent)
return IRQ_IXDP2800_PMC;
/*
* Device behind the first bridge
*/
if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) {
switch(dev->devfn) {
case IXDP2X00_PMC_DEVFN:
return IRQ_IXDP2800_PMC;
case IXDP2800_MASTER_ENET_DEVFN:
return IRQ_IXDP2800_EGRESS_ENET;
case IXDP2800_SWITCH_FABRIC_DEVFN:
return IRQ_IXDP2800_FABRIC;
}
}
return -1;
} else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
}
static void __init ixdp2800_master_enable_slave(void)
{
volatile u32 *addr;
printk(KERN_INFO "IXDP2800: enabling slave NPU\n");
addr = (volatile u32 *)ixp2000_pci_config_addr(0,
IXDP2X00_SLAVE_NPU_DEVFN,
PCI_COMMAND);
*addr |= PCI_COMMAND_MASTER;
}
static void __init ixdp2800_master_wait_for_slave_bus_scan(void)
{
volatile u32 *addr;
printk(KERN_INFO "IXDP2800: waiting for slave to finish bus scan\n");
addr = (volatile u32 *)ixp2000_pci_config_addr(0,
IXDP2X00_SLAVE_NPU_DEVFN,
PCI_COMMAND);
while ((*addr & PCI_COMMAND_MEMORY) == 0)
cpu_relax();
}
static void __init ixdp2800_slave_signal_bus_scan_completion(void)
{
printk(KERN_INFO "IXDP2800: bus scan done, signaling master\n");
*IXP2000_PCI_CMDSTAT |= PCI_COMMAND_MEMORY;
}
static void __init ixdp2800_pci_postinit(void)
{
if (!ixdp2x00_master_npu()) {
ixdp2x00_slave_pci_postinit();
ixdp2800_slave_signal_bus_scan_completion();
}
}
struct __initdata hw_pci ixdp2800_pci __initdata = {
.nr_controllers = 1,
.setup = ixdp2800_pci_setup,
.preinit = ixdp2800_pci_preinit,
.postinit = ixdp2800_pci_postinit,
.scan = ixp2000_pci_scan_bus,
.map_irq = ixdp2800_pci_map_irq,
};
int __init ixdp2800_pci_init(void)
{
if (machine_is_ixdp2800()) {
struct pci_dev *dev;
pci_common_init(&ixdp2800_pci);
if (ixdp2x00_master_npu()) {
dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
ixdp2800_master_enable_slave();
ixdp2800_master_wait_for_slave_bus_scan();
} else {
dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN);
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
}
}
return 0;
}
subsys_initcall(ixdp2800_pci_init);
void __init ixdp2800_init_irq(void)
{
ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2800_NR_IRQS);
}
MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.atag_offset = 0x100,
.map_io = ixdp2x00_map_io,
.init_irq = ixdp2800_init_irq,
.timer = &ixdp2800_timer,
.init_machine = ixdp2x00_init_machine,
.restart = ixp2000_restart,
MACHINE_END
/*
* arch/arm/mach-ixp2000/ixdp2x00.c
*
* Code common to IXDP2400 and IXDP2800 platforms.
*
* Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/pci.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/flash.h>
#include <asm/mach/arch.h>
#include <mach/gpio-ixp2000.h>
/*************************************************************************
* IXDP2x00 IRQ Initialization
*************************************************************************/
static volatile unsigned long *board_irq_mask;
static volatile unsigned long *board_irq_stat;
static unsigned long board_irq_count;
#ifdef CONFIG_ARCH_IXDP2400
/*
* Slowport configuration for accessing CPLD registers on IXDP2x00
*/
static struct slowport_cfg slowport_cpld_cfg = {
.CCR = SLOWPORT_CCR_DIV_2,
.WTC = 0x00000070,
.RTC = 0x00000070,
.PCR = SLOWPORT_MODE_FLASH,
.ADC = SLOWPORT_ADDR_WIDTH_24 | SLOWPORT_DATA_WIDTH_8
};
#endif
static void ixdp2x00_irq_mask(struct irq_data *d)
{
unsigned long dummy;
static struct slowport_cfg old_cfg;
/*
* This is ugly in common code but really don't know
* of a better way to handle it. :(
*/
#ifdef CONFIG_ARCH_IXDP2400
if (machine_is_ixdp2400())
ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg);
#endif
dummy = *board_irq_mask;
dummy |= IXP2000_BOARD_IRQ_MASK(d->irq);
ixp2000_reg_wrb(board_irq_mask, dummy);
#ifdef CONFIG_ARCH_IXDP2400
if (machine_is_ixdp2400())
ixp2000_release_slowport(&old_cfg);
#endif
}
static void ixdp2x00_irq_unmask(struct irq_data *d)
{
unsigned long dummy;
static struct slowport_cfg old_cfg;
#ifdef CONFIG_ARCH_IXDP2400
if (machine_is_ixdp2400())
ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg);
#endif
dummy = *board_irq_mask;
dummy &= ~IXP2000_BOARD_IRQ_MASK(d->irq);
ixp2000_reg_wrb(board_irq_mask, dummy);
if (machine_is_ixdp2400())
ixp2000_release_slowport(&old_cfg);
}
static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc)
{
volatile u32 ex_interrupt = 0;
static struct slowport_cfg old_cfg;
int i;
desc->irq_data.chip->irq_mask(&desc->irq_data);
#ifdef CONFIG_ARCH_IXDP2400
if (machine_is_ixdp2400())
ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg);
#endif
ex_interrupt = *board_irq_stat & 0xff;
if (machine_is_ixdp2400())
ixp2000_release_slowport(&old_cfg);
if(!ex_interrupt) {
printk(KERN_ERR "Spurious IXDP2x00 CPLD interrupt!\n");
return;
}
for(i = 0; i < board_irq_count; i++) {
if(ex_interrupt & (1 << i)) {
int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
generic_handle_irq(cpld_irq);
}
}
desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
static struct irq_chip ixdp2x00_cpld_irq_chip = {
.irq_ack = ixdp2x00_irq_mask,
.irq_mask = ixdp2x00_irq_mask,
.irq_unmask = ixdp2x00_irq_unmask
};
void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_of_irqs)
{
unsigned int irq;
ixp2000_init_irq();
if (!ixdp2x00_master_npu())
return;
board_irq_stat = stat_reg;
board_irq_mask = mask_reg;
board_irq_count = nr_of_irqs;
*board_irq_mask = 0xffffffff;
for(irq = IXP2000_BOARD_IRQ(0); irq < IXP2000_BOARD_IRQ(board_irq_count); irq++) {
irq_set_chip_and_handler(irq, &ixdp2x00_cpld_irq_chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
/* Hook into PCI interrupt */
irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler);
}
/*************************************************************************
* IXDP2x00 memory map
*************************************************************************/
static struct map_desc ixdp2x00_io_desc __initdata = {
.virtual = IXDP2X00_VIRT_CPLD_BASE,
.pfn = __phys_to_pfn(IXDP2X00_PHYS_CPLD_BASE),
.length = IXDP2X00_CPLD_SIZE,
.type = MT_DEVICE
};
void __init ixdp2x00_map_io(void)
{
ixp2000_map_io();
iotable_init(&ixdp2x00_io_desc, 1);
}
/*************************************************************************
* IXDP2x00-common PCI init
*
* The IXDP2[48]00 has a horrid PCI bus layout. Basically the board
* contains two NPUs (ingress and egress) connected over PCI, both running
* instances of the kernel. So far so good. Peers on the PCI bus running
* Linux is a common design in telecom systems. The problem is that instead
* of all the devices being controlled by a single host, different
* devices are controlled by different NPUs on the same bus, leading to
* multiple hosts on the bus. The exact bus layout looks like:
*
* Bus 0
* Master NPU <-------------------+-------------------> Slave NPU
* |
* |
* P2P
* |
*
* Bus 1 |
* <--+------+---------+---------+------+-->
* | | | | |
* | | | | |
* ... Dev PMC Media Eth0 Eth1 ...
*
* The master controls all but Eth1, which is controlled by the
* slave. What this means is that the both the master and the slave
* have to scan the bus, but only one of them can enumerate the bus.
* In addition, after the bus is scanned, each kernel must remove
* the device(s) it does not control from the PCI dev list otherwise
* a driver on each NPU will try to manage it and we will have horrible
* conflicts. Oh..and the slave NPU needs to see the master NPU
* for Intel's drivers to work properly. Closed source drivers...
*
* The way we deal with this is fairly simple but ugly:
*
* 1) Let master scan and enumerate the bus completely.
* 2) Master deletes Eth1 from device list.
* 3) Slave scans bus and then deletes all but Eth1 (Eth0 on slave)
* from device list.
* 4) Find HW designers and LART them.
*
* The boards also do not do normal PCI IRQ routing, or any sort of
* sensical swizzling, so we just need to check where on the bus a
* device sits and figure out to which CPLD pin the interrupt is routed.
* See ixdp2[48]00.c files.
*
*************************************************************************/
void ixdp2x00_slave_pci_postinit(void)
{
struct pci_dev *dev;
/*
* Remove PMC device is there is one
*/
if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) {
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
}
dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN);
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
}
/**************************************************************************
* IXDP2x00 Machine Setup
*************************************************************************/
static struct flash_platform_data ixdp2x00_platform_data = {
.map_name = "cfi_probe",
.width = 1,
};
static struct ixp2000_flash_data ixdp2x00_flash_data = {
.platform_data = &ixdp2x00_platform_data,
.nr_banks = 1
};
static struct resource ixdp2x00_flash_resource = {
.start = 0xc4000000,
.end = 0xc4000000 + 0x00ffffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device ixdp2x00_flash = {
.name = "IXP2000-Flash",
.id = 0,
.dev = {
.platform_data = &ixdp2x00_flash_data,
},
.num_resources = 1,
.resource = &ixdp2x00_flash_resource,
};
static struct ixp2000_i2c_pins ixdp2x00_i2c_gpio_pins = {
.sda_pin = IXDP2X00_GPIO_SDA,
.scl_pin = IXDP2X00_GPIO_SCL,
};
static struct platform_device ixdp2x00_i2c_controller = {
.name = "IXP2000-I2C",
.id = 0,
.dev = {
.platform_data = &ixdp2x00_i2c_gpio_pins,
},
.num_resources = 0
};
static struct platform_device *ixdp2x00_devices[] __initdata = {
&ixdp2x00_flash,
&ixdp2x00_i2c_controller
};
void __init ixdp2x00_init_machine(void)
{
gpio_line_set(IXDP2X00_GPIO_I2C_ENABLE, 1);
gpio_line_config(IXDP2X00_GPIO_I2C_ENABLE, GPIO_OUT);
platform_add_devices(ixdp2x00_devices, ARRAY_SIZE(ixdp2x00_devices));
ixp2000_uart_init();
}
/*
* arch/arm/mach-ixp2000/ixdp2x01.c
*
* Code common to Intel IXDP2401 and IXDP2801 platforms
*
* Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2002-2003 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/pci.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
/*************************************************************************
* IXDP2x01 IRQ Handling
*************************************************************************/
static void ixdp2x01_irq_mask(struct irq_data *d)
{
ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG,
IXP2000_BOARD_IRQ_MASK(d->irq));
}
static void ixdp2x01_irq_unmask(struct irq_data *d)
{
ixp2000_reg_write(IXDP2X01_INT_MASK_CLR_REG,
IXP2000_BOARD_IRQ_MASK(d->irq));
}
static u32 valid_irq_mask;
static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc)
{
u32 ex_interrupt;
int i;
desc->irq_data.chip->irq_mask(&desc->irq_data);
ex_interrupt = *IXDP2X01_INT_STAT_REG & valid_irq_mask;
if (!ex_interrupt) {
printk(KERN_ERR "Spurious IXDP2X01 CPLD interrupt!\n");
return;
}
for (i = 0; i < IXP2000_BOARD_IRQS; i++) {
if (ex_interrupt & (1 << i)) {
int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
generic_handle_irq(cpld_irq);
}
}
desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
static struct irq_chip ixdp2x01_irq_chip = {
.irq_mask = ixdp2x01_irq_mask,
.irq_ack = ixdp2x01_irq_mask,
.irq_unmask = ixdp2x01_irq_unmask
};
/*
* We only do anything if we are the master NPU on the board.
* The slave NPU only has the ethernet chip going directly to
* the PCIB interrupt input.
*/
void __init ixdp2x01_init_irq(void)
{
int irq = 0;
/* initialize chip specific interrupts */
ixp2000_init_irq();
if (machine_is_ixdp2401())
valid_irq_mask = IXDP2401_VALID_IRQ_MASK;
else
valid_irq_mask = IXDP2801_VALID_IRQ_MASK;
/* Mask all interrupts from CPLD, disable simulation */
ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff);
ixp2000_reg_wrb(IXDP2X01_INT_SIM_REG, 0);
for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) {
if (irq & valid_irq_mask) {
irq_set_chip_and_handler(irq, &ixdp2x01_irq_chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
} else {
set_irq_flags(irq, 0);
}
}
/* Hook into PCI interrupts */
irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler);
}
/*************************************************************************
* IXDP2x01 memory map
*************************************************************************/
static struct map_desc ixdp2x01_io_desc __initdata = {
.virtual = IXDP2X01_VIRT_CPLD_BASE,
.pfn = __phys_to_pfn(IXDP2X01_PHYS_CPLD_BASE),
.length = IXDP2X01_CPLD_REGION_SIZE,
.type = MT_DEVICE
};
static void __init ixdp2x01_map_io(void)
{
ixp2000_map_io();
iotable_init(&ixdp2x01_io_desc, 1);
}
/*************************************************************************
* IXDP2x01 serial ports
*************************************************************************/
static struct plat_serial8250_port ixdp2x01_serial_port1[] = {
{
.mapbase = (unsigned long)IXDP2X01_UART1_PHYS_BASE,
.membase = (char *)IXDP2X01_UART1_VIRT_BASE,
.irq = IRQ_IXDP2X01_UART1,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM32,
.regshift = 2,
.uartclk = IXDP2X01_UART_CLK,
},
{ }
};
static struct resource ixdp2x01_uart_resource1 = {
.start = IXDP2X01_UART1_PHYS_BASE,
.end = IXDP2X01_UART1_PHYS_BASE + 0xffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device ixdp2x01_serial_device1 = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM1,
.dev = {
.platform_data = ixdp2x01_serial_port1,
},
.num_resources = 1,
.resource = &ixdp2x01_uart_resource1,
};
static struct plat_serial8250_port ixdp2x01_serial_port2[] = {
{
.mapbase = (unsigned long)IXDP2X01_UART2_PHYS_BASE,
.membase = (char *)IXDP2X01_UART2_VIRT_BASE,
.irq = IRQ_IXDP2X01_UART2,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM32,
.regshift = 2,
.uartclk = IXDP2X01_UART_CLK,
},
{ }
};
static struct resource ixdp2x01_uart_resource2 = {
.start = IXDP2X01_UART2_PHYS_BASE,
.end = IXDP2X01_UART2_PHYS_BASE + 0xffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device ixdp2x01_serial_device2 = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM2,
.dev = {
.platform_data = ixdp2x01_serial_port2,
},
.num_resources = 1,
.resource = &ixdp2x01_uart_resource2,
};
static void ixdp2x01_uart_init(void)
{
platform_device_register(&ixdp2x01_serial_device1);
platform_device_register(&ixdp2x01_serial_device2);
}
/*************************************************************************
* IXDP2x01 timer tick configuration
*************************************************************************/
static unsigned int ixdp2x01_clock;
static int __init ixdp2x01_clock_setup(char *str)
{
ixdp2x01_clock = simple_strtoul(str, NULL, 10);
return 1;
}
__setup("ixdp2x01_clock=", ixdp2x01_clock_setup);
static void __init ixdp2x01_timer_init(void)
{
if (!ixdp2x01_clock)
ixdp2x01_clock = 50000000;
ixp2000_init_time(ixdp2x01_clock);
}
static struct sys_timer ixdp2x01_timer = {
.init = ixdp2x01_timer_init,
.offset = ixp2000_gettimeoffset,
};
/*************************************************************************
* IXDP2x01 PCI
*************************************************************************/
void __init ixdp2x01_pci_preinit(void)
{
ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000);
ixp2000_pci_preinit();
pcibios_setup("firmware");
}
#define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
static int __init ixdp2x01_pci_map_irq(const struct pci_dev *dev, u8 slot,
u8 pin)
{
u8 bus = dev->bus->number;
u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin);
struct pci_bus *tmp_bus = dev->bus;
/* Primary bus, no interrupts here */
if (bus == 0) {
return -1;
}
/* Lookup first leaf in bus tree */
while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL)) {
tmp_bus = tmp_bus->parent;
}
/* Select between known bridges */
switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) {
/* Device is located after first MB bridge */
case 0x0008:
if (tmp_bus == dev->bus) {
/* Device is located directly after first MB bridge */
switch (devpin) {
case DEVPIN(1, 1): /* Onboard 82546 ch 0 */
if (machine_is_ixdp2401())
return IRQ_IXDP2401_INTA_82546;
return -1;
case DEVPIN(1, 2): /* Onboard 82546 ch 1 */
if (machine_is_ixdp2401())
return IRQ_IXDP2401_INTB_82546;
return -1;
case DEVPIN(0, 1): /* PMC INTA# */
return IRQ_IXDP2X01_SPCI_PMC_INTA;
case DEVPIN(0, 2): /* PMC INTB# */
return IRQ_IXDP2X01_SPCI_PMC_INTB;
case DEVPIN(0, 3): /* PMC INTC# */
return IRQ_IXDP2X01_SPCI_PMC_INTC;
case DEVPIN(0, 4): /* PMC INTD# */
return IRQ_IXDP2X01_SPCI_PMC_INTD;
}
}
break;
case 0x0010:
if (tmp_bus == dev->bus) {
/* Device is located directly after second MB bridge */
/* Secondary bus of second bridge */
switch (devpin) {
case DEVPIN(0, 1): /* DB#0 */
return IRQ_IXDP2X01_SPCI_DB_0;
case DEVPIN(1, 1): /* DB#1 */
return IRQ_IXDP2X01_SPCI_DB_1;
}
} else {
/* Device is located indirectly after second MB bridge */
/* Not supported now */
}
break;
}
return -1;
}
static int ixdp2x01_pci_setup(int nr, struct pci_sys_data *sys)
{
sys->mem_offset = 0xe0000000;
if (machine_is_ixdp2801() || machine_is_ixdp28x5())
sys->mem_offset -= ((*IXP2000_PCI_ADDR_EXT & 0xE000) << 16);
return ixp2000_pci_setup(nr, sys);
}
struct hw_pci ixdp2x01_pci __initdata = {
.nr_controllers = 1,
.setup = ixdp2x01_pci_setup,
.preinit = ixdp2x01_pci_preinit,
.scan = ixp2000_pci_scan_bus,
.map_irq = ixdp2x01_pci_map_irq,
};
int __init ixdp2x01_pci_init(void)
{
if (machine_is_ixdp2401() || machine_is_ixdp2801() ||\
machine_is_ixdp28x5())
pci_common_init(&ixdp2x01_pci);
return 0;
}
subsys_initcall(ixdp2x01_pci_init);
/*************************************************************************
* IXDP2x01 Machine Initialization
*************************************************************************/
static struct flash_platform_data ixdp2x01_flash_platform_data = {
.map_name = "cfi_probe",
.width = 1,
};
static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs)
{
ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN));
return (ofs & IXDP2X01_FLASH_WINDOW_MASK);
}
static struct ixp2000_flash_data ixdp2x01_flash_data = {
.platform_data = &ixdp2x01_flash_platform_data,
.bank_setup = ixdp2x01_flash_bank_setup
};
static struct resource ixdp2x01_flash_resource = {
.start = 0xc4000000,
.end = 0xc4000000 + 0x01ffffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device ixdp2x01_flash = {
.name = "IXP2000-Flash",
.id = 0,
.dev = {
.platform_data = &ixdp2x01_flash_data,
},
.num_resources = 1,
.resource = &ixdp2x01_flash_resource,
};
static struct ixp2000_i2c_pins ixdp2x01_i2c_gpio_pins = {
.sda_pin = IXDP2X01_GPIO_SDA,
.scl_pin = IXDP2X01_GPIO_SCL,
};
static struct platform_device ixdp2x01_i2c_controller = {
.name = "IXP2000-I2C",
.id = 0,
.dev = {
.platform_data = &ixdp2x01_i2c_gpio_pins,
},
.num_resources = 0
};
static struct platform_device *ixdp2x01_devices[] __initdata = {
&ixdp2x01_flash,
&ixdp2x01_i2c_controller
};
static void __init ixdp2x01_init_machine(void)
{
ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
(IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN));
ixdp2x01_flash_data.nr_banks =
((*IXDP2X01_CPLD_FLASH_REG & IXDP2X01_CPLD_FLASH_BANK_MASK) + 1);
platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices));
ixp2000_uart_init();
ixdp2x01_uart_init();
}
static void ixdp2401_restart(char mode, const char *cmd)
{
/*
* Reset flash banking register so that we are pointing at
* RedBoot bank.
*/
ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
((0 >> IXDP2X01_FLASH_WINDOW_BITS)
| IXDP2X01_CPLD_FLASH_INTERN));
ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0xffffffff);
ixp2000_restart(mode, cmd);
}
static void ixdp280x_restart(char mode, const char *cmd)
{
/*
* On IXDP2801 we need to write this magic sequence to the CPLD
* to cause a complete reset of the CPU and all external devices
* and move the flash bank register back to 0.
*/
unsigned long reset_reg = *IXDP2X01_CPLD_RESET_REG;
reset_reg = 0x55AA0000 | (reset_reg & 0x0000FFFF);
ixp2000_reg_write(IXDP2X01_CPLD_RESET_REG, reset_reg);
ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0x80000000);
ixp2000_restart(mode, cmd);
}
#ifdef CONFIG_ARCH_IXDP2401
MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.atag_offset = 0x100,
.map_io = ixdp2x01_map_io,
.init_irq = ixdp2x01_init_irq,
.timer = &ixdp2x01_timer,
.init_machine = ixdp2x01_init_machine,
.restart = ixdp2401_restart,
MACHINE_END
#endif
#ifdef CONFIG_ARCH_IXDP2801
MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.atag_offset = 0x100,
.map_io = ixdp2x01_map_io,
.init_irq = ixdp2x01_init_irq,
.timer = &ixdp2x01_timer,
.init_machine = ixdp2x01_init_machine,
.restart = ixdp280x_restart,
MACHINE_END
/*
* IXDP28x5 is basically an IXDP2801 with a different CPU but Intel
* changed the machine ID in the bootloader
*/
MACHINE_START(IXDP28X5, "Intel IXDP2805/2855 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.atag_offset = 0x100,
.map_io = ixdp2x01_map_io,
.init_irq = ixdp2x01_init_irq,
.timer = &ixdp2x01_timer,
.init_machine = ixdp2x01_init_machine,
.restart = ixdp280x_restart,
MACHINE_END
#endif
/*
* arch/arm/mach-ixp2000/pci.c
*
* PCI routines for IXDP2400/IXDP2800 boards
*
* Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
* Maintained by: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2002 Intel Corp.
* 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#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/delay.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <asm/mach/pci.h>
static volatile int pci_master_aborts = 0;
static int clear_master_aborts(void);
u32 *
ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
{
u32 *paddress;
if (PCI_SLOT(devfn) > 7)
return 0;
/* Must be dword aligned */
where &= ~3;
/*
* For top bus, generate type 0, else type 1
*/
if (!bus_nr) {
/* only bits[23:16] are used for IDSEL */
paddress = (u32 *) (IXP2000_PCI_CFG0_VIRT_BASE
| (1 << (PCI_SLOT(devfn) + 16))
| (PCI_FUNC(devfn) << 8) | where);
} else {
paddress = (u32 *) (IXP2000_PCI_CFG1_VIRT_BASE
| (bus_nr << 16)
| (PCI_SLOT(devfn) << 11)
| (PCI_FUNC(devfn) << 8) | where);
}
return paddress;
}
/*
* 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,
};
int ixp2000_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
u32 n;
u32 *addr;
n = where % 4;
addr = ixp2000_pci_config_addr(bus->number, devfn, where);
if (!addr)
return PCIBIOS_DEVICE_NOT_FOUND;
pci_master_aborts = 0;
*value = (*addr >> (8*n)) & bytemask[size];
if (pci_master_aborts) {
pci_master_aborts = 0;
*value = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND;
}
return PCIBIOS_SUCCESSFUL;
}
/*
* We don't do error checks by calling clear_master_aborts() b/c the
* assumption is that the caller did a read first to make sure a device
* exists.
*/
int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value)
{
u32 mask;
u32 *addr;
u32 temp;
mask = ~(bytemask[size] << ((where % 0x4) * 8));
addr = ixp2000_pci_config_addr(bus->number, devfn, where);
if (!addr)
return PCIBIOS_DEVICE_NOT_FOUND;
temp = (u32) (value) << ((where % 0x4) * 8);
*addr = (*addr & mask) | temp;
clear_master_aborts();
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops ixp2000_pci_ops = {
.read = ixp2000_pci_read_config,
.write = ixp2000_pci_write_config
};
struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops,
sysdata, &sysdata->resources);
}
int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
volatile u32 temp;
unsigned long flags;
pci_master_aborts = 1;
local_irq_save(flags);
temp = *(IXP2000_PCI_CONTROL);
if (temp & ((1 << 8) | (1 << 5))) {
ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
}
temp = *(IXP2000_PCI_CMDSTAT);
if (temp & (1 << 29)) {
while (temp & (1 << 29)) {
ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp);
temp = *(IXP2000_PCI_CMDSTAT);
}
}
local_irq_restore(flags);
/*
* 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;
}
int
clear_master_aborts(void)
{
volatile u32 temp;
unsigned long flags;
local_irq_save(flags);
temp = *(IXP2000_PCI_CONTROL);
if (temp & ((1 << 8) | (1 << 5))) {
ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
}
temp = *(IXP2000_PCI_CMDSTAT);
if (temp & (1 << 29)) {
while (temp & (1 << 29)) {
ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp);
temp = *(IXP2000_PCI_CMDSTAT);
}
}
local_irq_restore(flags);
return 0;
}
void __init
ixp2000_pci_preinit(void)
{
pci_set_flags(0);
pcibios_min_io = 0;
pcibios_min_mem = 0;
#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
/*
* Configure the PCI unit to properly byteswap I/O transactions,
* and verify that it worked.
*/
ixp2000_reg_write(IXP2000_PCI_CONTROL,
(*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE));
if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0)
panic("IXP2000: PCI I/O is broken on this ixp model, and "
"the needed workaround has not been configured in");
#endif
hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, 0,
"PCI config cycle to non-existent device");
}
/*
* IXP2000 systems often have large resource requirements, so we just
* use our own resource space.
*/
static struct resource ixp2000_pci_mem_space = {
.start = 0xe0000000,
.end = 0xffffffff,
.flags = IORESOURCE_MEM,
.name = "PCI Mem Space"
};
static struct resource ixp2000_pci_io_space = {
.start = 0x00010000,
.end = 0x0001ffff,
.flags = IORESOURCE_IO,
.name = "PCI I/O Space"
};
int ixp2000_pci_setup(int nr, struct pci_sys_data *sys)
{
if (nr >= 1)
return 0;
pci_add_resource_offset(&sys->resources,
&ixp2000_pci_io_space, sys->io_offset);
pci_add_resource_offset(&sys->resources,
&ixp2000_pci_mem_space, sys->mem_offset);
return 1;
}
if ARCH_IXP23XX
config ARCH_SUPPORTS_BIG_ENDIAN
bool
default y
menu "Intel IXP23xx Implementation Options"
comment "IXP23xx Platforms"
config MACH_ESPRESSO
bool "Support IP Fabrics Double Espresso platform"
help
config MACH_IXDP2351
bool "Support Intel IXDP2351 platform"
help
config MACH_ROADRUNNER
bool "Support ADI RoadRunner platform"
help
endmenu
endif
#
# Makefile for the linux kernel.
#
obj-y := core.o pci.o
obj-m :=
obj-n :=
obj- :=
obj-$(CONFIG_MACH_ESPRESSO) += espresso.o
obj-$(CONFIG_MACH_IXDP2351) += ixdp2351.o
obj-$(CONFIG_MACH_ROADRUNNER) += roadrunner.o
zreladdr-y += 0x00008000
params_phys-y := 0x00000100
/*
* arch/arm/mach-ixp23xx/core.c
*
* Core routines for IXP23xx chips
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2005 (c) MontaVista Software, Inc.
*
* Based on 2.4 code Copyright 2004 (c) Intel Corporation
*
* 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/init.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/bitops.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
#include <asm/system_misc.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
#include <asm/mach/arch.h>
/*************************************************************************
* Chip specific mappings shared by all IXP23xx systems
*************************************************************************/
static struct map_desc ixp23xx_io_desc[] __initdata = {
{ /* XSI-CPP CSRs */
.virtual = IXP23XX_XSI2CPP_CSR_VIRT,
.pfn = __phys_to_pfn(IXP23XX_XSI2CPP_CSR_PHYS),
.length = IXP23XX_XSI2CPP_CSR_SIZE,
.type = MT_DEVICE,
}, { /* Expansion Bus Config */
.virtual = IXP23XX_EXP_CFG_VIRT,
.pfn = __phys_to_pfn(IXP23XX_EXP_CFG_PHYS),
.length = IXP23XX_EXP_CFG_SIZE,
.type = MT_DEVICE,
}, { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACS,.... */
.virtual = IXP23XX_PERIPHERAL_VIRT,
.pfn = __phys_to_pfn(IXP23XX_PERIPHERAL_PHYS),
.length = IXP23XX_PERIPHERAL_SIZE,
.type = MT_DEVICE,
}, { /* CAP CSRs */
.virtual = IXP23XX_CAP_CSR_VIRT,
.pfn = __phys_to_pfn(IXP23XX_CAP_CSR_PHYS),
.length = IXP23XX_CAP_CSR_SIZE,
.type = MT_DEVICE,
}, { /* MSF CSRs */
.virtual = IXP23XX_MSF_CSR_VIRT,
.pfn = __phys_to_pfn(IXP23XX_MSF_CSR_PHYS),
.length = IXP23XX_MSF_CSR_SIZE,
.type = MT_DEVICE,
}, { /* PCI I/O Space */
.virtual = IXP23XX_PCI_IO_VIRT,
.pfn = __phys_to_pfn(IXP23XX_PCI_IO_PHYS),
.length = IXP23XX_PCI_IO_SIZE,
.type = MT_DEVICE,
}, { /* PCI Config Space */
.virtual = IXP23XX_PCI_CFG_VIRT,
.pfn = __phys_to_pfn(IXP23XX_PCI_CFG_PHYS),
.length = IXP23XX_PCI_CFG_SIZE,
.type = MT_DEVICE,
}, { /* PCI local CFG CSRs */
.virtual = IXP23XX_PCI_CREG_VIRT,
.pfn = __phys_to_pfn(IXP23XX_PCI_CREG_PHYS),
.length = IXP23XX_PCI_CREG_SIZE,
.type = MT_DEVICE,
}, { /* PCI MEM Space */
.virtual = IXP23XX_PCI_MEM_VIRT,
.pfn = __phys_to_pfn(IXP23XX_PCI_MEM_PHYS),
.length = IXP23XX_PCI_MEM_SIZE,
.type = MT_DEVICE,
}
};
void __init ixp23xx_map_io(void)
{
iotable_init(ixp23xx_io_desc, ARRAY_SIZE(ixp23xx_io_desc));
}
/***************************************************************************
* IXP23xx Interrupt Handling
***************************************************************************/
enum ixp23xx_irq_type {
IXP23XX_IRQ_LEVEL, IXP23XX_IRQ_EDGE
};
static void ixp23xx_config_irq(unsigned int, enum ixp23xx_irq_type);
static int ixp23xx_irq_set_type(struct irq_data *d, unsigned int type)
{
int line = d->irq - IRQ_IXP23XX_GPIO6 + 6;
u32 int_style;
enum ixp23xx_irq_type irq_type;
volatile u32 *int_reg;
/*
* Only GPIOs 6-15 are wired to interrupts on IXP23xx
*/
if (line < 6 || line > 15)
return -EINVAL;
switch (type) {
case IRQ_TYPE_EDGE_BOTH:
int_style = IXP23XX_GPIO_STYLE_TRANSITIONAL;
irq_type = IXP23XX_IRQ_EDGE;
break;
case IRQ_TYPE_EDGE_RISING:
int_style = IXP23XX_GPIO_STYLE_RISING_EDGE;
irq_type = IXP23XX_IRQ_EDGE;
break;
case IRQ_TYPE_EDGE_FALLING:
int_style = IXP23XX_GPIO_STYLE_FALLING_EDGE;
irq_type = IXP23XX_IRQ_EDGE;
break;
case IRQ_TYPE_LEVEL_HIGH:
int_style = IXP23XX_GPIO_STYLE_ACTIVE_HIGH;
irq_type = IXP23XX_IRQ_LEVEL;
break;
case IRQ_TYPE_LEVEL_LOW:
int_style = IXP23XX_GPIO_STYLE_ACTIVE_LOW;
irq_type = IXP23XX_IRQ_LEVEL;
break;
default:
return -EINVAL;
}
ixp23xx_config_irq(d->irq, irq_type);
if (line >= 8) { /* pins 8-15 */
line -= 8;
int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT2R;
} else { /* pins 0-7 */
int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT1R;
}
/*
* Clear pending interrupts
*/
*IXP23XX_GPIO_GPISR = (1 << line);
/* Clear the style for the appropriate pin */
*int_reg &= ~(IXP23XX_GPIO_STYLE_MASK <<
(line * IXP23XX_GPIO_STYLE_SIZE));
/* Set the new style */
*int_reg |= (int_style << (line * IXP23XX_GPIO_STYLE_SIZE));
return 0;
}
static void ixp23xx_irq_mask(struct irq_data *d)
{
volatile unsigned long *intr_reg;
unsigned int irq = d->irq;
if (irq >= 56)
irq += 8;
intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
*intr_reg &= ~(1 << (irq % 32));
}
static void ixp23xx_irq_ack(struct irq_data *d)
{
int line = d->irq - IRQ_IXP23XX_GPIO6 + 6;
if ((line < 6) || (line > 15))
return;
*IXP23XX_GPIO_GPISR = (1 << line);
}
/*
* Level triggered interrupts on GPIO lines can only be cleared when the
* interrupt condition disappears.
*/
static void ixp23xx_irq_level_unmask(struct irq_data *d)
{
volatile unsigned long *intr_reg;
unsigned int irq = d->irq;
ixp23xx_irq_ack(d);
if (irq >= 56)
irq += 8;
intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
*intr_reg |= (1 << (irq % 32));
}
static void ixp23xx_irq_edge_unmask(struct irq_data *d)
{
volatile unsigned long *intr_reg;
unsigned int irq = d->irq;
if (irq >= 56)
irq += 8;
intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
*intr_reg |= (1 << (irq % 32));
}
static struct irq_chip ixp23xx_irq_level_chip = {
.irq_ack = ixp23xx_irq_mask,
.irq_mask = ixp23xx_irq_mask,
.irq_unmask = ixp23xx_irq_level_unmask,
.irq_set_type = ixp23xx_irq_set_type
};
static struct irq_chip ixp23xx_irq_edge_chip = {
.irq_ack = ixp23xx_irq_ack,
.irq_mask = ixp23xx_irq_mask,
.irq_unmask = ixp23xx_irq_edge_unmask,
.irq_set_type = ixp23xx_irq_set_type
};
static void ixp23xx_pci_irq_mask(struct irq_data *d)
{
unsigned int irq = d->irq;
*IXP23XX_PCI_XSCALE_INT_ENABLE &= ~(1 << (IRQ_IXP23XX_INTA + 27 - irq));
}
static void ixp23xx_pci_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq;
*IXP23XX_PCI_XSCALE_INT_ENABLE |= (1 << (IRQ_IXP23XX_INTA + 27 - irq));
}
/*
* TODO: Should this just be done at ASM level?
*/
static void pci_handler(unsigned int irq, struct irq_desc *desc)
{
u32 pci_interrupt;
unsigned int irqno;
pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;
desc->irq_data.chip->irq_ack(&desc->irq_data);
/* See which PCI_INTA, or PCI_INTB interrupted */
if (pci_interrupt & (1 << 26)) {
irqno = IRQ_IXP23XX_INTB;
} else if (pci_interrupt & (1 << 27)) {
irqno = IRQ_IXP23XX_INTA;
} else {
BUG();
}
generic_handle_irq(irqno);
desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
static struct irq_chip ixp23xx_pci_irq_chip = {
.irq_ack = ixp23xx_pci_irq_mask,
.irq_mask = ixp23xx_pci_irq_mask,
.irq_unmask = ixp23xx_pci_irq_unmask
};
static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type)
{
switch (type) {
case IXP23XX_IRQ_LEVEL:
irq_set_chip_and_handler(irq, &ixp23xx_irq_level_chip,
handle_level_irq);
break;
case IXP23XX_IRQ_EDGE:
irq_set_chip_and_handler(irq, &ixp23xx_irq_edge_chip,
handle_edge_irq);
break;
}
set_irq_flags(irq, IRQF_VALID);
}
void __init ixp23xx_init_irq(void)
{
int irq;
/* Route everything to IRQ */
*IXP23XX_INTR_SEL1 = 0x0;
*IXP23XX_INTR_SEL2 = 0x0;
*IXP23XX_INTR_SEL3 = 0x0;
*IXP23XX_INTR_SEL4 = 0x0;
/* Mask all sources */
*IXP23XX_INTR_EN1 = 0x0;
*IXP23XX_INTR_EN2 = 0x0;
*IXP23XX_INTR_EN3 = 0x0;
*IXP23XX_INTR_EN4 = 0x0;
/*
* Configure all IRQs for level-sensitive operation
*/
for (irq = 0; irq <= NUM_IXP23XX_RAW_IRQS; irq++) {
ixp23xx_config_irq(irq, IXP23XX_IRQ_LEVEL);
}
for (irq = IRQ_IXP23XX_INTA; irq <= IRQ_IXP23XX_INTB; irq++) {
irq_set_chip_and_handler(irq, &ixp23xx_pci_irq_chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
irq_set_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler);
}
/*************************************************************************
* Timer-tick functions for IXP23xx
*************************************************************************/
#define CLOCK_TICKS_PER_USEC (CLOCK_TICK_RATE / USEC_PER_SEC)
static unsigned long next_jiffy_time;
static unsigned long
ixp23xx_gettimeoffset(void)
{
unsigned long elapsed;
elapsed = *IXP23XX_TIMER_CONT - (next_jiffy_time - LATCH);
return elapsed / CLOCK_TICKS_PER_USEC;
}
static irqreturn_t
ixp23xx_timer_interrupt(int irq, void *dev_id)
{
/* Clear Pending Interrupt by writing '1' to it */
*IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
while ((signed long)(*IXP23XX_TIMER_CONT - next_jiffy_time) >= LATCH) {
timer_tick();
next_jiffy_time += LATCH;
}
return IRQ_HANDLED;
}
static struct irqaction ixp23xx_timer_irq = {
.name = "IXP23xx Timer Tick",
.handler = ixp23xx_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
void __init ixp23xx_init_timer(void)
{
/* Clear Pending Interrupt by writing '1' to it */
*IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
/* Setup the Timer counter value */
*IXP23XX_TIMER1_RELOAD =
(LATCH & ~IXP23XX_TIMER_RELOAD_MASK) | IXP23XX_TIMER_ENABLE;
*IXP23XX_TIMER_CONT = 0;
next_jiffy_time = LATCH;
/* Connect the interrupt handler and enable the interrupt */
setup_irq(IRQ_IXP23XX_TIMER1, &ixp23xx_timer_irq);
}
struct sys_timer ixp23xx_timer = {
.init = ixp23xx_init_timer,
.offset = ixp23xx_gettimeoffset,
};
/*************************************************************************
* IXP23xx Platform Initialization
*************************************************************************/
static struct resource ixp23xx_uart_resources[] = {
{
.start = IXP23XX_UART1_PHYS,
.end = IXP23XX_UART1_PHYS + 0x0fff,
.flags = IORESOURCE_MEM
}, {
.start = IXP23XX_UART2_PHYS,
.end = IXP23XX_UART2_PHYS + 0x0fff,
.flags = IORESOURCE_MEM
}
};
static struct plat_serial8250_port ixp23xx_uart_data[] = {
{
.mapbase = IXP23XX_UART1_PHYS,
.membase = (char *)(IXP23XX_UART1_VIRT + 3),
.irq = IRQ_IXP23XX_UART1,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP23XX_UART_XTAL,
}, {
.mapbase = IXP23XX_UART2_PHYS,
.membase = (char *)(IXP23XX_UART2_VIRT + 3),
.irq = IRQ_IXP23XX_UART2,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP23XX_UART_XTAL,
},
{ },
};
static struct platform_device ixp23xx_uart = {
.name = "serial8250",
.id = 0,
.dev.platform_data = ixp23xx_uart_data,
.num_resources = 2,
.resource = ixp23xx_uart_resources,
};
static struct platform_device *ixp23xx_devices[] __initdata = {
&ixp23xx_uart,
};
void __init ixp23xx_sys_init(void)
{
/* by default, the idle code is disabled */
disable_hlt();
*IXP23XX_EXP_UNIT_FUSE |= 0xf;
platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices));
}
void ixp23xx_restart(char mode, const char *cmd)
{
/* Use on-chip reset capability */
*IXP23XX_RESET0 |= IXP23XX_RST_ALL;
}
/*
* arch/arm/mach-ixp23xx/espresso.c
*
* Double Espresso-specific routines
*
* Author: Lennert Buytenhek <buytenh@wantstofly.org>
*
* 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/init.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/bitops.h>
#include <linux/ioport.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/mtd/physmap.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/tlbflush.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
static int __init espresso_pci_init(void)
{
if (machine_is_espresso())
ixp23xx_pci_slave_init();
return 0;
};
subsys_initcall(espresso_pci_init);
static struct physmap_flash_data espresso_flash_data = {
.width = 2,
};
static struct resource espresso_flash_resource = {
.start = 0x90000000,
.end = 0x91ffffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device espresso_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &espresso_flash_data,
},
.num_resources = 1,
.resource = &espresso_flash_resource,
};
static void __init espresso_init(void)
{
platform_device_register(&espresso_flash);
/*
* Mark flash as writeable.
*/
IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
ixp23xx_sys_init();
}
MACHINE_START(ESPRESSO, "IP Fabrics Double Espresso")
/* Maintainer: Lennert Buytenhek */
.map_io = ixp23xx_map_io,
.init_irq = ixp23xx_init_irq,
.timer = &ixp23xx_timer,
.atag_offset = 0x100,
.init_machine = espresso_init,
.restart = ixp23xx_restart,
MACHINE_END
/*
* arch/arm/mach-ixp23xx/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.
*/
#include <mach/ixp23xx.h>
.macro addruart, rp, rv, tmp
ldr \rp, =IXP23XX_PERIPHERAL_PHYS @ physical
ldr \rv, =IXP23XX_PERIPHERAL_VIRT @ virtual
#ifdef __ARMEB__
orr \rp, \rp, #0x00000003
orr \rv, \rv, #0x00000003
#endif
.endm
#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>
/*
* arch/arm/mach-ixp23xx/include/mach/entry-macro.S
*/
.macro get_irqnr_preamble, base, tmp
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqnr, =(IXP23XX_INTC_VIRT + IXP23XX_INTR_IRQ_ENC_ST_OFFSET)
ldr \irqnr, [\irqnr] @ get interrupt number
cmp \irqnr, #0x0 @ spurious interrupt ?
movne \irqnr, \irqnr, lsr #2 @ skip unwanted low order bits
subne \irqnr, \irqnr, #1 @ convert to 0 based
#if 0
cmp \irqnr, #IRQ_IXP23XX_PCI_INT_RPH
bne 1001f
mov \irqnr, #IRQ_IXP23XX_INTA
ldr \irqnr, =0xf5000030
mov \tmp, #(1<<26)
tst \irqnr, \tmp
movne \irqnr, #IRQ_IXP23XX_INTB
mov \tmp, #(1<<27)
tst \irqnr, \tmp
movne \irqnr, #IRQ_IXP23XX_INTA
1001:
#endif
.endm
/*
* arch/arm/mach-ixp23xx/include/mach/hardware.h
*
* Copyright (C) 2002-2004 Intel Corporation.
* Copyricht (C) 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.
*
* Hardware definitions for IXP23XX based systems
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
/* PCI IO info */
#include "ixp23xx.h"
/*
* Platform helper functions
*/
#include "platform.h"
/*
* Platform-specific headers
*/
#include "ixdp2351.h"
#endif
/*
* arch/arm/mach-ixp23xx/include/mach/io.h
*
* Original Author: Naeem M Afzal <naeem.m.afzal@intel.com>
* Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright (C) 2003-2005 Intel Corp.
* Copyright (C) 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_ARCH_IO_H
#define __ASM_ARCH_IO_H
#define IO_SPACE_LIMIT 0xffffffff
#define __io(p) ((void __iomem*)((p) + IXP23XX_PCI_IO_VIRT))
#endif
/*
* arch/arm/mach-ixp23xx/include/mach/irqs.h
*
* IRQ definitions for IXP23XX based systems
*
* Author: Naeem Afzal <naeem.m.afzal@intel.com>
*
* Copyright (C) 2003-2004 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H
#define NR_IXP23XX_IRQS IRQ_IXP23XX_INTB+1
#define IRQ_IXP23XX_EXTIRQS NR_IXP23XX_IRQS
#define IRQ_IXP23XX_DBG0 0 /* Debug/Execution/MBox */
#define IRQ_IXP23XX_DBG1 1 /* Debug/Execution/MBox */
#define IRQ_IXP23XX_NPE_TRG 2 /* npe_trigger */
#define IRQ_IXP23XX_TIMER1 3 /* Timer[0] */
#define IRQ_IXP23XX_TIMER2 4 /* Timer[1] */
#define IRQ_IXP23XX_TIMESTAMP 5 /* Timer[2], Time-stamp */
#define IRQ_IXP23XX_WDOG 6 /* Time[3], Watchdog Timer */
#define IRQ_IXP23XX_PCI_DBELL 7 /* PCI Doorbell */
#define IRQ_IXP23XX_PCI_DMA1 8 /* PCI DMA Channel 1 */
#define IRQ_IXP23XX_PCI_DMA2 9 /* PCI DMA Channel 2 */
#define IRQ_IXP23XX_PCI_DMA3 10 /* PCI DMA Channel 3 */
#define IRQ_IXP23XX_PCI_INT_RPH 11 /* pcxg_pci_int_rph */
#define IRQ_IXP23XX_CPP_PMU 12 /* xpxg_pm_int_rpl */
#define IRQ_IXP23XX_SWINT0 13 /* S/W Interrupt0 */
#define IRQ_IXP23XX_SWINT1 14 /* S/W Interrupt1 */
#define IRQ_IXP23XX_UART2 15 /* UART1 Interrupt */
#define IRQ_IXP23XX_UART1 16 /* UART0 Interrupt */
#define IRQ_IXP23XX_XSI_PMU_ROLLOVER 17 /* AHB Performance M. Unit counter rollover */
#define IRQ_IXP23XX_XSI_AHB_PM0 18 /* intr_pm_o */
#define IRQ_IXP23XX_XSI_AHB_ECE0 19 /* intr_ece_o */
#define IRQ_IXP23XX_XSI_AHB_GASKET 20 /* gas_intr_o */
#define IRQ_IXP23XX_XSI_CPP 21 /* xsi2cpp_int */
#define IRQ_IXP23XX_CPP_XSI 22 /* cpp2xsi_int */
#define IRQ_IXP23XX_ME_ATTN0 23 /* ME_ATTN */
#define IRQ_IXP23XX_ME_ATTN1 24 /* ME_ATTN */
#define IRQ_IXP23XX_ME_ATTN2 25 /* ME_ATTN */
#define IRQ_IXP23XX_ME_ATTN3 26 /* ME_ATTN */
#define IRQ_IXP23XX_PCI_ERR_RPH 27 /* PCXG_PCI_ERR_RPH */
#define IRQ_IXP23XX_D0XG_ECC_CORR 28 /* D0XG_DRAM_ECC_CORR */
#define IRQ_IXP23XX_D0XG_ECC_UNCORR 29 /* D0XG_DRAM_ECC_UNCORR */
#define IRQ_IXP23XX_SRAM_ERR1 30 /* SRAM1_ERR */
#define IRQ_IXP23XX_SRAM_ERR0 31 /* SRAM0_ERR */
#define IRQ_IXP23XX_MEDIA_ERR 32 /* MEDIA_ERR */
#define IRQ_IXP23XX_STH_DRAM_ECC_MAJ 33 /* STH_DRAM0_ECC_MAJ */
#define IRQ_IXP23XX_GPIO6 34 /* GPIO0 interrupts */
#define IRQ_IXP23XX_GPIO7 35 /* GPIO1 interrupts */
#define IRQ_IXP23XX_GPIO8 36 /* GPIO2 interrupts */
#define IRQ_IXP23XX_GPIO9 37 /* GPIO3 interrupts */
#define IRQ_IXP23XX_GPIO10 38 /* GPIO4 interrupts */
#define IRQ_IXP23XX_GPIO11 39 /* GPIO5 interrupts */
#define IRQ_IXP23XX_GPIO12 40 /* GPIO6 interrupts */
#define IRQ_IXP23XX_GPIO13 41 /* GPIO7 interrupts */
#define IRQ_IXP23XX_GPIO14 42 /* GPIO8 interrupts */
#define IRQ_IXP23XX_GPIO15 43 /* GPIO9 interrupts */
#define IRQ_IXP23XX_SHAC_RING0 44 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING1 45 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING2 46 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING3 47 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING4 48 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING5 49 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING6 50 /* SHAC RING Full */
#define IRQ_IXP23XX_SHAC_RING7 51 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING8 52 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING9 53 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING10 54 /* SHAC Ring Full */
#define IRQ_IXP23XX_SHAC_RING11 55 /* SHAC Ring Full */
#define IRQ_IXP23XX_ME_THREAD_A0_ME0 56 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A1_ME0 57 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A2_ME0 58 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A3_ME0 59 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A4_ME0 60 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A5_ME0 61 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A6_ME0 62 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A7_ME0 63 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A8_ME1 64 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A9_ME1 65 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A10_ME1 66 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A11_ME1 67 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A12_ME1 68 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A13_ME1 69 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A14_ME1 70 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A15_ME1 71 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A16_ME2 72 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A17_ME2 73 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A18_ME2 74 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A19_ME2 75 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A20_ME2 76 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A21_ME2 77 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A22_ME2 78 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A23_ME2 79 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A24_ME3 80 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A25_ME3 81 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A26_ME3 82 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A27_ME3 83 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A28_ME3 84 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A29_ME3 85 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A30_ME3 86 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_A31_ME3 87 /* ME_THREAD_A */
#define IRQ_IXP23XX_ME_THREAD_B0_ME0 88 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B1_ME0 89 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B2_ME0 90 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B3_ME0 91 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B4_ME0 92 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B5_ME0 93 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B6_ME0 94 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B7_ME0 95 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B8_ME1 96 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B9_ME1 97 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B10_ME1 98 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B11_ME1 99 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B12_ME1 100 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B13_ME1 101 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B14_ME1 102 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B15_ME1 103 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B16_ME2 104 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B17_ME2 105 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B18_ME2 106 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B19_ME2 107 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B20_ME2 108 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B21_ME2 109 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B22_ME2 110 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B23_ME2 111 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B24_ME3 112 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B25_ME3 113 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B26_ME3 114 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B27_ME3 115 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B28_ME3 116 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B29_ME3 117 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B30_ME3 118 /* ME_THREAD_B */
#define IRQ_IXP23XX_ME_THREAD_B31_ME3 119 /* ME_THREAD_B */
#define NUM_IXP23XX_RAW_IRQS 120
#define IRQ_IXP23XX_INTA 120 /* Indirect pcxg_pci_int_rph */
#define IRQ_IXP23XX_INTB 121 /* Indirect pcxg_pci_int_rph */
#define NR_IXP23XX_IRQ (IRQ_IXP23XX_INTB + 1)
/*
* We default to 32 per-board IRQs. Increase this number if you need
* more, but keep it realistic.
*/
#define NR_IXP23XX_MACH_IRQS 32
#define NR_IRQS (NR_IXP23XX_IRQS + NR_IXP23XX_MACH_IRQS)
#define IXP23XX_MACH_IRQ(irq) (NR_IXP23XX_IRQ + (irq))
/*
* IXDP2351-specific interrupts
*/
/*
* External PCI interrupts signaled through INTB
*
*/
#define IXDP2351_INTB_IRQ_BASE 0
#define IRQ_IXDP2351_INTA_82546 IXP23XX_MACH_IRQ(0)
#define IRQ_IXDP2351_INTB_82546 IXP23XX_MACH_IRQ(1)
#define IRQ_IXDP2351_SPCI_DB_0 IXP23XX_MACH_IRQ(2)
#define IRQ_IXDP2351_SPCI_DB_1 IXP23XX_MACH_IRQ(3)
#define IRQ_IXDP2351_SPCI_PMC_INTA IXP23XX_MACH_IRQ(4)
#define IRQ_IXDP2351_SPCI_PMC_INTB IXP23XX_MACH_IRQ(5)
#define IRQ_IXDP2351_SPCI_PMC_INTC IXP23XX_MACH_IRQ(6)
#define IRQ_IXDP2351_SPCI_PMC_INTD IXP23XX_MACH_IRQ(7)
#define IRQ_IXDP2351_SPCI_FIC IXP23XX_MACH_IRQ(8)
#define IXDP2351_INTB_IRQ_BIT(irq) (irq - IXP23XX_MACH_IRQ(0))
#define IXDP2351_INTB_IRQ_MASK(irq) (1 << IXDP2351_INTB_IRQ_BIT(irq))
#define IXDP2351_INTB_IRQ_VALID 0x01FF
#define IXDP2351_INTB_IRQ_NUM 16
/*
* Other external interrupts signaled through INTA
*/
#define IXDP2351_INTA_IRQ_BASE 16
#define IRQ_IXDP2351_IPMI_FROM IXP23XX_MACH_IRQ(16)
#define IRQ_IXDP2351_125US IXP23XX_MACH_IRQ(17)
#define IRQ_IXDP2351_DB_0_ADD IXP23XX_MACH_IRQ(18)
#define IRQ_IXDP2351_DB_1_ADD IXP23XX_MACH_IRQ(19)
#define IRQ_IXDP2351_DEBUG1 IXP23XX_MACH_IRQ(20)
#define IRQ_IXDP2351_ADD_UART IXP23XX_MACH_IRQ(21)
#define IRQ_IXDP2351_FIC_ADD IXP23XX_MACH_IRQ(24)
#define IRQ_IXDP2351_CS8900 IXP23XX_MACH_IRQ(25)
#define IRQ_IXDP2351_BBSRAM IXP23XX_MACH_IRQ(26)
#define IRQ_IXDP2351_CONFIG_MEDIA IXP23XX_MACH_IRQ(27)
#define IRQ_IXDP2351_CLOCK_REF IXP23XX_MACH_IRQ(28)
#define IRQ_IXDP2351_A10_NP IXP23XX_MACH_IRQ(29)
#define IRQ_IXDP2351_A11_NP IXP23XX_MACH_IRQ(30)
#define IRQ_IXDP2351_DEBUG_NP IXP23XX_MACH_IRQ(31)
#define IXDP2351_INTA_IRQ_BIT(irq) (irq - IXP23XX_MACH_IRQ(16))
#define IXDP2351_INTA_IRQ_MASK(irq) (1 << IXDP2351_INTA_IRQ_BIT(irq))
#define IXDP2351_INTA_IRQ_VALID 0xFF3F
#define IXDP2351_INTA_IRQ_NUM 16
/*
* ADI RoadRunner IRQs
*/
#define IRQ_ROADRUNNER_PCI_INTA IRQ_IXP23XX_INTA
#define IRQ_ROADRUNNER_PCI_INTB IRQ_IXP23XX_INTB
#define IRQ_ROADRUNNER_PCI_INTC IRQ_IXP23XX_GPIO11
#define IRQ_ROADRUNNER_PCI_INTD IRQ_IXP23XX_GPIO12
/*
* Put new board definitions here
*/
#endif
/*
* arch/arm/mach-ixp23xx/include/mach/ixdp2351.h
*
* Register and other defines for IXDP2351
*
* Copyright (c) 2002-2004 Intel Corp.
* Copytight (c) 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef __ASM_ARCH_IXDP2351_H
#define __ASM_ARCH_IXDP2351_H
/*
* NP module memory map
*/
#define IXDP2351_NP_PHYS_BASE (IXP23XX_EXP_BUS_CS4_BASE)
#define IXDP2351_NP_PHYS_SIZE 0x00100000
#define IXDP2351_NP_VIRT_BASE 0xeff00000
#define IXDP2351_VIRT_CS8900_BASE (IXDP2351_NP_VIRT_BASE)
#define IXDP2351_VIRT_CS8900_END (IXDP2351_VIRT_CS8900_BASE + 16)
#define IXDP2351_VIRT_NP_CPLD_BASE (IXP23XX_EXP_BUS_CS4_BASE_VIRT + 0x00010000)
#define IXDP2351_NP_CPLD_REG(reg) ((volatile u16 *)(IXDP2351_VIRT_NP_CPLD_BASE + reg))
#define IXDP2351_NP_CPLD_RESET1_REG IXDP2351_NP_CPLD_REG(0x00)
#define IXDP2351_NP_CPLD_LED_REG IXDP2351_NP_CPLD_REG(0x02)
#define IXDP2351_NP_CPLD_VERSION_REG IXDP2351_NP_CPLD_REG(0x04)
/*
* Base board module memory map
*/
#define IXDP2351_BB_BASE_PHYS (IXP23XX_EXP_BUS_CS5_BASE)
#define IXDP2351_BB_SIZE 0x01000000
#define IXDP2351_BB_BASE_VIRT (0xee000000)
#define IXDP2351_BB_AREA_BASE(offset) (IXDP2351_BB_BASE_VIRT + offset)
#define IXDP2351_VIRT_NVRAM_BASE IXDP2351_BB_AREA_BASE(0x0)
#define IXDP2351_NVRAM_SIZE (0x20000)
#define IXDP2351_VIRT_MB_IXF1104_BASE IXDP2351_BB_AREA_BASE(0x00020000)
#define IXDP2351_VIRT_ADD_UART_BASE IXDP2351_BB_AREA_BASE(0x000240C0)
#define IXDP2351_VIRT_FIC_BASE IXDP2351_BB_AREA_BASE(0x00200000)
#define IXDP2351_VIRT_DB0_BASE IXDP2351_BB_AREA_BASE(0x00400000)
#define IXDP2351_VIRT_DB1_BASE IXDP2351_BB_AREA_BASE(0x00600000)
#define IXDP2351_VIRT_CPLD_BASE IXDP2351_BB_AREA_BASE(0x00024000)
/*
* On board CPLD registers
*/
#define IXDP2351_CPLD_BB_REG(reg) ((volatile u16 *)(IXDP2351_VIRT_CPLD_BASE + reg))
#define IXDP2351_CPLD_RESET0_REG IXDP2351_CPLD_BB_REG(0x00)
#define IXDP2351_CPLD_RESET1_REG IXDP2351_CPLD_BB_REG(0x04)
#define IXDP2351_CPLD_RESET1_MAGIC 0x55AA
#define IXDP2351_CPLD_RESET1_ENABLE 0x8000
#define IXDP2351_CPLD_FPGA_CONFIG_REG IXDP2351_CPLD_BB_REG(0x08)
#define IXDP2351_CPLD_INTB_MASK_SET_REG IXDP2351_CPLD_BB_REG(0x10)
#define IXDP2351_CPLD_INTA_MASK_SET_REG IXDP2351_CPLD_BB_REG(0x14)
#define IXDP2351_CPLD_INTB_STAT_REG IXDP2351_CPLD_BB_REG(0x18)
#define IXDP2351_CPLD_INTA_STAT_REG IXDP2351_CPLD_BB_REG(0x1C)
#define IXDP2351_CPLD_INTB_RAW_REG IXDP2351_CPLD_BB_REG(0x20) /* read */
#define IXDP2351_CPLD_INTA_RAW_REG IXDP2351_CPLD_BB_REG(0x24) /* read */
#define IXDP2351_CPLD_INTB_MASK_CLR_REG IXDP2351_CPLD_INTB_RAW_REG /* write */
#define IXDP2351_CPLD_INTA_MASK_CLR_REG IXDP2351_CPLD_INTA_RAW_REG /* write */
#define IXDP2351_CPLD_INTB_SIM_REG IXDP2351_CPLD_BB_REG(0x28)
#define IXDP2351_CPLD_INTA_SIM_REG IXDP2351_CPLD_BB_REG(0x2C)
/* Interrupt bits are defined in irqs.h */
#define IXDP2351_CPLD_BB_GBE0_REG IXDP2351_CPLD_BB_REG(0x30)
#define IXDP2351_CPLD_BB_GBE1_REG IXDP2351_CPLD_BB_REG(0x34)
/* #define IXDP2351_CPLD_BB_MISC_REG IXDP2351_CPLD_REG(0x1C) */
/* #define IXDP2351_CPLD_BB_MISC_REV_MASK 0xFF */
/* #define IXDP2351_CPLD_BB_GDXCS0_REG IXDP2351_CPLD_REG(0x24) */
/* #define IXDP2351_CPLD_BB_GDXCS1_REG IXDP2351_CPLD_REG(0x28) */
/* #define IXDP2351_CPLD_BB_CLOCK_REG IXDP2351_CPLD_REG(0x04) */
#endif
/*
* arch/arm/mach-ixp23xx/include/mach/ixp23xx.h
*
* Register definitions for IXP23XX
*
* Copyright (C) 2003-2005 Intel Corporation.
* Copyright (C) 2005 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.
*/
#ifndef __ASM_ARCH_IXP23XX_H
#define __ASM_ARCH_IXP23XX_H
/*
* IXP2300 linux memory map:
*
* virt phys size
* fffd0000 a0000000 64K XSI2CPP_CSR
* fffc0000 c4000000 4K EXP_CFG
* fff00000 c8000000 64K PERIPHERAL
* fe000000 1c0000000 16M CAP_CSR
* fd000000 1c8000000 16M MSF_CSR
* fb000000 16M ---
* fa000000 1d8000000 32M PCI_IO
* f8000000 1da000000 32M PCI_CFG
* f6000000 1de000000 32M PCI_CREG
* f4000000 32M ---
* f0000000 1e0000000 64M PCI_MEM
* e[c-f]000000 per-platform mappings
*/
/****************************************************************************
* Static mappings.
****************************************************************************/
#define IXP23XX_XSI2CPP_CSR_PHYS 0xa0000000
#define IXP23XX_XSI2CPP_CSR_VIRT 0xfffd0000
#define IXP23XX_XSI2CPP_CSR_SIZE 0x00010000
#define IXP23XX_EXP_CFG_PHYS 0xc4000000
#define IXP23XX_EXP_CFG_VIRT 0xfffc0000
#define IXP23XX_EXP_CFG_SIZE 0x00001000
#define IXP23XX_PERIPHERAL_PHYS 0xc8000000
#define IXP23XX_PERIPHERAL_VIRT 0xfff00000
#define IXP23XX_PERIPHERAL_SIZE 0x00010000
#define IXP23XX_CAP_CSR_PHYS 0x1c0000000ULL
#define IXP23XX_CAP_CSR_VIRT 0xfe000000
#define IXP23XX_CAP_CSR_SIZE 0x01000000
#define IXP23XX_MSF_CSR_PHYS 0x1c8000000ULL
#define IXP23XX_MSF_CSR_VIRT 0xfd000000
#define IXP23XX_MSF_CSR_SIZE 0x01000000
#define IXP23XX_PCI_IO_PHYS 0x1d8000000ULL
#define IXP23XX_PCI_IO_VIRT 0xfa000000
#define IXP23XX_PCI_IO_SIZE 0x02000000
#define IXP23XX_PCI_CFG_PHYS 0x1da000000ULL
#define IXP23XX_PCI_CFG_VIRT 0xf8000000
#define IXP23XX_PCI_CFG_SIZE 0x02000000
#define IXP23XX_PCI_CFG0_VIRT IXP23XX_PCI_CFG_VIRT
#define IXP23XX_PCI_CFG1_VIRT (IXP23XX_PCI_CFG_VIRT + 0x01000000)
#define IXP23XX_PCI_CREG_PHYS 0x1de000000ULL
#define IXP23XX_PCI_CREG_VIRT 0xf6000000
#define IXP23XX_PCI_CREG_SIZE 0x02000000
#define IXP23XX_PCI_CSR_VIRT (IXP23XX_PCI_CREG_VIRT + 0x01000000)
#define IXP23XX_PCI_MEM_START 0xe0000000
#define IXP23XX_PCI_MEM_PHYS 0x1e0000000ULL
#define IXP23XX_PCI_MEM_VIRT 0xf0000000
#define IXP23XX_PCI_MEM_SIZE 0x04000000
/****************************************************************************
* XSI2CPP CSRs.
****************************************************************************/
#define IXP23XX_XSI2CPP_REG(x) ((volatile unsigned long *)(IXP23XX_XSI2CPP_CSR_VIRT + (x)))
#define IXP23XX_CPP2XSI_CURR_XFER_REG3 IXP23XX_XSI2CPP_REG(0xf8)
#define IXP23XX_CPP2XSI_ADDR_31 (1 << 19)
#define IXP23XX_CPP2XSI_PSH_OFF (1 << 20)
#define IXP23XX_CPP2XSI_COH_OFF (1 << 21)
/****************************************************************************
* Expansion Bus Config.
****************************************************************************/
#define IXP23XX_EXP_CFG_REG(x) ((volatile unsigned long *)(IXP23XX_EXP_CFG_VIRT + (x)))
#define IXP23XX_EXP_CS0 IXP23XX_EXP_CFG_REG(0x00)
#define IXP23XX_EXP_CS1 IXP23XX_EXP_CFG_REG(0x04)
#define IXP23XX_EXP_CS2 IXP23XX_EXP_CFG_REG(0x08)
#define IXP23XX_EXP_CS3 IXP23XX_EXP_CFG_REG(0x0c)
#define IXP23XX_EXP_CS4 IXP23XX_EXP_CFG_REG(0x10)
#define IXP23XX_EXP_CS5 IXP23XX_EXP_CFG_REG(0x14)
#define IXP23XX_EXP_CS6 IXP23XX_EXP_CFG_REG(0x18)
#define IXP23XX_EXP_CS7 IXP23XX_EXP_CFG_REG(0x1c)
#define IXP23XX_FLASH_WRITABLE (0x2)
#define IXP23XX_FLASH_BUS8 (0x1)
#define IXP23XX_EXP_CFG0 IXP23XX_EXP_CFG_REG(0x20)
#define IXP23XX_EXP_CFG1 IXP23XX_EXP_CFG_REG(0x24)
#define IXP23XX_EXP_CFG0_MEM_MAP (1 << 31)
#define IXP23XX_EXP_CFG0_XSCALE_SPEED_SEL (3 << 22)
#define IXP23XX_EXP_CFG0_XSCALE_SPEED_EN (1 << 21)
#define IXP23XX_EXP_CFG0_CPP_SPEED_SEL (3 << 19)
#define IXP23XX_EXP_CFG0_CPP_SPEED_EN (1 << 18)
#define IXP23XX_EXP_CFG0_PCI_SWIN (3 << 16)
#define IXP23XX_EXP_CFG0_PCI_DWIN (3 << 14)
#define IXP23XX_EXP_CFG0_PCI33_MODE (1 << 13)
#define IXP23XX_EXP_CFG0_QDR_SPEED_SEL (1 << 12)
#define IXP23XX_EXP_CFG0_CPP_DIV_SEL (1 << 5)
#define IXP23XX_EXP_CFG0_XSI_NOT_PRES (1 << 4)
#define IXP23XX_EXP_CFG0_PROM_BOOT (1 << 3)
#define IXP23XX_EXP_CFG0_PCI_ARB (1 << 2)
#define IXP23XX_EXP_CFG0_PCI_HOST (1 << 1)
#define IXP23XX_EXP_CFG0_FLASH_WIDTH (1 << 0)
#define IXP23XX_EXP_UNIT_FUSE IXP23XX_EXP_CFG_REG(0x28)
#define IXP23XX_EXP_MSF_MUX IXP23XX_EXP_CFG_REG(0x30)
#define IXP23XX_EXP_CFG_FUSE IXP23XX_EXP_CFG_REG(0x34)
#define IXP23XX_EXP_BUS_PHYS 0x90000000
#define IXP23XX_EXP_BUS_WINDOW_SIZE 0x01000000
#define IXP23XX_EXP_BUS_CS0_BASE (IXP23XX_EXP_BUS_PHYS + 0x00000000)
#define IXP23XX_EXP_BUS_CS1_BASE (IXP23XX_EXP_BUS_PHYS + 0x01000000)
#define IXP23XX_EXP_BUS_CS2_BASE (IXP23XX_EXP_BUS_PHYS + 0x02000000)
#define IXP23XX_EXP_BUS_CS3_BASE (IXP23XX_EXP_BUS_PHYS + 0x03000000)
#define IXP23XX_EXP_BUS_CS4_BASE (IXP23XX_EXP_BUS_PHYS + 0x04000000)
#define IXP23XX_EXP_BUS_CS5_BASE (IXP23XX_EXP_BUS_PHYS + 0x05000000)
#define IXP23XX_EXP_BUS_CS6_BASE (IXP23XX_EXP_BUS_PHYS + 0x06000000)
#define IXP23XX_EXP_BUS_CS7_BASE (IXP23XX_EXP_BUS_PHYS + 0x07000000)
/****************************************************************************
* Peripherals.
****************************************************************************/
#define IXP23XX_UART1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x0000)
#define IXP23XX_UART2_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x1000)
#define IXP23XX_PMU_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x2000)
#define IXP23XX_INTC_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x3000)
#define IXP23XX_GPIO_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x4000)
#define IXP23XX_TIMER_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x5000)
#define IXP23XX_NPE0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x6000)
#define IXP23XX_DSR_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x7000)
#define IXP23XX_NPE1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x8000)
#define IXP23XX_ETH0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x9000)
#define IXP23XX_ETH1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xA000)
#define IXP23XX_GIG0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xB000)
#define IXP23XX_GIG1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xC000)
#define IXP23XX_DDRS_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xD000)
#define IXP23XX_UART1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x0000)
#define IXP23XX_UART2_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x1000)
#define IXP23XX_PMU_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x2000)
#define IXP23XX_INTC_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x3000)
#define IXP23XX_GPIO_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x4000)
#define IXP23XX_TIMER_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x5000)
#define IXP23XX_NPE0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x6000)
#define IXP23XX_DSR_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x7000)
#define IXP23XX_NPE1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x8000)
#define IXP23XX_ETH0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x9000)
#define IXP23XX_ETH1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xA000)
#define IXP23XX_GIG0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xB000)
#define IXP23XX_GIG1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xC000)
#define IXP23XX_DDRS_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xD000)
/****************************************************************************
* Interrupt controller.
****************************************************************************/
#define IXP23XX_INTC_REG(x) ((volatile unsigned long *)(IXP23XX_INTC_VIRT + (x)))
#define IXP23XX_INTR_ST1 IXP23XX_INTC_REG(0x00)
#define IXP23XX_INTR_ST2 IXP23XX_INTC_REG(0x04)
#define IXP23XX_INTR_ST3 IXP23XX_INTC_REG(0x08)
#define IXP23XX_INTR_ST4 IXP23XX_INTC_REG(0x0c)
#define IXP23XX_INTR_EN1 IXP23XX_INTC_REG(0x10)
#define IXP23XX_INTR_EN2 IXP23XX_INTC_REG(0x14)
#define IXP23XX_INTR_EN3 IXP23XX_INTC_REG(0x18)
#define IXP23XX_INTR_EN4 IXP23XX_INTC_REG(0x1c)
#define IXP23XX_INTR_SEL1 IXP23XX_INTC_REG(0x20)
#define IXP23XX_INTR_SEL2 IXP23XX_INTC_REG(0x24)
#define IXP23XX_INTR_SEL3 IXP23XX_INTC_REG(0x28)
#define IXP23XX_INTR_SEL4 IXP23XX_INTC_REG(0x2c)
#define IXP23XX_INTR_IRQ_ST1 IXP23XX_INTC_REG(0x30)
#define IXP23XX_INTR_IRQ_ST2 IXP23XX_INTC_REG(0x34)
#define IXP23XX_INTR_IRQ_ST3 IXP23XX_INTC_REG(0x38)
#define IXP23XX_INTR_IRQ_ST4 IXP23XX_INTC_REG(0x3c)
#define IXP23XX_INTR_IRQ_ENC_ST_OFFSET 0x54
/****************************************************************************
* GPIO.
****************************************************************************/
#define IXP23XX_GPIO_REG(x) ((volatile unsigned long *)(IXP23XX_GPIO_VIRT + (x)))
#define IXP23XX_GPIO_GPOUTR IXP23XX_GPIO_REG(0x00)
#define IXP23XX_GPIO_GPOER IXP23XX_GPIO_REG(0x04)
#define IXP23XX_GPIO_GPINR IXP23XX_GPIO_REG(0x08)
#define IXP23XX_GPIO_GPISR IXP23XX_GPIO_REG(0x0c)
#define IXP23XX_GPIO_GPIT1R IXP23XX_GPIO_REG(0x10)
#define IXP23XX_GPIO_GPIT2R IXP23XX_GPIO_REG(0x14)
#define IXP23XX_GPIO_GPCLKR IXP23XX_GPIO_REG(0x18)
#define IXP23XX_GPIO_GPDBSELR IXP23XX_GPIO_REG(0x1c)
#define IXP23XX_GPIO_STYLE_MASK 0x7
#define IXP23XX_GPIO_STYLE_ACTIVE_HIGH 0x0
#define IXP23XX_GPIO_STYLE_ACTIVE_LOW 0x1
#define IXP23XX_GPIO_STYLE_RISING_EDGE 0x2
#define IXP23XX_GPIO_STYLE_FALLING_EDGE 0x3
#define IXP23XX_GPIO_STYLE_TRANSITIONAL 0x4
#define IXP23XX_GPIO_STYLE_SIZE 3
/****************************************************************************
* Timer.
****************************************************************************/
#define IXP23XX_TIMER_REG(x) ((volatile unsigned long *)(IXP23XX_TIMER_VIRT + (x)))
#define IXP23XX_TIMER_CONT IXP23XX_TIMER_REG(0x00)
#define IXP23XX_TIMER1_TIMESTAMP IXP23XX_TIMER_REG(0x04)
#define IXP23XX_TIMER1_RELOAD IXP23XX_TIMER_REG(0x08)
#define IXP23XX_TIMER2_TIMESTAMP IXP23XX_TIMER_REG(0x0c)
#define IXP23XX_TIMER2_RELOAD IXP23XX_TIMER_REG(0x10)
#define IXP23XX_TIMER_WDOG IXP23XX_TIMER_REG(0x14)
#define IXP23XX_TIMER_WDOG_EN IXP23XX_TIMER_REG(0x18)
#define IXP23XX_TIMER_WDOG_KEY IXP23XX_TIMER_REG(0x1c)
#define IXP23XX_TIMER_WDOG_KEY_MAGIC 0x482e
#define IXP23XX_TIMER_STATUS IXP23XX_TIMER_REG(0x20)
#define IXP23XX_TIMER_SOFT_RESET IXP23XX_TIMER_REG(0x24)
#define IXP23XX_TIMER_SOFT_RESET_EN IXP23XX_TIMER_REG(0x28)
#define IXP23XX_TIMER_ENABLE (1 << 0)
#define IXP23XX_TIMER_ONE_SHOT (1 << 1)
/* Low order bits of reload value ignored */
#define IXP23XX_TIMER_RELOAD_MASK (0x3)
#define IXP23XX_TIMER_DISABLED (0x0)
#define IXP23XX_TIMER1_INT_PEND (1 << 0)
#define IXP23XX_TIMER2_INT_PEND (1 << 1)
#define IXP23XX_TIMER_STATUS_TS_PEND (1 << 2)
#define IXP23XX_TIMER_STATUS_WDOG_PEND (1 << 3)
#define IXP23XX_TIMER_STATUS_WARM_RESET (1 << 4)
/****************************************************************************
* CAP CSRs.
****************************************************************************/
#define IXP23XX_GLOBAL_REG(x) ((volatile unsigned long *)(IXP23XX_CAP_CSR_VIRT + 0x4a00 + (x)))
#define IXP23XX_PRODUCT_ID IXP23XX_GLOBAL_REG(0x00)
#define IXP23XX_MISC_CONTROL IXP23XX_GLOBAL_REG(0x04)
#define IXP23XX_MSF_CLK_CNTRL IXP23XX_GLOBAL_REG(0x08)
#define IXP23XX_RESET0 IXP23XX_GLOBAL_REG(0x0c)
#define IXP23XX_RESET1 IXP23XX_GLOBAL_REG(0x10)
#define IXP23XX_STRAP_OPTIONS IXP23XX_GLOBAL_REG(0x18)
#define IXP23XX_ENABLE_WATCHDOG (1 << 24)
#define IXP23XX_SHPC_INIT_COMP (1 << 21)
#define IXP23XX_RST_ALL (1 << 16)
#define IXP23XX_RESET_PCI (1 << 2)
#define IXP23XX_PCI_UNIT_RESET (1 << 1)
#define IXP23XX_XSCALE_RESET (1 << 0)
#define IXP23XX_UENGINE_CSR_VIRT_BASE (IXP23XX_CAP_CSR_VIRT + 0x18000)
/****************************************************************************
* PCI CSRs.
****************************************************************************/
#define IXP23XX_PCI_CREG(x) ((volatile unsigned long *)(IXP23XX_PCI_CREG_VIRT + (x)))
#define IXP23XX_PCI_CMDSTAT IXP23XX_PCI_CREG(0x04)
#define IXP23XX_PCI_SRAM_BAR IXP23XX_PCI_CREG(0x14)
#define IXP23XX_PCI_SDRAM_BAR IXP23XX_PCI_CREG(0x18)
#define IXP23XX_PCI_CSR(x) ((volatile unsigned long *)(IXP23XX_PCI_CREG_VIRT + 0x01000000 + (x)))
#define IXP23XX_PCI_OUT_INT_STATUS IXP23XX_PCI_CSR(0x0030)
#define IXP23XX_PCI_OUT_INT_MASK IXP23XX_PCI_CSR(0x0034)
#define IXP23XX_PCI_SRAM_BASE_ADDR_MASK IXP23XX_PCI_CSR(0x00fc)
#define IXP23XX_PCI_DRAM_BASE_ADDR_MASK IXP23XX_PCI_CSR(0x0100)
#define IXP23XX_PCI_CONTROL IXP23XX_PCI_CSR(0x013c)
#define IXP23XX_PCI_ADDR_EXT IXP23XX_PCI_CSR(0x0140)
#define IXP23XX_PCI_ME_PUSH_STATUS IXP23XX_PCI_CSR(0x0148)
#define IXP23XX_PCI_ME_PUSH_EN IXP23XX_PCI_CSR(0x014c)
#define IXP23XX_PCI_ERR_STATUS IXP23XX_PCI_CSR(0x0150)
#define IXP23XX_PCI_ERROR_STATUS IXP23XX_PCI_CSR(0x0150)
#define IXP23XX_PCI_ERR_ENABLE IXP23XX_PCI_CSR(0x0154)
#define IXP23XX_PCI_XSCALE_INT_STATUS IXP23XX_PCI_CSR(0x0158)
#define IXP23XX_PCI_XSCALE_INT_ENABLE IXP23XX_PCI_CSR(0x015c)
#define IXP23XX_PCI_CPP_ADDR_BITS IXP23XX_PCI_CSR(0x0160)
#endif
/*
* arch/arm/mach-ixp23xx/include/mach/memory.h
*
* Copyright (c) 2003-2004 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
#include <mach/hardware.h>
/*
* Physical DRAM offset.
*/
#define PLAT_PHYS_OFFSET (0x00000000)
#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)
#define __phys_to_bus(x) ((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
#define __bus_to_phys(x) ((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v))
#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b))
#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p))
#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b))
#define arch_is_coherent() 1
#endif
/*
* arch/arm/mach-ixp23xx/include/mach/platform.h
*
* Various bits of code used by platform-level code.
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2005 (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 __ASSEMBLY__
static inline unsigned long ixp2000_reg_read(volatile void *reg)
{
return *((volatile unsigned long *)reg);
}
static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
{
*((volatile unsigned long *)reg) = val;
}
static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
{
*((volatile unsigned long *)reg) = val;
}
struct pci_sys_data;
void ixp23xx_map_io(void);
void ixp23xx_init_irq(void);
void ixp23xx_sys_init(void);
void ixp23xx_restart(char, const char *);
int ixp23xx_pci_setup(int, struct pci_sys_data *);
void ixp23xx_pci_preinit(void);
struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*);
void ixp23xx_pci_slave_init(void);
extern struct sys_timer ixp23xx_timer;
#define IXP23XX_UART_XTAL 14745600
#ifndef __ASSEMBLY__
/*
* Is system memory on the XSI or CPP bus?
*/
static inline unsigned ixp23xx_cpp_boot(void)
{
return (*IXP23XX_EXP_CFG0 & IXP23XX_EXP_CFG0_XSI_NOT_PRES);
}
#endif
#endif
/*
* arch/arm/mach-ixp23xx/include/mach/time.h
*/
/*
* arch/arm/mach-ixp23xx/include/mach/timex.h
*
* XScale architecture timex specifications
*/
#define CLOCK_TICK_RATE 75000000
/*
* arch/arm/mach-ixp23xx/include/mach/uncompress.h
*
* Copyright (C) 2002-2004 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_UNCOMPRESS_H
#define __ASM_ARCH_UNCOMPRESS_H
#include <mach/ixp23xx.h>
#include <linux/serial_reg.h>
#define UART_BASE ((volatile u32 *)IXP23XX_UART1_PHYS)
static inline void putc(char c)
{
int j;
for (j = 0; j < 0x1000; j++) {
if (UART_BASE[UART_LSR] & UART_LSR_THRE)
break;
barrier();
}
UART_BASE[UART_TX] = c;
}
static inline void flush(void)
{
}
#define arch_decomp_setup()
#define arch_decomp_wdog()
#endif
/*
* arch/arm/mach-ixp23xx/ixdp2351.c
*
* IXDP2351 board-specific routines
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2005 (c) MontaVista Software, Inc.
*
* Based on 2.4 code Copyright 2004 (c) Intel Corporation
*
* 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/init.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/bitops.h>
#include <linux/ioport.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/mtd/physmap.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
/*
* IXDP2351 Interrupt Handling
*/
static void ixdp2351_inta_mask(struct irq_data *d)
{
*IXDP2351_CPLD_INTA_MASK_SET_REG = IXDP2351_INTA_IRQ_MASK(d->irq);
}
static void ixdp2351_inta_unmask(struct irq_data *d)
{
*IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(d->irq);
}
static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc)
{
u16 ex_interrupt =
*IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID;
int i;
desc->irq_data.chip->irq_mask(&desc->irq_data);
for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) {
if (ex_interrupt & (1 << i)) {
int cpld_irq =
IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i);
generic_handle_irq(cpld_irq);
}
}
desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
static struct irq_chip ixdp2351_inta_chip = {
.irq_ack = ixdp2351_inta_mask,
.irq_mask = ixdp2351_inta_mask,
.irq_unmask = ixdp2351_inta_unmask
};
static void ixdp2351_intb_mask(struct irq_data *d)
{
*IXDP2351_CPLD_INTB_MASK_SET_REG = IXDP2351_INTB_IRQ_MASK(d->irq);
}
static void ixdp2351_intb_unmask(struct irq_data *d)
{
*IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(d->irq);
}
static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc)
{
u16 ex_interrupt =
*IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID;
int i;
desc->irq_data.chip->irq_ack(&desc->irq_data);
for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
if (ex_interrupt & (1 << i)) {
int cpld_irq =
IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
generic_handle_irq(cpld_irq);
}
}
desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
static struct irq_chip ixdp2351_intb_chip = {
.irq_ack = ixdp2351_intb_mask,
.irq_mask = ixdp2351_intb_mask,
.irq_unmask = ixdp2351_intb_unmask
};
void __init ixdp2351_init_irq(void)
{
int irq;
/* Mask all interrupts from CPLD, disable simulation */
*IXDP2351_CPLD_INTA_MASK_SET_REG = (u16) -1;
*IXDP2351_CPLD_INTB_MASK_SET_REG = (u16) -1;
*IXDP2351_CPLD_INTA_SIM_REG = 0;
*IXDP2351_CPLD_INTB_SIM_REG = 0;
ixp23xx_init_irq();
for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE);
irq <
IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + IXDP2351_INTA_IRQ_NUM);
irq++) {
if (IXDP2351_INTA_IRQ_MASK(irq) & IXDP2351_INTA_IRQ_VALID) {
set_irq_flags(irq, IRQF_VALID);
irq_set_chip_and_handler(irq, &ixdp2351_inta_chip,
handle_level_irq);
}
}
for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE);
irq <
IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + IXDP2351_INTB_IRQ_NUM);
irq++) {
if (IXDP2351_INTB_IRQ_MASK(irq) & IXDP2351_INTB_IRQ_VALID) {
set_irq_flags(irq, IRQF_VALID);
irq_set_chip_and_handler(irq, &ixdp2351_intb_chip,
handle_level_irq);
}
}
irq_set_chained_handler(IRQ_IXP23XX_INTA, ixdp2351_inta_handler);
irq_set_chained_handler(IRQ_IXP23XX_INTB, ixdp2351_intb_handler);
}
/*
* IXDP2351 PCI
*/
/*
* This board does not do normal PCI IRQ routing, or any
* sort of swizzling, so we just need to check where on the
* bus the device is and figure out what CPLD pin it is
* being routed to.
*/
#define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
static int __init ixdp2351_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
u8 bus = dev->bus->number;
u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin);
struct pci_bus *tmp_bus = dev->bus;
/* Primary bus, no interrupts here */
if (!bus)
return -1;
/* Lookup first leaf in bus tree */
while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL))
tmp_bus = tmp_bus->parent;
/* Select between known bridges */
switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) {
/* Device is located after first bridge */
case 0x0008:
if (tmp_bus == dev->bus) {
/* Device is located directy after first bridge */
switch (devpin) {
/* Onboard 82546 */
case DEVPIN(1, 1): /* Onboard 82546 ch 0 */
return IRQ_IXDP2351_INTA_82546;
case DEVPIN(1, 2): /* Onboard 82546 ch 1 */
return IRQ_IXDP2351_INTB_82546;
/* PMC SLOT */
case DEVPIN(0, 1): /* PMCP INTA# */
case DEVPIN(2, 4): /* PMCS INTD# */
return IRQ_IXDP2351_SPCI_PMC_INTA;
case DEVPIN(0, 2): /* PMCP INTB# */
case DEVPIN(2, 1): /* PMCS INTA# */
return IRQ_IXDP2351_SPCI_PMC_INTB;
case DEVPIN(0, 3): /* PMCP INTC# */
case DEVPIN(2, 2): /* PMCS INTB# */
return IRQ_IXDP2351_SPCI_PMC_INTC;
case DEVPIN(0, 4): /* PMCP INTD# */
case DEVPIN(2, 3): /* PMCS INTC# */
return IRQ_IXDP2351_SPCI_PMC_INTD;
}
} else {
/* Device is located indirectly after first bridge */
/* Not supported now */
return -1;
}
break;
case 0x0010:
if (tmp_bus == dev->bus) {
/* Device is located directy after second bridge */
/* Secondary bus of second bridge */
switch (devpin) {
case DEVPIN(0, 1): /* DB#0 */
case DEVPIN(0, 2):
case DEVPIN(0, 3):
case DEVPIN(0, 4):
return IRQ_IXDP2351_SPCI_DB_0;
case DEVPIN(1, 1): /* DB#1 */
case DEVPIN(1, 2):
case DEVPIN(1, 3):
case DEVPIN(1, 4):
return IRQ_IXDP2351_SPCI_DB_1;
case DEVPIN(2, 1): /* FIC1 */
case DEVPIN(2, 2):
case DEVPIN(2, 3):
case DEVPIN(2, 4):
case DEVPIN(3, 1): /* FIC2 */
case DEVPIN(3, 2):
case DEVPIN(3, 3):
case DEVPIN(3, 4):
return IRQ_IXDP2351_SPCI_FIC;
}
} else {
/* Device is located indirectly after second bridge */
/* Not supported now */
return -1;
}
break;
}
return -1;
}
struct hw_pci ixdp2351_pci __initdata = {
.nr_controllers = 1,
.preinit = ixp23xx_pci_preinit,
.setup = ixp23xx_pci_setup,
.scan = ixp23xx_pci_scan_bus,
.map_irq = ixdp2351_map_irq,
};
int __init ixdp2351_pci_init(void)
{
if (machine_is_ixdp2351())
pci_common_init(&ixdp2351_pci);
return 0;
}
subsys_initcall(ixdp2351_pci_init);
/*
* IXDP2351 Static Mapped I/O
*/
static struct map_desc ixdp2351_io_desc[] __initdata = {
{
.virtual = IXDP2351_NP_VIRT_BASE,
.pfn = __phys_to_pfn((u64)IXDP2351_NP_PHYS_BASE),
.length = IXDP2351_NP_PHYS_SIZE,
.type = MT_DEVICE
}, {
.virtual = IXDP2351_BB_BASE_VIRT,
.pfn = __phys_to_pfn((u64)IXDP2351_BB_BASE_PHYS),
.length = IXDP2351_BB_SIZE,
.type = MT_DEVICE
}
};
static void __init ixdp2351_map_io(void)
{
ixp23xx_map_io();
iotable_init(ixdp2351_io_desc, ARRAY_SIZE(ixdp2351_io_desc));
}
static struct physmap_flash_data ixdp2351_flash_data = {
.width = 1,
};
static struct resource ixdp2351_flash_resource = {
.start = 0x90000000,
.end = 0x93ffffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device ixdp2351_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &ixdp2351_flash_data,
},
.num_resources = 1,
.resource = &ixdp2351_flash_resource,
};
static void __init ixdp2351_init(void)
{
platform_device_register(&ixdp2351_flash);
/*
* Mark flash as writeable
*/
IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE;
IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE;
ixp23xx_sys_init();
}
static void ixdp2351_restart(char mode, const char *cmd)
{
/* First try machine specific support */
*IXDP2351_CPLD_RESET1_REG = IXDP2351_CPLD_RESET1_MAGIC;
(void) *IXDP2351_CPLD_RESET1_REG;
*IXDP2351_CPLD_RESET1_REG = IXDP2351_CPLD_RESET1_ENABLE;
ixp23xx_restart(mode, cmd);
}
MACHINE_START(IXDP2351, "Intel IXDP2351 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.map_io = ixdp2351_map_io,
.init_irq = ixdp2351_init_irq,
.timer = &ixp23xx_timer,
.atag_offset = 0x100,
.init_machine = ixdp2351_init,
.restart = ixdp2351_restart,
MACHINE_END
/*
* arch/arm/mach-ixp23xx/pci.c
*
* PCI routines for IXP23XX based systems
*
* Copyright (c) 2005 MontaVista Software, Inc.
*
* based on original code:
*
* Author: Naeem Afzal <naeem.m.afzal@intel.com>
* Copyright 2002-2005 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/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/delay.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/mach/pci.h>
#include <mach/hardware.h>
extern int (*external_fault) (unsigned long, struct pt_regs *);
static volatile int pci_master_aborts = 0;
#ifdef DEBUG
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
int clear_master_aborts(void);
static u32
*ixp23xx_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
{
u32 *paddress;
/*
* Must be dword aligned
*/
where &= ~3;
/*
* For top bus, generate type 0, else type 1
*/
if (!bus_nr) {
if (PCI_SLOT(devfn) >= 8)
return 0;
paddress = (u32 *) (IXP23XX_PCI_CFG0_VIRT
| (1 << (PCI_SLOT(devfn) + 16))
| (PCI_FUNC(devfn) << 8) | where);
} else {
paddress = (u32 *) (IXP23XX_PCI_CFG1_VIRT
| (bus_nr << 16)
| (PCI_SLOT(devfn) << 11)
| (PCI_FUNC(devfn) << 8) | where);
}
return paddress;
}
/*
* 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 int ixp23xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *value)
{
u32 n;
u32 *addr;
n = where % 4;
DBG("In config_read(%d) %d from dev %d:%d:%d\n", size, where,
bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
addr = ixp23xx_pci_config_addr(bus->number, devfn, where);
if (!addr)
return PCIBIOS_DEVICE_NOT_FOUND;
pci_master_aborts = 0;
*value = (*addr >> (8*n)) & bytemask[size];
if (pci_master_aborts) {
pci_master_aborts = 0;
*value = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND;
}
return PCIBIOS_SUCCESSFUL;
}
/*
* We don't do error checking on the address for writes.
* It's assumed that the user checked for the device existing first
* by doing a read first.
*/
static int ixp23xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value)
{
u32 mask;
u32 *addr;
u32 temp;
mask = ~(bytemask[size] << ((where % 0x4) * 8));
addr = ixp23xx_pci_config_addr(bus->number, devfn, where);
if (!addr)
return PCIBIOS_DEVICE_NOT_FOUND;
temp = (u32) (value) << ((where % 0x4) * 8);
*addr = (*addr & mask) | temp;
clear_master_aborts();
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops ixp23xx_pci_ops = {
.read = ixp23xx_pci_read_config,
.write = ixp23xx_pci_write_config,
};
struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
return pci_scan_root_bus(NULL, sysdata->busnr, &ixp23xx_pci_ops,
sysdata, &sysdata->resources);
}
int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
volatile unsigned long temp;
unsigned long flags;
pci_master_aborts = 1;
local_irq_save(flags);
temp = *IXP23XX_PCI_CONTROL;
/*
* master abort and cmd tgt err
*/
if (temp & ((1 << 8) | (1 << 5)))
*IXP23XX_PCI_CONTROL = temp;
temp = *IXP23XX_PCI_CMDSTAT;
if (temp & (1 << 29))
*IXP23XX_PCI_CMDSTAT = temp;
local_irq_restore(flags);
/*
* 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;
}
int clear_master_aborts(void)
{
volatile u32 temp;
temp = *IXP23XX_PCI_CONTROL;
/*
* master abort and cmd tgt err
*/
if (temp & ((1 << 8) | (1 << 5)))
*IXP23XX_PCI_CONTROL = temp;
temp = *IXP23XX_PCI_CMDSTAT;
if (temp & (1 << 29))
*IXP23XX_PCI_CMDSTAT = temp;
return 0;
}
static void __init ixp23xx_pci_common_init(void)
{
#ifdef __ARMEB__
*IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */
#endif
/*
* ADDR_31 needs to be clear for PCI memory access to CPP memory
*/
*IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_ADDR_31;
*IXP23XX_CPP2XSI_CURR_XFER_REG3 |= IXP23XX_CPP2XSI_PSH_OFF;
/*
* Select correct memory for PCI inbound transactions
*/
if (ixp23xx_cpp_boot()) {
*IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1);
} else {
*IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1);
/*
* Enable coherency on A2 silicon.
*/
if (arch_is_coherent())
*IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF;
}
}
void __init ixp23xx_pci_preinit(void)
{
pcibios_min_io = 0;
pcibios_min_mem = 0xe0000000;
pci_set_flags(0);
ixp23xx_pci_common_init();
hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 0,
"PCI config cycle to non-existent device");
*IXP23XX_PCI_ADDR_EXT = 0x0000e000;
}
/*
* Prevent PCI layer from seeing the inbound host-bridge resources
*/
static void __devinit pci_fixup_ixp23xx(struct pci_dev *dev)
{
int i;
dev->class &= 0xff;
dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
dev->resource[i].start = 0;
dev->resource[i].end = 0;
dev->resource[i].flags = 0;
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9002, pci_fixup_ixp23xx);
/*
* IXP2300 systems often have large resource requirements, so we just
* use our own resource space.
*/
static struct resource ixp23xx_pci_mem_space = {
.start = IXP23XX_PCI_MEM_START,
.end = IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE - 1,
.flags = IORESOURCE_MEM,
.name = "PCI Mem Space"
};
static struct resource ixp23xx_pci_io_space = {
.start = 0x00000100,
.end = 0x01ffffff,
.flags = IORESOURCE_IO,
.name = "PCI I/O Space"
};
int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
{
if (nr >= 1)
return 0;
pci_add_resource_offset(&sys->resources,
&ixp23xx_pci_io_space, sys->io_offset);
pci_add_resource_offset(&sys->resources,
&ixp23xx_pci_mem_space, sys->mem_offset);
return 1;
}
void __init ixp23xx_pci_slave_init(void)
{
ixp23xx_pci_common_init();
}
/*
* arch/arm/mach-ixp23xx/roadrunner.c
*
* RoadRunner board-specific routines
*
* Author: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2005 (c) MontaVista Software, Inc.
*
* Based on 2.4 code Copyright 2005 (c) ADI Engineering Corporation
*
* 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/init.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/bitops.h>
#include <linux/ioport.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/mtd/physmap.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/tlbflush.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
/*
* Interrupt mapping
*/
#define INTA IRQ_ROADRUNNER_PCI_INTA
#define INTB IRQ_ROADRUNNER_PCI_INTB
#define INTC IRQ_ROADRUNNER_PCI_INTC
#define INTD IRQ_ROADRUNNER_PCI_INTD
#define INTC_PIN IXP23XX_GPIO_PIN_11
#define INTD_PIN IXP23XX_GPIO_PIN_12
static int __init roadrunner_map_irq(const struct pci_dev *dev, u8 idsel,
u8 pin)
{
static int pci_card_slot_irq[] = {INTB, INTC, INTD, INTA};
static int pmc_card_slot_irq[] = {INTA, INTB, INTC, INTD};
static int usb_irq[] = {INTB, INTC, INTD, -1};
static int mini_pci_1_irq[] = {INTB, INTC, -1, -1};
static int mini_pci_2_irq[] = {INTC, INTD, -1, -1};
switch(dev->bus->number) {
case 0:
switch(dev->devfn) {
case 0x0: // PCI-PCI bridge
break;
case 0x8: // PCI Card Slot
return pci_card_slot_irq[pin - 1];
case 0x10: // PMC Slot
return pmc_card_slot_irq[pin - 1];
case 0x18: // PMC Slot Secondary Agent
break;
case 0x20: // IXP Processor
break;
default:
return NO_IRQ;
}
break;
case 1:
switch(dev->devfn) {
case 0x0: // IDE Controller
return (pin == 1) ? INTC : -1;
case 0x8: // USB fun 0
case 0x9: // USB fun 1
case 0xa: // USB fun 2
return usb_irq[pin - 1];
case 0x10: // Mini PCI 1
return mini_pci_1_irq[pin-1];
case 0x18: // Mini PCI 2
return mini_pci_2_irq[pin-1];
case 0x20: // MEM slot
return (pin == 1) ? INTA : -1;
default:
return NO_IRQ;
}
break;
default:
return NO_IRQ;
}
return NO_IRQ;
}
static void __init roadrunner_pci_preinit(void)
{
irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
ixp23xx_pci_preinit();
}
static struct hw_pci roadrunner_pci __initdata = {
.nr_controllers = 1,
.preinit = roadrunner_pci_preinit,
.setup = ixp23xx_pci_setup,
.scan = ixp23xx_pci_scan_bus,
.map_irq = roadrunner_map_irq,
};
static int __init roadrunner_pci_init(void)
{
if (machine_is_roadrunner())
pci_common_init(&roadrunner_pci);
return 0;
};
subsys_initcall(roadrunner_pci_init);
static struct physmap_flash_data roadrunner_flash_data = {
.width = 2,
};
static struct resource roadrunner_flash_resource = {
.start = 0x90000000,
.end = 0x93ffffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device roadrunner_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &roadrunner_flash_data,
},
.num_resources = 1,
.resource = &roadrunner_flash_resource,
};
static void __init roadrunner_init(void)
{
platform_device_register(&roadrunner_flash);
/*
* Mark flash as writeable
*/
IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE;
IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE;
ixp23xx_sys_init();
}
MACHINE_START(ROADRUNNER, "ADI Engineering RoadRunner Development Platform")
/* Maintainer: Deepak Saxena */
.map_io = ixp23xx_map_io,
.init_irq = ixp23xx_init_irq,
.timer = &ixp23xx_timer,
.atag_offset = 0x100,
.init_machine = roadrunner_init,
.restart = ixp23xx_restart,
MACHINE_END
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment