提交 ca9ba447 编写于 作者: L Linus Torvalds

Merge master.kernel.org:/home/rmk/linux-2.6-arm

* master.kernel.org:/home/rmk/linux-2.6-arm:
  [ARM] 3388/1: ixp23xx: add core ixp23xx support
  [ARM] 3417/1: add support for logicpd pxa270 card engine
  [ARM] 3387/1: ixp23xx: add defconfig
  [ARM] 3377/2: add support for intel xsc3 core
  [ARM] Move ice-dcc code into misc.c
  [ARM] Fix decompressor serial IO to give CRLF not LFCR
  [ARM] proc-v6: mark page table walks outer-cacheable, shared.  Enable NX.
  [ARM] nommu: trivial patch for arch/arm/lib/Makefile
  [ARM] 3416/1: Update LART site URL
  [ARM] 3415/1: Akita: Add missing EXPORT_SYMBOL
  [ARM] 3414/1: ep93xx: reset ethernet controller before uncompressing
......@@ -26,7 +26,7 @@ Installing a bootloader
A couple of bootloaders able to boot Linux on Assabet are available:
BLOB (http://www.lart.tudelft.nl/lartware/blob/)
BLOB (http://www.lartmaker.nl/lartware/blob/)
BLOB is a bootloader used within the LART project. Some contributed
patches were merged into BLOB to add support for Assabet.
......
......@@ -11,4 +11,4 @@ is under development, with plenty of others in different stages of
planning.
The hardware designs for this board have been released under an open license;
see the LART page at http://www.lart.tudelft.nl/ for more information.
see the LART page at http://www.lartmaker.nl/ for more information.
......@@ -153,6 +153,12 @@ config ARCH_IXP2000
help
Support for Intel's IXP2400/2800 (XScale) family of processors.
config ARCH_IXP23XX
bool "IXP23XX-based"
select PCI
help
Support for Intel's IXP23xx (XScale) family of processors.
config ARCH_L7200
bool "LinkUp-L7200"
select FIQ
......@@ -274,6 +280,8 @@ source "arch/arm/mach-ixp4xx/Kconfig"
source "arch/arm/mach-ixp2000/Kconfig"
source "arch/arm/mach-ixp23xx/Kconfig"
source "arch/arm/mach-pxa/Kconfig"
source "arch/arm/mach-sa1100/Kconfig"
......@@ -792,7 +800,8 @@ source "drivers/acorn/block/Kconfig"
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
|| ARCH_IXP23XX
source "drivers/ide/Kconfig"
endif
......
......@@ -57,6 +57,7 @@ tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
ifeq ($(CONFIG_AEABI),y)
......@@ -97,6 +98,7 @@ endif
machine-$(CONFIG_ARCH_IOP3XX) := iop3xx
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
machine-$(CONFIG_ARCH_IXP2000) := ixp2000
machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
machine-$(CONFIG_ARCH_OMAP1) := omap1
machine-$(CONFIG_ARCH_OMAP2) := omap2
incdir-$(CONFIG_ARCH_OMAP) := omap
......
......@@ -50,10 +50,6 @@ ifeq ($(CONFIG_ARCH_AT91RM9200),y)
OBJS += head-at91rm9200.o
endif
ifeq ($(CONFIG_DEBUG_ICEDCC),y)
OBJS += ice-dcc.o
endif
ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
OBJS += big-endian.o
endif
......
.text
.global icedcc_putc
icedcc_putc:
mov r2, #0x4000000
1:
subs r2, r2, #1
movlt pc, r14
mrc p14, 0, r1, c0, c0, 0
tst r1, #2
bne 1b
mcr p14, 0, r0, c1, c0, 0
mov pc, r14
......@@ -20,24 +20,45 @@ unsigned int __machine_arch_type;
#include <linux/string.h>
#include <asm/arch/uncompress.h>
#ifdef STANDALONE_DEBUG
#define putstr printf
#endif
#else
static void putstr(const char *ptr);
#include <linux/compiler.h>
#include <asm/arch/uncompress.h>
#ifdef CONFIG_DEBUG_ICEDCC
#define putstr icedcc_putstr
#define putc icedcc_putc
static void icedcc_putc(int ch)
{
int status, i = 0x4000000;
extern void icedcc_putc(int ch);
do {
if (--i < 0)
return;
static void
icedcc_putstr(const char *ptr)
asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
} while (status & 2);
asm("mcr p15, 0, %0, c1, c0, 0" : : "r" (ch));
}
#define putc(ch) icedcc_putc(ch)
#define flush() do { } while (0)
#endif
static void putstr(const char *ptr)
{
for (; *ptr != '\0'; ptr++) {
icedcc_putc(*ptr);
char c;
while ((c = *ptr++) != '\0') {
if (c == '\n')
putc('\r');
putc(c);
}
flush();
}
#endif
......
此差异已折叠。
......@@ -18,7 +18,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
# the code in uaccess.S is not preemption safe and
# probably faster on ARMv3 only
ifeq ($CONFIG_PREEMPT,y)
ifeq ($(CONFIG_PREEMPT),y)
lib-y += copy_from_user.o copy_to_user.o
else
ifneq ($(CONFIG_CPU_32v3),y)
......
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/config.h>
#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.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 <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/system.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 <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(unsigned int irq, unsigned int type)
{
int line = 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 IRQT_BOTHEDGE:
int_style = IXP23XX_GPIO_STYLE_TRANSITIONAL;
irq_type = IXP23XX_IRQ_EDGE;
break;
case IRQT_RISING:
int_style = IXP23XX_GPIO_STYLE_RISING_EDGE;
irq_type = IXP23XX_IRQ_EDGE;
break;
case IRQT_FALLING:
int_style = IXP23XX_GPIO_STYLE_FALLING_EDGE;
irq_type = IXP23XX_IRQ_EDGE;
break;
case IRQT_HIGH:
int_style = IXP23XX_GPIO_STYLE_ACTIVE_HIGH;
irq_type = IXP23XX_IRQ_LEVEL;
break;
case IRQT_LOW:
int_style = IXP23XX_GPIO_STYLE_ACTIVE_LOW;
irq_type = IXP23XX_IRQ_LEVEL;
break;
default:
return -EINVAL;
}
ixp23xx_config_irq(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(unsigned int irq)
{
volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
*intr_reg &= ~(1 << (irq % 32));
}
static void ixp23xx_irq_ack(unsigned int irq)
{
int line = 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(unsigned int irq)
{
volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
ixp23xx_irq_ack(irq);
*intr_reg |= (1 << (irq % 32));
}
static void ixp23xx_irq_edge_unmask(unsigned int irq)
{
volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
*intr_reg |= (1 << (irq % 32));
}
static struct irqchip ixp23xx_irq_level_chip = {
.ack = ixp23xx_irq_mask,
.mask = ixp23xx_irq_mask,
.unmask = ixp23xx_irq_level_unmask,
.set_type = ixp23xx_irq_set_type
};
static struct irqchip ixp23xx_irq_edge_chip = {
.ack = ixp23xx_irq_ack,
.mask = ixp23xx_irq_mask,
.unmask = ixp23xx_irq_edge_unmask,
.set_type = ixp23xx_irq_set_type
};
static void ixp23xx_pci_irq_mask(unsigned int irq)
{
*IXP23XX_PCI_XSCALE_INT_ENABLE &= ~(1 << (IRQ_IXP23XX_INTA + 27 - irq));
}
static void ixp23xx_pci_irq_unmask(unsigned int 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 irqdesc *desc, struct pt_regs *regs)
{
u32 pci_interrupt;
unsigned int irqno;
struct irqdesc *int_desc;
pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;
desc->chip->ack(irq);
/* 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();
}
int_desc = irq_desc + irqno;
int_desc->handle(irqno, int_desc, regs);
desc->chip->unmask(irq);
}
static struct irqchip ixp23xx_pci_irq_chip = {
.ack = ixp23xx_pci_irq_mask,
.mask = ixp23xx_pci_irq_mask,
.unmask = ixp23xx_pci_irq_unmask
};
static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type)
{
switch (type) {
case IXP23XX_IRQ_LEVEL:
set_irq_chip(irq, &ixp23xx_irq_level_chip);
set_irq_handler(irq, do_level_IRQ);
break;
case IXP23XX_IRQ_EDGE:
set_irq_chip(irq, &ixp23xx_irq_edge_chip);
set_irq_handler(irq, do_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++) {
set_irq_chip(irq, &ixp23xx_pci_irq_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID);
}
set_irq_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, struct pt_regs *regs)
{
/* Clear Pending Interrupt by writing '1' to it */
*IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
while ((*IXP23XX_TIMER_CONT - next_jiffy_time) > LATCH) {
timer_tick(regs);
next_jiffy_time += LATCH;
}
return IRQ_HANDLED;
}
static struct irqaction ixp23xx_timer_irq = {
.name = "IXP23xx Timer Tick",
.handler = ixp23xx_timer_interrupt,
.flags = SA_INTERRUPT | SA_TIMER,
};
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 Initializaion
*************************************************************************/
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)
{
platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices));
}
/*
* 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/config.h>
#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.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 <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/system.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/irq.h>
#include <asm/mach/pci.h>
static void __init espresso_init(void)
{
physmap_configure(0x90000000, 0x02000000, 2, NULL);
/*
* 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 */
.phys_io = IXP23XX_PERIPHERAL_PHYS,
.io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
.map_io = ixp23xx_map_io,
.init_irq = ixp23xx_init_irq,
.timer = &ixp23xx_timer,
.boot_params = 0x00000100,
.init_machine = espresso_init,
MACHINE_END
/*
* 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/config.h>
#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.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 <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/system.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/irq.h>
#include <asm/mach/pci.h>
/*
* IXDP2351 Interrupt Handling
*/
static void ixdp2351_inta_mask(unsigned int irq)
{
*IXDP2351_CPLD_INTA_MASK_SET_REG = IXDP2351_INTA_IRQ_MASK(irq);
}
static void ixdp2351_inta_unmask(unsigned int irq)
{
*IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(irq);
}
static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
{
u16 ex_interrupt =
*IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID;
int i;
desc->chip->mask(irq);
for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) {
if (ex_interrupt & (1 << i)) {
struct irqdesc *cpld_desc;
int cpld_irq =
IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i);
cpld_desc = irq_desc + cpld_irq;
cpld_desc->handle(cpld_irq, cpld_desc, regs);
}
}
desc->chip->unmask(irq);
}
static struct irqchip ixdp2351_inta_chip = {
.ack = ixdp2351_inta_mask,
.mask = ixdp2351_inta_mask,
.unmask = ixdp2351_inta_unmask
};
static void ixdp2351_intb_mask(unsigned int irq)
{
*IXDP2351_CPLD_INTB_MASK_SET_REG = IXDP2351_INTB_IRQ_MASK(irq);
}
static void ixdp2351_intb_unmask(unsigned int irq)
{
*IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(irq);
}
static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
{
u16 ex_interrupt =
*IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID;
int i;
desc->chip->ack(irq);
for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
if (ex_interrupt & (1 << i)) {
struct irqdesc *cpld_desc;
int cpld_irq =
IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
cpld_desc = irq_desc + cpld_irq;
cpld_desc->handle(cpld_irq, cpld_desc, regs);
}
}
desc->chip->unmask(irq);
}
static struct irqchip ixdp2351_intb_chip = {
.ack = ixdp2351_intb_mask,
.mask = ixdp2351_intb_mask,
.unmask = ixdp2351_intb_unmask
};
void 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);
set_irq_handler(irq, do_level_IRQ);
set_irq_chip(irq, &ixdp2351_inta_chip);
}
}
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);
set_irq_handler(irq, do_level_IRQ);
set_irq_chip(irq, &ixdp2351_intb_chip);
}
}
set_irq_chained_handler(IRQ_IXP23XX_INTA, &ixdp2351_inta_handler);
set_irq_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(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 void __init ixdp2351_init(void)
{
physmap_configure(0x90000000, 0x04000000, 1, NULL);
/*
* 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(IXDP2351, "Intel IXDP2351 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.phys_io = IXP23XX_PERIPHERAL_PHYS,
.io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
.map_io = ixdp2351_map_io,
.init_irq = ixdp2351_init_irq,
.timer = &ixp23xx_timer,
.boot_params = 0x00000100,
.init_machine = ixdp2351_init,
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/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/system.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
extern int (*external_fault) (unsigned long, struct pt_regs *);
static 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_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata);
}
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;
}
void __init ixp23xx_pci_preinit(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);
}
hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS,
"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;
sys->resource[0] = &ixp23xx_pci_io_space;
sys->resource[1] = &ixp23xx_pci_mem_space;
sys->resource[2] = NULL;
return 1;
}
/*
* 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/config.h>
#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.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 <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/system.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/irq.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(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 roadrunner_pci_preinit(void)
{
set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW);
set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_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 void __init roadrunner_init(void)
{
physmap_configure(0x90000000, 0x04000000, 2, NULL);
/*
* 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 */
.phys_io = IXP23XX_PERIPHERAL_PHYS,
.io_pg_offst = ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
.map_io = ixp23xx_map_io,
.init_irq = ixp23xx_init_irq,
.timer = &ixp23xx_timer,
.boot_params = 0x00000100,
.init_machine = roadrunner_init,
MACHINE_END
......@@ -10,6 +10,11 @@ config ARCH_LUBBOCK
select PXA25x
select SA1111
config MACH_LOGICPD_PXA270
bool "LogicPD PXA270 Card Engine Development Platform"
select PXA27x
select IWMMXT
config MACH_MAINSTONE
bool "Intel HCDDBBVA0 Development Platform"
select PXA27x
......
......@@ -9,6 +9,7 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
# Specific board support
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
......
/*
* linux/arch/arm/mach-pxa/lpd270.c
*
* Support for the LogicPD PXA270 Card Engine.
* Derived from the mainstone code, which carries these notices:
*
* Author: Nicolas Pitre
* Created: Nov 05, 2002
* Copyright: MontaVista Software Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/lpd270.h>
#include <asm/arch/audio.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
#include <asm/arch/irda.h>
#include <asm/arch/ohci.h>
#include "generic.h"
static unsigned int lpd270_irq_enabled;
static void lpd270_mask_irq(unsigned int irq)
{
int lpd270_irq = irq - LPD270_IRQ(0);
__raw_writew(~(1 << lpd270_irq), LPD270_INT_STATUS);
lpd270_irq_enabled &= ~(1 << lpd270_irq);
__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
}
static void lpd270_unmask_irq(unsigned int irq)
{
int lpd270_irq = irq - LPD270_IRQ(0);
lpd270_irq_enabled |= 1 << lpd270_irq;
__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
}
static struct irqchip lpd270_irq_chip = {
.ack = lpd270_mask_irq,
.mask = lpd270_mask_irq,
.unmask = lpd270_unmask_irq,
};
static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc,
struct pt_regs *regs)
{
unsigned long pending;
pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled;
do {
GEDR(0) = GPIO_bit(0); /* clear useless edge notification */
if (likely(pending)) {
irq = LPD270_IRQ(0) + __ffs(pending);
desc = irq_desc + irq;
desc_handle_irq(irq, desc, regs);
pending = __raw_readw(LPD270_INT_STATUS) &
lpd270_irq_enabled;
}
} while (pending);
}
static void __init lpd270_init_irq(void)
{
int irq;
pxa_init_irq();
__raw_writew(0, LPD270_INT_MASK);
__raw_writew(0, LPD270_INT_STATUS);
/* setup extra LogicPD PXA270 irqs */
for (irq = LPD270_IRQ(2); irq <= LPD270_IRQ(4); irq++) {
set_irq_chip(irq, &lpd270_irq_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler);
set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
}
#ifdef CONFIG_PM
static int lpd270_irq_resume(struct sys_device *dev)
{
__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
return 0;
}
static struct sysdev_class lpd270_irq_sysclass = {
set_kset_name("cpld_irq"),
.resume = lpd270_irq_resume,
};
static struct sys_device lpd270_irq_device = {
.cls = &lpd270_irq_sysclass,
};
static int __init lpd270_irq_device_init(void)
{
int ret = sysdev_class_register(&lpd270_irq_sysclass);
if (ret == 0)
ret = sysdev_register(&lpd270_irq_device);
return ret;
}
device_initcall(lpd270_irq_device_init);
#endif
static struct resource smc91x_resources[] = {
[0] = {
.start = LPD270_ETH_PHYS,
.end = (LPD270_ETH_PHYS + 0xfffff),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = LPD270_ETHERNET_IRQ,
.end = LPD270_ETHERNET_IRQ,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
};
static struct platform_device lpd270_audio_device = {
.name = "pxa2xx-ac97",
.id = -1,
};
static struct resource lpd270_flash_resources[] = {
[0] = {
.start = PXA_CS0_PHYS,
.end = PXA_CS0_PHYS + SZ_64M - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = PXA_CS1_PHYS,
.end = PXA_CS1_PHYS + SZ_64M - 1,
.flags = IORESOURCE_MEM,
},
};
static struct mtd_partition lpd270_flash0_partitions[] = {
{
.name = "Bootloader",
.size = 0x00040000,
.offset = 0,
.mask_flags = MTD_WRITEABLE /* force read-only */
}, {
.name = "Kernel",
.size = 0x00400000,
.offset = 0x00040000,
}, {
.name = "Filesystem",
.size = MTDPART_SIZ_FULL,
.offset = 0x00440000
},
};
static struct flash_platform_data lpd270_flash_data[2] = {
{
.name = "processor-flash",
.map_name = "cfi_probe",
.parts = lpd270_flash0_partitions,
.nr_parts = ARRAY_SIZE(lpd270_flash0_partitions),
}, {
.name = "mainboard-flash",
.map_name = "cfi_probe",
.parts = NULL,
.nr_parts = 0,
}
};
static struct platform_device lpd270_flash_device[2] = {
{
.name = "pxa2xx-flash",
.id = 0,
.dev = {
.platform_data = &lpd270_flash_data[0],
},
.resource = &lpd270_flash_resources[0],
.num_resources = 1,
}, {
.name = "pxa2xx-flash",
.id = 1,
.dev = {
.platform_data = &lpd270_flash_data[1],
},
.resource = &lpd270_flash_resources[1],
.num_resources = 1,
},
};
static void lpd270_backlight_power(int on)
{
if (on) {
pxa_gpio_mode(GPIO16_PWM0_MD);
pxa_set_cken(CKEN0_PWM0, 1);
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x3ff;
PWM_PERVAL0 = 0x3ff;
} else {
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x0;
PWM_PERVAL0 = 0x3FF;
pxa_set_cken(CKEN0_PWM0, 0);
}
}
/* 5.7" TFT QVGA (LoLo display number 1) */
static struct pxafb_mach_info sharp_lq057q3dc02 __initdata = {
.pixclock = 100000,
.xres = 240,
.yres = 320,
.bpp = 16,
.hsync_len = 64,
.left_margin = 0x27,
.right_margin = 0x09,
.vsync_len = 0x04,
.upper_margin = 0x08,
.lower_margin = 0x14,
.sync = 0,
.lccr0 = 0x07800080,
.lccr3 = 0x04400007,
.pxafb_backlight_power = lpd270_backlight_power,
};
/* 6.4" TFT VGA (LoLo display number 5) */
static struct pxafb_mach_info sharp_lq64d343 __initdata = {
.pixclock = 20000,
.xres = 640,
.yres = 480,
.bpp = 16,
.hsync_len = 49,
.left_margin = 0x89,
.right_margin = 0x19,
.vsync_len = 18,
.upper_margin = 0x22,
.lower_margin = 0,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.lccr0 = 0x07800080,
.lccr3 = 0x04400001,
.pxafb_backlight_power = lpd270_backlight_power,
};
/* 3.5" TFT QVGA (LoLo display number 8) */
static struct pxafb_mach_info sharp_lq035q7db02_20 __initdata = {
.pixclock = 100000,
.xres = 240,
.yres = 320,
.bpp = 16,
.hsync_len = 0x34,
.left_margin = 0x09,
.right_margin = 0x09,
.vsync_len = 0x08,
.upper_margin = 0x05,
.lower_margin = 0x14,
.sync = 0,
.lccr0 = 0x07800080,
.lccr3 = 0x04400007,
.pxafb_backlight_power = lpd270_backlight_power,
};
static struct platform_device *platform_devices[] __initdata = {
&smc91x_device,
&lpd270_audio_device,
&lpd270_flash_device[0],
&lpd270_flash_device[1],
};
static int lpd270_ohci_init(struct device *dev)
{
/* setup Port1 GPIO pin. */
pxa_gpio_mode(88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */
pxa_gpio_mode(89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
/* Set the Power Control Polarity Low and Power Sense
Polarity Low to active low. */
UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
return 0;
}
static struct pxaohci_platform_data lpd270_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = lpd270_ohci_init,
};
static void __init lpd270_init(void)
{
lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
lpd270_flash_data[1].width = 4;
/*
* System bus arbiter setting:
* - Core_Park
* - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
*/
ARB_CNTRL = ARB_CORE_PARK | 0x234;
/*
* On LogicPD PXA270, we route AC97_SYSCLK via GPIO45.
*/
pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
// set_pxa_fb_info(&sharp_lq057q3dc02);
set_pxa_fb_info(&sharp_lq64d343);
// set_pxa_fb_info(&sharp_lq035q7db02_20);
pxa_set_ohci_info(&lpd270_ohci_platform_data);
}
static struct map_desc lpd270_io_desc[] __initdata = {
{
.virtual = LPD270_CPLD_VIRT,
.pfn = __phys_to_pfn(LPD270_CPLD_PHYS),
.length = LPD270_CPLD_SIZE,
.type = MT_DEVICE,
},
};
static void __init lpd270_map_io(void)
{
pxa_map_io();
iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc));
/* initialize sleep mode regs (wake-up sources, etc) */
PGSR0 = 0x00008800;
PGSR1 = 0x00000002;
PGSR2 = 0x0001FC00;
PGSR3 = 0x00001F81;
PWER = 0xC0000002;
PRER = 0x00000002;
PFER = 0x00000002;
/* for use I SRAM as framebuffer. */
PSLR |= 0x00000F04;
PCFR = 0x00000066;
}
MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine")
/* Maintainer: Peter Barada */
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = lpd270_map_io,
.init_irq = lpd270_init_irq,
.timer = &pxa_timer,
.init_machine = lpd270_init,
MACHINE_END
......@@ -467,6 +467,8 @@ struct platform_device akitaioexp_device = {
.id = -1,
};
EXPORT_SYMBOL_GPL(akitaioexp_device);
static void __init akita_init(void)
{
spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
......
......@@ -111,7 +111,7 @@ config SA1100_LART
bool "LART"
help
Say Y here if you are using the Linux Advanced Radio Terminal
(also known as the LART). See <http://www.lart.tudelft.nl/> for
(also known as the LART). See <http://www.lartmaker.nl/> for
information on the LART.
config SA1100_PLEB
......
......@@ -11,7 +11,7 @@
* linux-2.4.5-rmk1
*
* This software has been developed while working on the LART
* computing board (http://www.lart.tudelft.nl/), which is
* computing board (http://www.lartmaker.nl/), which is
* sponsored by the Mobile Multi-media Communications
* (http://www.mmc.tudelft.nl/) and Ubiquitous Communications
* (http://www.ubicom.tudelft.nl/) projects.
......
......@@ -239,6 +239,17 @@ config CPU_XSCALE
select CPU_CACHE_VIVT
select CPU_TLB_V4WBI
# XScale Core Version 3
config CPU_XSC3
bool
depends on ARCH_IXP23XX
default y
select CPU_32v5
select CPU_ABRT_EV5T
select CPU_CACHE_VIVT
select CPU_TLB_V4WBI
select IO_36
# ARMv6
config CPU_V6
bool "Support ARM V6 processor"
......@@ -361,11 +372,17 @@ config CPU_TLB_V4WBI
config CPU_TLB_V6
bool
#
# CPU supports 36-bit I/O
#
config IO_36
bool
comment "Processor Features"
config ARM_THUMB
bool "Support Thumb user binaries"
depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_V6
depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6
default y
help
Say Y if you want to include kernel support for running user space
......
......@@ -30,6 +30,7 @@ obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o
obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o
obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o
obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o
obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o
......@@ -51,4 +52,5 @@ obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
obj-$(CONFIG_CPU_SA110) += proc-sa110.o
obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o
obj-$(CONFIG_CPU_V6) += proc-v6.o
/*
* linux/arch/arm/lib/copypage-xsc3.S
*
* Copyright (C) 2004 Intel Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Adapted for 3rd gen XScale core, no more mini-dcache
* Author: Matt Gilbert (matthew.m.gilbert@intel.com)
*/
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/asm-offsets.h>
/*
* General note:
* We don't really want write-allocate cache behaviour for these functions
* since that will just eat through 8K of the cache.
*/
.text
.align 5
/*
* XSC3 optimised copy_user_page
* r0 = destination
* r1 = source
* r2 = virtual user address of ultimate destination page
*
* The source page may have some clean entries in the cache already, but we
* can safely ignore them - break_cow() will flush them out of the cache
* if we eventually end up using our copied page.
*
*/
ENTRY(xsc3_mc_copy_user_page)
stmfd sp!, {r4, r5, lr}
mov lr, #PAGE_SZ/64-1
pld [r1, #0]
pld [r1, #32]
1: pld [r1, #64]
pld [r1, #96]
2: ldrd r2, [r1], #8
mov ip, r0
ldrd r4, [r1], #8
mcr p15, 0, ip, c7, c6, 1 @ invalidate
strd r2, [r0], #8
ldrd r2, [r1], #8
strd r4, [r0], #8
ldrd r4, [r1], #8
strd r2, [r0], #8
strd r4, [r0], #8
ldrd r2, [r1], #8
mov ip, r0
ldrd r4, [r1], #8
mcr p15, 0, ip, c7, c6, 1 @ invalidate
strd r2, [r0], #8
ldrd r2, [r1], #8
subs lr, lr, #1
strd r4, [r0], #8
ldrd r4, [r1], #8
strd r2, [r0], #8
strd r4, [r0], #8
bgt 1b
beq 2b
ldmfd sp!, {r4, r5, pc}
.align 5
/*
* XScale optimised clear_user_page
* r0 = destination
* r1 = virtual user address of ultimate destination page
*/
ENTRY(xsc3_mc_clear_user_page)
mov r1, #PAGE_SZ/32
mov r2, #0
mov r3, #0
1: mcr p15, 0, r0, c7, c6, 1 @ invalidate line
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8
strd r2, [r0], #8
subs r1, r1, #1
bne 1b
mov pc, lr
__INITDATA
.type xsc3_mc_user_fns, #object
ENTRY(xsc3_mc_user_fns)
.long xsc3_mc_clear_user_page
.long xsc3_mc_copy_user_page
.size xsc3_mc_user_fns, . - xsc3_mc_user_fns
......@@ -557,7 +557,8 @@ void __init create_mapping(struct map_desc *md)
* supersections are only allocated for domain 0 regardless
* of the actual domain assignments in use.
*/
if (cpu_architecture() >= CPU_ARCH_ARMv6 && domain == 0) {
if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())
&& domain == 0) {
/*
* Align to supersection boundary if !high pages.
* High pages have already been checked for proper
......
......@@ -21,6 +21,14 @@
#define D_CACHE_LINE_SIZE 32
#define TTB_C (1 << 0)
#define TTB_S (1 << 1)
#define TTB_IMP (1 << 2)
#define TTB_RGN_NC (0 << 3)
#define TTB_RGN_WBWA (1 << 3)
#define TTB_RGN_WT (2 << 3)
#define TTB_RGN_WB (3 << 3)
.macro cpsie, flags
.ifc \flags, f
.long 0xf1080040
......@@ -115,7 +123,7 @@ ENTRY(cpu_v6_switch_mm)
mov r2, #0
ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
#ifdef CONFIG_SMP
orr r0, r0, #2 @ set shared pgtable
orr r0, r0, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable
#endif
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
......@@ -161,8 +169,8 @@ ENTRY(cpu_v6_set_pte)
tst r1, #L_PTE_YOUNG
biceq r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK
@ tst r1, #L_PTE_EXEC
@ orreq r2, r2, #PTE_EXT_XN
tst r1, #L_PTE_EXEC
orreq r2, r2, #PTE_EXT_XN
tst r1, #L_PTE_PRESENT
moveq r2, #0
......@@ -221,7 +229,7 @@ __v6_setup:
mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
mcr p15, 0, r0, c2, c0, 2 @ TTB control register
#ifdef CONFIG_SMP
orr r4, r4, #2 @ set shared pgtable
orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable
#endif
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
#ifdef CONFIG_VFP
......
/*
* linux/arch/arm/mm/proc-xsc3.S
*
* Original Author: Matthew Gilbert
* Current Maintainer: Deepak Saxena <dsaxena@plexity.net>
*
* Copyright 2004 (C) Intel Corp.
* Copyright 2005 (c) 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.
*
* MMU functions for the Intel XScale3 Core (XSC3). The XSC3 core is an
* extension to Intel's original XScale core that adds the following
* features:
*
* - ARMv6 Supersections
* - Low Locality Reference pages (replaces mini-cache)
* - 36-bit addressing
* - L2 cache
* - Cache-coherency if chipset supports it
*
* Based on orignal XScale code by Nicolas Pitre
*/
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
#include <asm/procinfo.h>
#include <asm/hardware.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include "proc-macros.S"
/*
* This is the maximum size of an area which will be flushed. If the
* area is larger than this, then we flush the whole cache.
*/
#define MAX_AREA_SIZE 32768
/*
* The cache line size of the I and D cache.
*/
#define CACHELINESIZE 32
/*
* The size of the data cache.
*/
#define CACHESIZE 32768
/*
* Run with L2 enabled.
*/
#define L2_CACHE_ENABLE 1
/*
* Enable the Branch Target Buffer (can cause crashes, see erratum #42.)
*/
#define BTB_ENABLE 0
/*
* This macro is used to wait for a CP15 write and is needed
* when we have to ensure that the last operation to the co-pro
* was completed before continuing with operation.
*/
.macro cpwait_ret, lr, rd
mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15
sub pc, \lr, \rd, LSR #32 @ wait for completion and
@ flush instruction pipeline
.endm
/*
* This macro cleans & invalidates the entire xsc3 dcache by set & way.
*/
.macro clean_d_cache rd, rs
mov \rd, #0x1f00
orr \rd, \rd, #0x00e0
1: mcr p15, 0, \rd, c7, c14, 2 @ clean/inv set/way
adds \rd, \rd, #0x40000000
bcc 1b
subs \rd, \rd, #0x20
bpl 1b
.endm
.text
/*
* cpu_xsc3_proc_init()
*
* Nothing too exciting at the moment
*/
ENTRY(cpu_xsc3_proc_init)
mov pc, lr
/*
* cpu_xsc3_proc_fin()
*/
ENTRY(cpu_xsc3_proc_fin)
str lr, [sp, #-4]!
mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
msr cpsr_c, r0
bl xsc3_flush_kern_cache_all @ clean caches
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1800 @ ...IZ...........
bic r0, r0, #0x0006 @ .............CA.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ldr pc, [sp], #4
/*
* cpu_xsc3_reset(loc)
*
* Perform a soft reset of the system. Put the CPU into the
* same state as it would be if it had been reset, and branch
* to what would be the reset vector.
*
* loc: location to jump to for soft reset
*/
.align 5
ENTRY(cpu_xsc3_reset)
mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
msr cpsr_c, r1 @ reset CPSR
mrc p15, 0, r1, c1, c0, 0 @ ctrl register
bic r1, r1, #0x0086 @ ........B....CA.
bic r1, r1, #0x3900 @ ..VIZ..S........
mcr p15, 0, r1, c1, c0, 0 @ ctrl register
mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB
bic r1, r1, #0x0001 @ ...............M
mcr p15, 0, r1, c1, c0, 0 @ ctrl register
@ CAUTION: MMU turned off from this point. We count on the pipeline
@ already containing those two last instructions to survive.
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
mov pc, r0
/*
* cpu_xsc3_do_idle()
*
* Cause the processor to idle
*
* For now we do nothing but go to idle mode for every case
*
* XScale supports clock switching, but using idle mode support
* allows external hardware to react to system state changes.
MMG: Come back to this one.
*/
.align 5
ENTRY(cpu_xsc3_do_idle)
mov r0, #1
mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE
mov pc, lr
/* ================================= CACHE ================================ */
/*
* flush_user_cache_all()
*
* Invalidate all cache entries in a particular address
* space.
*/
ENTRY(xsc3_flush_user_cache_all)
/* FALLTHROUGH */
/*
* flush_kern_cache_all()
*
* Clean and invalidate the entire cache.
*/
ENTRY(xsc3_flush_kern_cache_all)
mov r2, #VM_EXEC
mov ip, #0
__flush_whole_cache:
clean_d_cache r0, r1
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB
mcrne p15, 0, ip, c7, c10, 4 @ Drain Write Buffer
mcrne p15, 0, ip, c7, c5, 4 @ Prefetch Flush
mov pc, lr
/*
* flush_user_cache_range(start, end, vm_flags)
*
* Invalidate a range of cache entries in the specified
* address space.
*
* - start - start address (may not be aligned)
* - end - end address (exclusive, may not be aligned)
* - vma - vma_area_struct describing address space
*/
.align 5
ENTRY(xsc3_flush_user_cache_range)
mov ip, #0
sub r3, r1, r0 @ calculate total size
cmp r3, #MAX_AREA_SIZE
bhs __flush_whole_cache
1: tst r2, #VM_EXEC
mcrne p15, 0, r0, c7, c5, 1 @ Invalidate I cache line
mcr p15, 0, r0, c7, c14, 1 @ Clean/invalidate D cache line
add r0, r0, #CACHELINESIZE
cmp r0, r1
blo 1b
tst r2, #VM_EXEC
mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB
mcrne p15, 0, ip, c7, c10, 4 @ Drain Write Buffer
mcrne p15, 0, ip, c7, c5, 4 @ Prefetch Flush
mov pc, lr
/*
* coherent_kern_range(start, end)
*
* Ensure coherency between the Icache and the Dcache in the
* region described by start. If you have non-snooping
* Harvard caches, you need to implement this function.
*
* - start - virtual start address
* - end - virtual end address
*
* Note: single I-cache line invalidation isn't used here since
* it also trashes the mini I-cache used by JTAG debuggers.
*/
ENTRY(xsc3_coherent_kern_range)
/* FALLTHROUGH */
ENTRY(xsc3_coherent_user_range)
bic r0, r0, #CACHELINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHELINESIZE
cmp r0, r1
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB
mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer
mcr p15, 0, r0, c7, c5, 4 @ Prefetch Flush
mov pc, lr
/*
* flush_kern_dcache_page(void *page)
*
* Ensure no D cache aliasing occurs, either with itself or
* the I cache
*
* - addr - page aligned address
*/
ENTRY(xsc3_flush_kern_dcache_page)
add r1, r0, #PAGE_SZ
1: mcr p15, 0, r0, c7, c14, 1 @ Clean/Invalidate D Cache line
add r0, r0, #CACHELINESIZE
cmp r0, r1
blo 1b
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB
mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer
mcr p15, 0, r0, c7, c5, 4 @ Prefetch Flush
mov pc, lr
/*
* dma_inv_range(start, end)
*
* Invalidate (discard) the specified virtual address range.
* May not write back any entries. If 'start' or 'end'
* are not cache line aligned, those lines must be written
* back.
*
* - start - virtual start address
* - end - virtual end address
*/
ENTRY(xsc3_dma_inv_range)
tst r0, #CACHELINESIZE - 1
bic r0, r0, #CACHELINESIZE - 1
mcrne p15, 0, r0, c7, c10, 1 @ clean L1 D entry
mcrne p15, 1, r0, c7, c11, 1 @ clean L2 D entry
tst r1, #CACHELINESIZE - 1
mcrne p15, 0, r1, c7, c10, 1 @ clean L1 D entry
mcrne p15, 1, r1, c7, c11, 1 @ clean L2 D entry
1: mcr p15, 0, r0, c7, c6, 1 @ invalidate L1 D entry
mcr p15, 1, r0, c7, c7, 1 @ Invalidate L2 D cache line
add r0, r0, #CACHELINESIZE
cmp r0, r1
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer
mov pc, lr
/*
* dma_clean_range(start, end)
*
* Clean the specified virtual address range.
*
* - start - virtual start address
* - end - virtual end address
*/
ENTRY(xsc3_dma_clean_range)
bic r0, r0, #CACHELINESIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D entry
mcr p15, 1, r0, c7, c11, 1 @ clean L2 D entry
add r0, r0, #CACHELINESIZE
cmp r0, r1
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer
mov pc, lr
/*
* dma_flush_range(start, end)
*
* Clean and invalidate the specified virtual address range.
*
* - start - virtual start address
* - end - virtual end address
*/
ENTRY(xsc3_dma_flush_range)
bic r0, r0, #CACHELINESIZE - 1
1: mcr p15, 0, r0, c7, c14, 1 @ Clean/invalidate L1 D cache line
mcr p15, 1, r0, c7, c11, 1 @ Clean L2 D cache line
mcr p15, 1, r0, c7, c7, 1 @ Invalidate L2 D cache line
add r0, r0, #CACHELINESIZE
cmp r0, r1
blo 1b
mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer
mov pc, lr
ENTRY(xsc3_cache_fns)
.long xsc3_flush_kern_cache_all
.long xsc3_flush_user_cache_all
.long xsc3_flush_user_cache_range
.long xsc3_coherent_kern_range
.long xsc3_coherent_user_range
.long xsc3_flush_kern_dcache_page
.long xsc3_dma_inv_range
.long xsc3_dma_clean_range
.long xsc3_dma_flush_range
ENTRY(cpu_xsc3_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #CACHELINESIZE
subs r1, r1, #CACHELINESIZE
bhi 1b
mov pc, lr
/* =============================== PageTable ============================== */
/*
* cpu_xsc3_switch_mm(pgd)
*
* Set the translation base pointer to be as described by pgd.
*
* pgd: new page tables
*/
.align 5
ENTRY(cpu_xsc3_switch_mm)
clean_d_cache r1, r2
mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB
mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer
mcr p15, 0, ip, c7, c5, 4 @ Prefetch Flush
#ifdef L2_CACHE_ENABLE
orr r0, r0, #0x18 @ cache the page table in L2
#endif
mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
cpwait_ret lr, ip
/*
* cpu_xsc3_set_pte(ptep, pte)
*
* Set a PTE and flush it out
*
*/
.align 5
ENTRY(cpu_xsc3_set_pte)
str r1, [r0], #-2048 @ linux version
bic r2, r1, #0xff0
orr r2, r2, #PTE_TYPE_EXT @ extended page
eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
tst r3, #L_PTE_USER @ User?
orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w
tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w
@ combined with user -> user r/w
#if L2_CACHE_ENABLE
@ If its cacheable it needs to be in L2 also.
eor ip, r1, #L_PTE_CACHEABLE
tst ip, #L_PTE_CACHEABLE
orreq r2, r2, #PTE_EXT_TEX(0x5)
#endif
tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
movne r2, #0 @ no -> fault
str r2, [r0] @ hardware version
mov ip, #0
mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line mcr
mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer
mov pc, lr
.ltorg
.align
__INIT
.type __xsc3_setup, #function
__xsc3_setup:
mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
msr cpsr_c, r0
mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB
mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer
mcr p15, 0, ip, c7, c5, 4 @ Prefetch Flush
mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs
#if L2_CACHE_ENABLE
orr r4, r4, #0x18 @ cache the page table in L2
#endif
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
mov r0, #1 @ Allow access to CP0 and CP13
orr r0, r0, #1 << 13 @ Its undefined whether this
mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes
mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg
and r0, r0, #2 @ preserve bit P bit setting
#if L2_CACHE_ENABLE
orr r0, r0, #(1 << 10) @ enable L2 for LLR cache
#endif
mcr p15, 0, r0, c1, c0, 1 @ set auxiliary control reg
mrc p15, 0, r0, c1, c0, 0 @ get control register
bic r0, r0, #0x0200 @ .... ..R. .... ....
bic r0, r0, #0x0002 @ .... .... .... ..A.
orr r0, r0, #0x0005 @ .... .... .... .C.M
#if BTB_ENABLE
orr r0, r0, #0x3900 @ ..VI Z..S .... ....
#else
orr r0, r0, #0x3100 @ ..VI ...S .... ....
#endif
#if L2_CACHE_ENABLE
orr r0, r0, #0x4000000 @ L2 enable
#endif
mov pc, lr
.size __xsc3_setup, . - __xsc3_setup
__INITDATA
/*
* Purpose : Function pointers used to access above functions - all calls
* come through these
*/
.type xsc3_processor_functions, #object
ENTRY(xsc3_processor_functions)
.word v5t_early_abort
.word cpu_xsc3_proc_init
.word cpu_xsc3_proc_fin
.word cpu_xsc3_reset
.word cpu_xsc3_do_idle
.word cpu_xsc3_dcache_clean_area
.word cpu_xsc3_switch_mm
.word cpu_xsc3_set_pte
.size xsc3_processor_functions, . - xsc3_processor_functions
.section ".rodata"
.type cpu_arch_name, #object
cpu_arch_name:
.asciz "armv5te"
.size cpu_arch_name, . - cpu_arch_name
.type cpu_elf_name, #object
cpu_elf_name:
.asciz "v5"
.size cpu_elf_name, . - cpu_elf_name
.type cpu_xsc3_name, #object
cpu_xsc3_name:
.asciz "XScale-Core3"
.size cpu_xsc3_name, . - cpu_xsc3_name
.align
.section ".proc.info.init", #alloc, #execinstr
.type __xsc3_proc_info,#object
__xsc3_proc_info:
.long 0x69056000
.long 0xffffe000
.long 0x00000c0e
b __xsc3_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
.long cpu_xsc3_name
.long xsc3_processor_functions
.long v4wbi_tlb_fns
.long xsc3_mc_user_fns
.long xsc3_cache_fns
.size __xsc3_proc_info, . - __xsc3_proc_info
......@@ -15,7 +15,7 @@
#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
static void putstr( const char *s )
static void putc(int c)
{
unsigned long serial_port;
do {
......@@ -28,17 +28,16 @@ static void putstr( const char *s )
return;
} while (0);
for (; *s; s++) {
/* wait for space in the UART's transmitter */
while ((UART(UART_SR) & UART_SR_TxFF));
/* send the character out. */
UART(UART_DR) = *s;
/* if a LF, also do CR... */
if (*s == 10) {
while ((UART(UART_SR) & UART_SR_TxFF));
UART(UART_DR) = 13;
}
}
/* wait for space in the UART's transmitter */
while ((UART(UART_SR) & UART_SR_TxFF))
barrier();
/* send the character out. */
UART(UART_DR) = c;
}
static inline void flush(void)
{
}
#define arch_decomp_setup()
......
......@@ -31,21 +31,22 @@
*
* This does not append a newline
*/
static void putstr(const char *s)
static void putc(int c)
{
void __iomem *sys = (void __iomem *) AT91_BASE_SYS; /* physical address */
while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXRDY))
barrier();
__raw_writel(c, sys + AT91_DBGU_THR);
}
static inline void flush(void)
{
void __iomem *sys = (void __iomem *) AT91_BASE_SYS; /* physical address */
while (*s) {
while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXRDY)) { barrier(); }
__raw_writel(*s, sys + AT91_DBGU_THR);
if (*s == '\n') {
while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXRDY)) { barrier(); }
__raw_writel('\r', sys + AT91_DBGU_THR);
}
s++;
}
/* wait for transmission to complete */
while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXEMPTY)) { barrier(); }
while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXEMPTY))
barrier();
}
#define arch_decomp_setup()
......
......@@ -3,27 +3,19 @@
*
* Copyright (C) 1999, 2000 Nexus Electronics Ltd.
*/
#define BASE 0x03010000
#define SERBASE (BASE + (0x2f8 << 2))
static __inline__ void putc(char c)
static inline void putc(char c)
{
while (!(*((volatile unsigned int *)(SERBASE + 0x14)) & 0x20));
while (!(*((volatile unsigned int *)(SERBASE + 0x14)) & 0x20))
barrier();
*((volatile unsigned int *)(SERBASE)) = c;
}
/*
* This does not append a newline
*/
static void putstr(const char *s)
static inline void flush(void)
{
while (*s) {
putc(*s);
if (*s == '\n')
putc('\r');
s++;
}
}
static __inline__ void arch_decomp_setup(void)
......
......@@ -25,7 +25,6 @@
#undef CLPS7111_BASE
#define CLPS7111_BASE CLPS7111_PHYS_BASE
#define barrier() __asm__ __volatile__("": : :"memory")
#define __raw_readl(p) (*(unsigned long *)(p))
#define __raw_writel(v,p) (*(unsigned long *)(p) = (v))
......@@ -40,21 +39,15 @@
/*
* This does not append a newline
*/
static void putstr(const char *s)
static inline void putc(int c)
{
char c;
while ((c = *s++) != '\0') {
while (clps_readl(SYSFLGx) & SYSFLG_UTXFF)
barrier();
clps_writel(c, UARTDRx);
while (clps_readl(SYSFLGx) & SYSFLG_UTXFF)
barrier();
clps_writel(c, UARTDRx);
}
if (c == '\n') {
while (clps_readl(SYSFLGx) & SYSFLG_UTXFF)
barrier();
clps_writel('\r', UARTDRx);
}
}
static inline void flush(void)
{
while (clps_readl(SYSFLGx) & SYSFLG_UBUSY)
barrier();
}
......
......@@ -8,33 +8,34 @@
* published by the Free Software Foundation.
*/
#include <linux/serial_reg.h>
#define SERIAL_BASE ((unsigned char *)0xfe000be0)
/*
* This does not append a newline
*/
static void putstr(const char *s)
static inline void putc(int c)
{
unsigned char v, *base = SERIAL_BASE;
do {
v = base[UART_LSR << 2];
barrier();
} while (!(v & UART_LSR_THRE));
base[UART_TX << 2] = c;
}
static inline void flush(void)
{
unsigned long tmp1, tmp2;
__asm__ __volatile__(
"ldrb %0, [%2], #1\n"
" teq %0, #0\n"
" beq 3f\n"
"1: strb %0, [%3]\n"
"2: ldrb %1, [%3, #0x14]\n"
" and %1, %1, #0x60\n"
" teq %1, #0x60\n"
" bne 2b\n"
" teq %0, #'\n'\n"
" moveq %0, #'\r'\n"
" beq 1b\n"
" ldrb %0, [%2], #1\n"
" teq %0, #0\n"
" bne 1b\n"
"3: ldrb %1, [%3, #0x14]\n"
" and %1, %1, #0x60\n"
" teq %1, #0x60\n"
" bne 3b"
: "=&r" (tmp1), "=&r" (tmp2)
: "r" (s), "r" (0xf0000be0) : "cc");
unsigned char v, *base = SERIAL_BASE;
do {
v = base[UART_LSR << 2];
barrier();
} while ((v & (UART_LSR_TEMT|UART_LSR_THRE)) !=
(UART_LSR_TEMT|UART_LSR_THRE));
}
/*
......
......@@ -15,10 +15,11 @@
#define DC21285_BASE ((volatile unsigned int *)0x42000160)
#define SER0_BASE ((volatile unsigned char *)0x7c0003f8)
static __inline__ void putc(char c)
static inline void putc(char c)
{
if (machine_is_netwinder()) {
while ((SER0_BASE[5] & 0x60) != 0x60);
while ((SER0_BASE[5] & 0x60) != 0x60)
barrier();
SER0_BASE[0] = c;
} else {
while (DC21285_BASE[6] & 8);
......@@ -26,17 +27,8 @@ static __inline__ void putc(char c)
}
}
/*
* This does not append a newline
*/
static void putstr(const char *s)
static inline void flush(void)
{
while (*s) {
putc(*s);
if (*s == '\n')
putc('\r');
s++;
}
}
/*
......
......@@ -16,17 +16,27 @@ static unsigned char __raw_readb(unsigned int ptr)
return *((volatile unsigned char *)ptr);
}
static unsigned int __raw_readl(unsigned int ptr)
{
return *((volatile unsigned int *)ptr);
}
static void __raw_writeb(unsigned char value, unsigned int ptr)
{
*((volatile unsigned char *)ptr) = value;
}
static void __raw_writel(unsigned int value, unsigned int ptr)
{
*((volatile unsigned int *)ptr) = value;
}
#define PHYS_UART1_DATA 0x808c0000
#define PHYS_UART1_FLAG 0x808c0018
#define UART1_FLAG_TXFF 0x20
static __inline__ void putc(char c)
static inline void putc(int c)
{
int i;
......@@ -39,15 +49,37 @@ static __inline__ void putc(char c)
__raw_writeb(c, PHYS_UART1_DATA);
}
static void putstr(const char *s)
static inline void flush(void)
{
while (*s) {
putc(*s);
if (*s == '\n')
putc('\r');
s++;
}
}
#define arch_decomp_setup()
/*
* Some bootloaders don't turn off DMA from the ethernet MAC before
* jumping to linux, which means that we might end up with bits of RX
* status and packet data scribbled over the uncompressed kernel image.
* Work around this by resetting the ethernet MAC before we uncompress.
*/
#define PHYS_ETH_SELF_CTL 0x80010020
#define ETH_SELF_CTL_RESET 0x00000001
static void ethernet_reset(void)
{
unsigned int v;
/* Reset the ethernet MAC. */
v = __raw_readl(PHYS_ETH_SELF_CTL);
__raw_writel(v | ETH_SELF_CTL_RESET, PHYS_ETH_SELF_CTL);
/* Wait for reset to finish. */
while (__raw_readl(PHYS_ETH_SELF_CTL) & ETH_SELF_CTL_RESET)
;
}
static void arch_decomp_setup(void)
{
ethernet_reset();
}
#define arch_decomp_wdog()
......@@ -12,22 +12,20 @@
#define LSR 0x14
#define TEMPTY 0x40
static void putstr(const char *s)
static inline void putc(int c)
{
char c;
volatile unsigned char *p = (volatile unsigned char *)(IO_PHYS+0x20000);
while ( (c = *s++) != '\0') {
/* wait until transmit buffer is empty */
while((p[LSR] & TEMPTY) == 0x0);
/* write next character */
*p = c;
if(c == '\n') {
while((p[LSR] & TEMPTY) == 0x0);
*p = '\r';
}
}
/* wait until transmit buffer is empty */
while((p[LSR] & TEMPTY) == 0x0)
barrier();
/* write next character */
*p = c;
}
static inline void flush(void)
{
}
/*
......
......@@ -39,8 +39,7 @@
*
* This does not append a newline
*/
static void
putstr(const char *s)
static void putc(int c)
{
unsigned long serial_port;
......@@ -54,20 +53,14 @@ putstr(const char *s)
return;
} while(0);
while (*s) {
while ( !(UART(USR2) & USR2_TXFE) )
barrier();
while (!(UART(USR2) & USR2_TXFE))
barrier();
UART(TXR) = *s;
if (*s == '\n') {
while ( !(UART(USR2) & USR2_TXFE) )
barrier();
UART(TXR) = c;
}
UART(TXR) = '\r';
}
s++;
}
static inline void flush(void)
{
}
/*
......
......@@ -28,21 +28,18 @@
/*
* This does not append a newline
*/
static void putstr(const char *s)
static void putc(int c)
{
while (*s) {
while (AMBA_UART_FR & (1 << 5));
while (AMBA_UART_FR & (1 << 5))
barrier();
AMBA_UART_DR = *s;
if (*s == '\n') {
while (AMBA_UART_FR & (1 << 5));
AMBA_UART_DR = c;
}
AMBA_UART_DR = '\r';
}
s++;
}
while (AMBA_UART_FR & (1 << 3));
static inline void flush(void)
{
while (AMBA_UART_FR & (1 << 3))
barrier();
}
/*
......
......@@ -19,23 +19,15 @@ static volatile UTYPE uart_base;
#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
static __inline__ void putc(char c)
static inline void putc(char c)
{
while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE);
while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
barrier();
*uart_base = c;
}
/*
* This does not append a newline
*/
static void putstr(const char *s)
static inline void flush(void)
{
while (*s) {
putc(*s);
if (*s == '\n')
putc('\r');
s++;
}
}
static __inline__ void __arch_decomp_setup(unsigned long arch_id)
......
......@@ -29,23 +29,18 @@
#define UARTSR PHYS(0x14) /* Status reg */
static __inline__ void putc(char c)
static inline void putc(int c)
{
int j = 0x1000;
while (--j && !(*UARTSR & UART_LSR_THRE));
while (--j && !(*UARTSR & UART_LSR_THRE))
barrier();
*UARTDR = c;
}
static void putstr(const char *s)
static inline void flush(void)
{
while (*s)
{
putc(*s);
if (*s == '\n')
putc('\r');
s++;
}
}
#define arch_decomp_setup()
......
/*
* include/asm-arm/arch-ixp23xx/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 <asm/arch/ixp23xx.h>
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ mmu enabled?
ldreq \rx, =IXP23XX_PERIPHERAL_PHYS @ physical
ldrne \rx, =IXP23XX_PERIPHERAL_VIRT @ virtual
.endm
#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>
/*
* include/asm-arm/arch-ixp23xx/dma.h
*/
/*
* include/asm-arm/arch-ixp23xx/entry-macro.S
*/
.macro disable_fiq
.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 @ suprious 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
/*
* include/asm-arm/arch-ixp23xx/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 */
#define PCIO_BASE IXP23XX_PCI_IO_VIRT
#define PCIBIOS_MIN_IO 0x00000000
#define PCIBIOS_MIN_MEM 0xe0000000
#include "ixp23xx.h"
#define pcibios_assign_all_busses() 0
/*
* Platform helper functions
*/
#include "platform.h"
/*
* Platform-specific headers
*/
#include "ixdp2351.h"
#endif
/*
* include/asm-arm/arch-ixp23xx/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))
#define __mem_pci(a) (a)
#include <linux/kernel.h> /* For BUG */
static inline void __iomem *
ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned long flags)
{
if (addr >= IXP23XX_PCI_MEM_START &&
addr <= IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE) {
if (addr + size > IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE)
return NULL;
return (void __iomem *)
((addr - IXP23XX_PCI_MEM_START) + IXP23XX_PCI_MEM_VIRT);
}
return __ioremap(addr, size, flags);
}
static inline void
ixp23xx_iounmap(void __iomem *addr)
{
if ((((u32)addr) >= IXP23XX_PCI_MEM_VIRT) &&
(((u32)addr) < IXP23XX_PCI_MEM_VIRT + IXP23XX_PCI_MEM_SIZE))
return;
__iounmap(addr);
}
#define __arch_ioremap(a,s,f) ixp23xx_ioremap(a,s,f)
#define __arch_iounmap(a) ixp23xx_iounmap(a)
#endif
/*
* include/asm-arm/arch-ixp23xx/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
/*
* include/asm-arm/arch-ixp23xx/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 IXDP3251_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
此差异已折叠。
/*
* include/asm-arm/arch-ixp23xx/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 <asm/hardware.h>
/*
* Physical DRAM offset.
*/
#define PHYS_OFFSET (0x00000000)
/*
* Virtual view <-> DMA view memory address translations
* virt_to_bus: Used to translate the virtual address to an
* address suitable to be passed to set_dma_addr
* bus_to_virt: Used to convert an address for DMA operations
* to an address that the kernel can use.
*/
#ifndef __ASSEMBLY__
#define __virt_to_bus(v) \
({ unsigned int ret; \
ret = ((__virt_to_phys(v) - 0x00000000) + \
(*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)); \
ret; })
#define __bus_to_virt(b) \
({ unsigned int data; \
data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR); \
__phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); })
#endif
#endif
/*
* include/asm-arm/arch-ixp23xx/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__
struct pci_sys_data;
void ixp23xx_map_io(void);
void ixp23xx_init_irq(void);
void ixp23xx_sys_init(void);
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*);
extern struct sys_timer ixp23xx_timer;
#define IXP23XX_UART_XTAL 14745600
#endif
/*
* include/asm-arm/arch-ixp23xx/system.h
*
* Copyright (C) 2003 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/hardware.h>
#include <asm/mach-types.h>
static inline void arch_idle(void)
{
#if 0
if (!hlt_counter)
cpu_do_idle();
#endif
}
static inline void arch_reset(char mode)
{
/* First try machine specific support */
if (machine_is_ixdp2351()) {
*IXDP2351_CPLD_RESET1_REG = IXDP2351_CPLD_RESET1_MAGIC;
(void) *IXDP2351_CPLD_RESET1_REG;
*IXDP2351_CPLD_RESET1_REG = IXDP2351_CPLD_RESET1_ENABLE;
}
/* Use on-chip reset capability */
*IXP23XX_RESET0 |= IXP23XX_RST_ALL;
}
/*
* include/asm-arm/arch-ixp23xx/time.h
*/
/*
* include/asm-arm/arch-ixp23xx/timex.h
*
* XScale architecture timex specifications
*/
#define CLOCK_TICK_RATE 75000000
/*
* include/asm-arm/arch-ixp23xx/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 <asm/hardware.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;
}
UART_BASE[UART_TX] = c;
}
static void putstr(const char *s)
{
while (*s) {
putc(*s);
if (*s == '\n')
putc('\r');
s++;
}
}
#define arch_decomp_setup()
#define arch_decomp_wdog()
#endif
/*
* include/asm-arm/arch-ixp23xx/vmalloc.h
*
* Copyright (c) 2005 MontaVista Software, Inc.
*
* NPU mappings end at 0xf0000000 and we allocate 64MB for board
* specific static I/O.
*/
#define VMALLOC_END (0xec000000)
......@@ -21,26 +21,18 @@
static volatile u32* uart_base;
static __inline__ void putc(char c)
static inline void putc(int c)
{
/* Check THRE and TEMT bits before we transmit the character.
*/
while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE);
while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
barrier();
*uart_base = c;
}
/*
* This does not append a newline
*/
static void putstr(const char *s)
static void flush(void)
{
while (*s)
{
putc(*s);
if (*s == '\n')
putc('\r');
s++;
}
}
static __inline__ void __arch_decomp_setup(unsigned long arch_id)
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册