Commit f270bc9e authored by Eli Carter's avatar Eli Carter Committed by Russell King

[ARM PATCH] 1503/1: Adds basic support for the iq80321 board

Patch from Eli Carter

# Tue Apr 15 16:07:34 CDT 2003 ejc@rnd-linux-c84
# add-iq80321
#
# Adds basic support for the iq80321 board.
#
# Diff'ed against 2.5.65-rmk1+1472-4+1502
# Applies to 2.5.67-rmk1+1502 with offsets
#
#  arch/arm/boot/Makefile                    |    1
#  arch/arm/boot/compressed/head-xscale.S    |    6
#  arch/arm/def-configs/iq80321              |  676 ++++++++++++++++++++++++++++++
#  arch/arm/kernel/debug.S                   |   10
#  arch/arm/kernel/entry-armv.S              |   22
#  arch/arm/mach-iop3xx/Kconfig              |   12
#  arch/arm/mach-iop3xx/Makefile             |   16
#  arch/arm/mach-iop3xx/arch.c               |   26 +
#  arch/arm/mach-iop3xx/iop321-irq.c         |   95 ++++
#  arch/arm/mach-iop3xx/iop321-pci.c         |  257 +++++++++++
#  arch/arm/mach-iop3xx/iop321-time.c        |   92 ++++
#  arch/arm/mach-iop3xx/iq80321-pci.c        |   98 ++++
#  arch/arm/mach-iop3xx/mm-321.c             |   64 ++
#  arch/arm/mm/proc-xscale.S                 |   19
#  include/asm-arm/arch-iop3xx/hardware.h    |   17
#  include/asm-arm/arch-iop3xx/iop321-irqs.h |   83 +++
#  include/asm-arm/arch-iop3xx/iop321.h      |  143 ++++++
#  include/asm-arm/arch-iop3xx/iq80321.h     |   17
#  include/asm-arm/arch-iop3xx/irqs.h        |   67 --
#  include/asm-arm/arch-iop3xx/memory.h      |   11
#  include/asm-arm/arch-iop3xx/serial.h      |   11
#  include/asm-arm/arch-iop3xx/timex.h       |    6
#  include/asm-arm/arch-iop3xx/uncompress.h  |    7
#  include/asm-arm/mach/pci.h                |    4
#  24 files changed, 1691 insertions(+), 69 deletions(-)
parent 22f50b5a
......@@ -45,6 +45,7 @@ endif
zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000
zreladdr-$(CONFIG_ARCH_ANAKIN) := 0x20008000
zreladdr-$(CONFIG_ARCH_IQ80310) := 0xa0008000
zreladdr-$(CONFIG_ARCH_IQ80321) := 0xa0008000
zreladdr-$(CONFIG_ARCH_ADIFCC) := 0xc0008000
ZRELADDR := $(zreladdr-y)
......
......@@ -34,6 +34,12 @@ __XScale_start:
bic r0, r0, #0x1000 @ clear Icache
mcr p15, 0, r0, c1, c0, 0
#ifdef CONFIG_ARCH_IQ80321
orr pc, pc, #0xa0000000
nop
mov r7, #MACH_TYPE_IQ80321
#endif
#ifdef CONFIG_ARCH_LUBBOCK
mov r7, #MACH_TYPE_LUBBOCK
#endif
......
This diff is collapsed.
......@@ -414,7 +414,13 @@
.macro addruart,rx
mov \rx, #0xfe000000 @ physical
orr \rx, \rx, #0x00810000
#ifdef CONFIG_ARCH_IQ80310
orr \rx, \rx, #0x00810000 @ location of the UART
#elif defined(CONFIG_ARCH_IQ80321)
orr \rx, \rx, #0x00800000 @ location of the UART
#else
#error Unknown IOP3XX implementation
#endif
.endm
.macro senduart,rd,rx
......@@ -429,9 +435,11 @@
.endm
.macro waituart,rd,rx
#ifndef CONFIG_ARCH_IQ80321
1001: ldrb \rd, [\rx, #0x6]
tst \rd, #0x10
beq 1001b
#endif
.endm
#elif defined(CONFIG_ARCH_ADI_EVB)
......
......@@ -584,6 +584,28 @@ ENTRY(anakin_active_irqs)
.macro irq_prio_table
.endm
#elif defined(CONFIG_ARCH_IOP321)
.macro disable_fiq
.endm
/*
* Note: only deal with normal interrupts, not FIQ
*/
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \irqnr, #0
mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC
cmp \irqstat, #0
beq 1001f
clz \irqnr, \irqstat
mov \base, #31
subs \irqnr,\base,\irqnr
add \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT
1001:
.endm
.macro irq_prio_table
.endm
#elif defined(CONFIG_ARCH_PXA)
.macro disable_fiq
......
......@@ -12,6 +12,12 @@ config ARCH_IQ80310
Say Y here if you want to run your kernel on the Intel IQ80310
evaluation kit for the IOP310 chipset.
config ARCH_IQ80321
bool "IQ80321"
depends on ARCH_IOP3XX
help
Say Y here if you want to run your kernel on the Intel IQ80321
evaluation kit for the IOP321 chipset.
endchoice
# Which IOP variant are we running?
......@@ -21,6 +27,12 @@ config ARCH_IOP310
help
The IQ80310 uses the IOP310 variant.
config ARCH_IOP321
bool
default ARCH_IQ80321
help
The IQ80321 uses the IOP321 variant.
comment "IOP3xx Chipset Features"
config IOP3XX_AAU
......
......@@ -4,16 +4,24 @@
# Object file lists.
obj-y := arch.o mm.o xs80200-irq.o iop310-irq.o \
iop310-pci.o
obj-y := arch.o
obj-m :=
obj-n :=
obj- :=
obj-$(CONFIG_ARCH_IOP310) += xs80200-irq.o iop310-irq.o iop310-pci.o mm.o
obj-$(CONFIG_ARCH_IQ80310) += iq80310-pci.o iq80310-irq.o
ifneq ($(CONFIG_XSCALE_PMU_TIMER),y)
obj-y += iq80310-time.o
obj-$(CONFIG_ARCH_IOP321) += iop321-irq.o iop321-pci.o mm-321.o iop321-time.o
obj-$(CONFIG_ARCH_IQ80321) += iq80321-pci.o
ifeq ($(CONFIG_ARCH_IQ80310),y)
ifneq ($(CONFIG_XSCALE_PMU_TIMER),y)
obj-y += iq80310-time.o
endif
endif
obj-$(CONFIG_IOP3XX_AAU) += aau.o
......
......@@ -24,7 +24,14 @@
#ifdef CONFIG_ARCH_IQ80310
extern void iq80310_map_io(void);
extern void iq80310_init_irq(void);
#endif
#ifdef CONFIG_ARCH_IQ80321
extern void iq80321_map_io(void);
extern void iop321_init_irq(void);
#endif
#ifdef CONFIG_ARCH_IQ80310
static void __init
fixup_iq80310(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
......@@ -34,7 +41,17 @@ fixup_iq80310(struct machine_desc *desc, struct tag *tags,
if (system_rev)
system_rev = 0xF;
}
#endif
#ifdef CONFIG_ARCH_IQ80321
static void __init
fixup_iop321(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
{
}
#endif
#ifdef CONFIG_ARCH_IQ80310
MACHINE_START(IQ80310, "Cyclone IQ80310")
MAINTAINER("MontaVista Software Inc.")
BOOT_MEM(0xa0000000, 0xfe000000, 0xfe000000)
......@@ -43,6 +60,15 @@ MACHINE_START(IQ80310, "Cyclone IQ80310")
INITIRQ(iq80310_init_irq)
MACHINE_END
#elif defined(CONFIG_ARCH_IQ80321)
MACHINE_START(IQ80321, "Intel IQ80321")
MAINTAINER("MontaVista Software, Inc.")
BOOT_MEM(PHYS_OFFSET, IQ80321_UART1, 0xfe800000)
FIXUP(fixup_iop321)
MAPIO(iq80321_map_io)
INITIRQ(iop321_init_irq)
MACHINE_END
#else
#error No machine descriptor defined for this IOP310 implementation
#endif
/*
* linux/arch/arm/mach-iop3xx/iop321-irq.c
*
* Generic IOP321 IRQ handling functionality
*
* Author: Rory Bolt <rorybolt@pacbell.net>
* Copyright (C) 2002 Rory Bolt
*
* 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.
*
* Added IOP3XX chipset and IQ80321 board masking code.
*
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <asm/mach/irq.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
static u32 iop321_mask /* = 0 */;
static inline void intctl_write(u32 val)
{
asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val));
}
static inline void intstr_write(u32 val)
{
asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val));
}
static void
iop321_irq_mask (unsigned int irq)
{
iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS));
intctl_write(iop321_mask);
}
static void
iop321_irq_unmask (unsigned int irq)
{
iop321_mask |= (1 << (irq - IOP321_IRQ_OFS));
intctl_write(iop321_mask);
}
struct irqchip ext_chip = {
.ack = iop321_irq_mask,
.mask = iop321_irq_mask,
.unmask = iop321_irq_unmask,
};
void __init iop321_init_irq(void)
{
unsigned int i, tmp;
/* Enable access to coprocessor 6 for dealing with IRQs.
* From RMK:
* Basically, the Intel documentation here is poor. It appears that
* you need to set the bit to be able to access the coprocessor from
* SVC mode. Whether that allows access from user space or not is
* unclear.
*/
asm volatile (
"mrc p15, 0, %0, c15, c1, 0\n\t"
"orr %0, %0, %1\n\t"
"mcr p15, 0, %0, c15, c1, 0\n\t"
/* The action is delayed, so we have to do this: */
"mrc p15, 0, %0, c15, c1, 0\n\t"
"mov %0, %0\n\t"
"sub pc, pc, #4"
: "=r" (tmp) : "i" (1 << 6) );
intctl_write(0); // disable all interrupts
intstr_write(0); // treat all as IRQ
if(machine_is_iq80321()) // all interrupts are inputs to chip
*IOP321_PCIIRSR = 0x0f;
for(i = IOP321_IRQ_OFS; i < NR_IOP321_IRQS; i++)
{
set_irq_chip(i, &ext_chip);
set_irq_handler(i, do_level_IRQ);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
}
/*
* arch/arm/mach-iop3xx/iop321-pci.c
*
* PCI support for the Intel IOP321 chipset
*
* Author: Rory Bolt <rorybolt@pacbell.net>
* Copyright (C) 2002 Rory Bolt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/mach/pci.h>
#include <asm/arch/iop321.h>
// #define DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
#else
#define DBG(x...) do { } while (0)
#endif
/*
* This routine builds either a type0 or type1 configuration command. If the
* bus is on the 80321 then a type0 made, else a type1 is created.
*/
static u32 iop321_cfg_address(struct pci_bus *bus, int devfn, int where)
{
struct pci_sys_data *sys = bus->sysdata;
u32 addr;
if (sys->busnr == bus->number)
addr = 1 << (PCI_SLOT(devfn) + 16);
else
addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
addr |= PCI_FUNC(devfn) << 8 | (where & ~3);
return addr;
}
/*
* This routine checks the status of the last configuration cycle. If an error
* was detected it returns a 1, else it returns a 0. The errors being checked
* are parity, master abort, target abort (master and target). These types of
* errors occure during a config cycle where there is no device, like during
* the discovery stage.
*/
static int iop321_pci_status(void)
{
unsigned int status;
int ret = 0;
/*
* Check the status registers.
*/
status = *IOP321_ATUSR;
if (status & 0xf900)
{
DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
*IOP321_ATUSR = status & 0xf900;
ret = 1;
}
status = *IOP321_ATUISR;
if (status & 0x679f)
{
DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
*IOP321_ATUISR = status & 0x679f;
ret = 1;
}
return ret;
}
/*
* Simply write the address register and read the configuration
* data. Note that the 4 nop's ensure that we are able to handle
* a delayed abort (in theory.)
*/
static inline u32 iop321_read(unsigned long addr)
{
u32 val;
__asm__ __volatile__(
"str %1, [%2]\n\t"
"ldr %0, [%3]\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
: "=r" (val)
: "r" (addr), "r" (IOP321_OCCAR), "r" (IOP321_OCCDR));
return val;
}
/*
* The read routines must check the error status of the last configuration
* cycle. If there was an error, the routine returns all hex f's.
*/
static int
iop321_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
unsigned long addr = iop321_cfg_address(bus, devfn, where);
u32 val = iop321_read(addr) >> ((where & 3) * 8);
if( iop321_pci_status() )
val = 0xffffffff;
*value = val;
return PCIBIOS_SUCCESSFUL;
}
static int
iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value)
{
unsigned long addr = iop321_cfg_address(bus, devfn, where);
u32 val;
if (size != 4) {
val = iop321_read(addr);
if (!iop321_pci_status() == 0)
return PCIBIOS_SUCCESSFUL;
where = (where & 3) * 8;
if (size == 1)
val &= ~(0xff << where);
else
val &= ~(0xffff << where);
*IOP321_OCCDR = val | value << where;
} else {
asm volatile(
"str %1, [%2]\n\t"
"str %0, [%3]\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
:
: "r" (value), "r" (addr),
"r" (IOP321_OCCAR), "r" (IOP321_OCCDR));
}
}
static struct pci_ops iop321_ops = {
.read = iop321_read_config,
.write = iop321_write_config,
};
/*
* When a PCI device does not exist during config cycles, the 80200 gets a
* bus error instead of returning 0xffffffff. This handler simply returns.
*/
int
iop321_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
addr, fsr, regs->ARM_pc, regs->ARM_lr);
/*
* 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;
}
/*
* Scan an IOP321 PCI bus. sys->bus defines which bus we scan.
*/
struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *sys)
{
return pci_scan_bus(sys->busnr, &iop321_ops, sys);
}
/*
* Setup the system data for controller 'nr'. Return 0 if none found,
* 1 if found, or negative error.
*/
int iop321_setup(int nr, struct pci_sys_data *sys)
{
struct resource *res;
if (nr >= 1)
return 0;
res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
if (!res)
panic("PCI: unable to alloc resources");
memset(res, 0, sizeof(struct resource) * 2);
switch (nr) {
case 0:
res[0].start = IOP321_PCI_LOWER_IO + 0x6e000000;
res[0].end = IOP321_PCI_LOWER_IO + 0x6e00ffff;
res[0].name = "PCI IO Primary";
res[0].flags = IORESOURCE_IO;
res[1].start = IOP321_PCI_LOWER_MEM;
res[1].end = IOP321_PCI_LOWER_MEM + IOP321_PCI_WINDOW_SIZE;
res[1].name = "PCI Memory Primary";
res[1].flags = IORESOURCE_MEM;
break;
}
request_resource(&ioport_resource, &res[0]);
request_resource(&iomem_resource, &res[1]);
sys->resource[0] = &res[0];
sys->resource[1] = &res[1];
sys->resource[2] = NULL;
sys->io_offset = 0x6e000000;
return 1;
}
void iop321_init(void)
{
DBG("PCI: Intel 80321 PCI init code.\n");
DBG("\tATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD);
DBG("\tATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n",
*IOP321_OMWTVR0,
*IOP321_OIOWTVR);
DBG("\tATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR);
DBG("\tATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n", *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0);
DBG("\tATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n", *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR);
DBG("\tATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n", *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2);
DBG("\tATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n", *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3);
hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort");
}
/*
* arch/arm/mach-iop3xx/iop321-time.c
*
* Timer code for IOP321 based systems
*
* Author: Deepak Saxena <dsaxena@mvista.com>
*
* Copyright 2002 MontaVista Software Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/timex.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/mach-types.h>
#include <asm/mach/irq.h>
static unsigned long iop321_gettimeoffset(void)
{
unsigned long elapsed, usec;
/*
* FIXME: Implement what is described in this comment.
*
* If an interrupt was pending before we read the timer,
* we've already wrapped. Factor this into the time.
* If an interrupt was pending after we read the timer,
* it may have wrapped between checking the interrupt
* status and reading the timer. Re-read the timer to
* be sure its value is after the wrap.
*/
elapsed = *IOP321_TU_TCR0;
/*
* Now convert them to usec.
*/
usec = (unsigned long)((LATCH - elapsed) * (tick_nsec / 1000)) / LATCH;
return usec;
}
static void iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
u32 tisr;
asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr));
tisr |= 1;
asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr));
do_timer(regs);
}
extern unsigned long (*gettimeoffset)(void);
static struct irqaction timer_irq = {
.name = "timer",
.handler = iop321_timer_interrupt,
};
extern int setup_arm_irq(int, struct irqaction*);
void __init time_init(void)
{
u32 timer_ctl;
u32 latch = LATCH;
gettimeoffset = iop321_gettimeoffset;
setup_irq(IRQ_IOP321_TIMER0, &timer_irq);
timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD |
IOP321_TMR_RATIO_1_1;
asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH));
asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl));
}
/*
* arch/arm/mach-iop3xx/iq80321-pci.c
*
* PCI support for the Intel IQ80321 reference board
*
* Author: Rory Bolt <rorybolt@pacbell.net>
* Copyright (C) 2002 Rory Bolt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
/*
* The following macro is used to lookup irqs in a standard table
* format for those systems that do not already have PCI
* interrupts properly routed. We assume 1 <= pin <= 4
*/
#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \
({ int _ctl_ = -1; \
unsigned int _idsel = idsel - minid; \
if (_idsel <= maxid) \
_ctl_ = pci_irq_table[_idsel][pin-1]; \
_ctl_; })
#define INTA IRQ_IQ80321_INTA
#define INTB IRQ_IQ80321_INTB
#define INTC IRQ_IQ80321_INTC
#define INTD IRQ_IQ80321_INTD
#define INTE IRQ_IQ80321_I82544
typedef u8 irq_table[4];
static irq_table pci_irq_table[] = {
/*
* PCI IDSEL/INTPIN->INTLINE
* A B C D
*/
{INTE, INTE, INTE, INTE}, /* Gig-E */
{INTD, INTC, INTD, INTA}, /* Unused */
{INTC, INTD, INTA, INTB}, /* PCI-X Slot */
};
static inline int __init
iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
{
BUG_ON(pin < 1 || pin > 4);
return PCI_IRQ_TABLE_LOOKUP(2, 3);
}
static int iq80321_setup(int nr, struct pci_sys_data *sys)
{
switch (nr) {
case 0:
sys->map_irq = iq80321_map_irq;
break;
default:
return 0;
}
return iop321_setup(nr, sys);
}
static void iq80321_preinit(void)
{
iop321_init();
}
static struct hw_pci iq80321_pci __initdata = {
.swizzle = pci_std_swizzle,
.nr_controllers = 1,
.setup = iq80321_setup,
.scan = iop321_scan_bus,
.preinit = iq80321_preinit,
};
static int __init iq80321_pci_init(void)
{
if (machine_is_iq80321())
pci_common_init(&iq80321_pci);
return 0;
}
subsys_initcall(iq80321_pci_init);
/*
* linux/arch/arm/mach-iop3xx/mm.c
*
* Low level memory intialization for IOP321 based systems
*
* Author: Rory Bolt <rorybolt@pacbell.net>
* Copyright (C) 2002 Rory Bolt
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/mm.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/mach/map.h>
#include <asm/mach-types.h>
/*
* Standard IO mapping for all IOP321 based systems
*/
static struct map_desc iop80321_std_desc[] __initdata = {
/* virtual physical length type */
/* mem mapped registers */
{ 0xfff00000, 0xffffe000, 0x00002000, MT_DEVICE },
/* PCI IO space */
{ 0xfe000000, 0x90000000, 0x00020000, MT_DEVICE }
};
void __init iop321_map_io(void)
{
iotable_init(iop80321_std_desc, ARRAY_SIZE(iop80321_std_desc));
}
/*
* IQ80321 specific IO mappings
*
* We use RedBoot's setup for the onboard devices.
*/
#ifdef CONFIG_ARCH_IQ80321
static struct map_desc iq80321_io_desc[] __initdata = {
/* virtual physical length type */
/* on-board devices */
{ 0xfe800000, 0xfe800000, 0x00100000, MT_DEVICE }
};
void __init iq80321_map_io(void)
{
iop321_map_io();
iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc));
}
#endif // CONFIG_ARCH_IQ80321
......@@ -654,6 +654,9 @@ ENTRY(cpu_xscale_set_pte)
cpu_80200_name:
.asciz "XScale-80200"
cpu_80321_name:
.asciz "XScale-IOP80321"
cpu_pxa250_name:
.asciz "XScale-PXA250"
......@@ -748,6 +751,22 @@ __80200_proc_info:
.long xscale_mc_user_fns
.size __80200_proc_info, . - __80200_proc_info
.type __80321_proc_info,#object
__80321_proc_info:
.long 0x69052420
.long 0xfffffff0
.long 0x00000c0e
b __xscale_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
.long cpu_80321_name
.long xscale_processor_functions
.long v4wbi_tlb_fns
.long xscale_mc_user_fns
.long xscale_cache_fns
.size __80321_proc_info, . - __80321_proc_info
.type __pxa250_proc_info,#object
__pxa250_proc_info:
.long 0x69052100
......
......@@ -20,6 +20,7 @@
#define pcibios_assign_all_busses() 1
#ifdef CONFIG_ARCH_IOP310
/*
* these are the values for the secondary PCI bus on the 80312 chip. I will
* have to do some fixup in the bus/dev fixup code
......@@ -34,5 +35,21 @@
#if defined(CONFIG_ARCH_IQ80310)
#include "iq80310.h"
#endif
#endif
#ifdef CONFIG_ARCH_IOP321
#define PCIBIOS_MIN_IO 0x90000000
#define PCIBIOS_MIN_MEM 0x80000000
#include "iop321.h"
#ifdef CONFIG_ARCH_IQ80321
#include "iq80321.h"
#endif
#endif
#endif /* _ASM_ARCH_HARDWARE_H */
/*
* linux/include/asm-arm/arch-iop3xx/irqs.h
*
* Author: Rory Bolt <rorybolt@pacbell.net>
* Copyright: (C) 2002 Rory Bolt
*
* 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.
*
*/
/*
* IOP80321 chipset interrupts
*/
#define IOP321_IRQ_OFS 0
#define IOP321_IRQ(x) (IOP321_IRQ_OFS + (x))
/*
* On IRQ or FIQ register
*/
#define IRQ_IOP321_DMA0_EOT IOP321_IRQ(0)
#define IRQ_IOP321_DMA0_EOC IOP321_IRQ(1)
#define IRQ_IOP321_DMA1_EOT IOP321_IRQ(2)
#define IRQ_IOP321_DMA1_EOC IOP321_IRQ(3)
#define IRQ_IOP321_RSVD_4 IOP321_IRQ(4)
#define IRQ_IOP321_RSVD_5 IOP321_IRQ(5)
#define IRQ_IOP321_AA_EOT IOP321_IRQ(6)
#define IRQ_IOP321_AA_EOC IOP321_IRQ(7)
#define IRQ_IOP321_CORE_PMON IOP321_IRQ(8)
#define IRQ_IOP321_TIMER0 IOP321_IRQ(9)
#define IRQ_IOP321_TIMER1 IOP321_IRQ(10)
#define IRQ_IOP321_I2C_0 IOP321_IRQ(11)
#define IRQ_IOP321_I2C_1 IOP321_IRQ(12)
#define IRQ_IOP321_MESSAGING IOP321_IRQ(13)
#define IRQ_IOP321_ATU_BIST IOP321_IRQ(14)
#define IRQ_IOP321_PERFMON IOP321_IRQ(15)
#define IRQ_IOP321_CORE_PMU IOP321_IRQ(16)
#define IRQ_IOP321_BIU_ERR IOP321_IRQ(17)
#define IRQ_IOP321_ATU_ERR IOP321_IRQ(18)
#define IRQ_IOP321_MCU_ERR IOP321_IRQ(19)
#define IRQ_IOP321_DMA0_ERR IOP321_IRQ(20)
#define IRQ_IOP321_DMA1_ERR IOP321_IRQ(21)
#define IRQ_IOP321_RSVD_22 IOP321_IRQ(22)
#define IRQ_IOP321_AA_ERR IOP321_IRQ(23)
#define IRQ_IOP321_MSG_ERR IOP321_IRQ(24)
#define IRQ_IOP321_SSP IOP321_IRQ(25)
#define IRQ_IOP321_RSVD_26 IOP321_IRQ(26)
#define IRQ_IOP321_XINT0 IOP321_IRQ(27)
#define IRQ_IOP321_XINT1 IOP321_IRQ(28)
#define IRQ_IOP321_XINT2 IOP321_IRQ(29)
#define IRQ_IOP321_XINT3 IOP321_IRQ(30)
#define IRQ_IOP321_HPI IOP321_IRQ(31)
#define NR_IOP321_IRQS (IOP321_IRQ(31) + 1)
#define NR_IRQS NR_IOP321_IRQS
/*
* Interrupts available on the IQ80321 board
*/
#ifdef CONFIG_ARCH_IQ80321
/*
* On board devices
*/
#define IRQ_IQ80321_I82544 IRQ_IOP321_XINT0
#define IRQ_IQ80321_UART IRQ_IOP321_XINT1
/*
* PCI interrupts
*/
#define IRQ_IQ80321_INTA IRQ_IOP321_XINT0
#define IRQ_IQ80321_INTB IRQ_IOP321_XINT1
#define IRQ_IQ80321_INTC IRQ_IOP321_XINT2
#define IRQ_IQ80321_INTD IRQ_IOP321_XINT3
#endif // CONFIG_ARCH_IQ80321
#define XSCALE_PMU_IRQ IRQ_IOP321_CORE_PMU
/*
* linux/include/asm/arch-iop3xx/iop321.h
*
* Intel IOP321 Chip definitions
*
* Author: Rory Bolt <rorybolt@pacbell.net>
* Copyright (C) 2002 Rory Bolt
*
* 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 _IOP321_HW_H_
#define _IOP321_HW_H_
/*
* IOP321 I/O and Mem space regions for PCI autoconfiguration
*/
#define IOP321_PCI_LOWER_IO 0x90000000
#define IOP321_PCI_UPPER_IO 0x9000ffff
#define IOP321_PCI_LOWER_MEM 0x80000000
#define IOP321_PCI_UPPER_MEM 0x83ffffff
#define IOP321_PCI_WINDOW_SIZE 64 * 0x100000
/*
* IOP321 chipset registers
*/
#define IOP321_VIRT_MEM_BASE 0xfff00000 /* chip virtual mem address*/
#define IOP321_PHY_MEM_BASE 0xffffe000 /* chip physical memory address */
#define IOP321_REG_ADDR(reg) (IOP321_VIRT_MEM_BASE | (reg))
/* Reserved 0x00000000 through 0x000000FF */
/* Address Translation Unit 0x00000100 through 0x000001FF */
#define IOP321_ATUVID (volatile u16 *)IOP321_REG_ADDR(0x00000100)
#define IOP321_ATUDID (volatile u16 *)IOP321_REG_ADDR(0x00000102)
#define IOP321_ATUCMD (volatile u16 *)IOP321_REG_ADDR(0x00000104)
#define IOP321_ATUSR (volatile u16 *)IOP321_REG_ADDR(0x00000106)
#define IOP321_ATURID (volatile u8 *)IOP321_REG_ADDR(0x00000108)
#define IOP321_ATUCCR (volatile u32 *)IOP321_REG_ADDR(0x00000109)
#define IOP321_ATUCLSR (volatile u8 *)IOP321_REG_ADDR(0x0000010C)
#define IOP321_ATULT (volatile u8 *)IOP321_REG_ADDR(0x0000010D)
#define IOP321_ATUHTR (volatile u8 *)IOP321_REG_ADDR(0x0000010E)
#define IOP321_ATUBIST (volatile u8 *)IOP321_REG_ADDR(0x0000010F)
#define IOP321_IABAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000110)
#define IOP321_IAUBAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000114)
#define IOP321_IABAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000118)
#define IOP321_IAUBAR1 (volatile u32 *)IOP321_REG_ADDR(0x0000011C)
#define IOP321_IABAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000120)
#define IOP321_IAUBAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000124)
#define IOP321_ASVIR (volatile u16 *)IOP321_REG_ADDR(0x0000012C)
#define IOP321_ASIR (volatile u16 *)IOP321_REG_ADDR(0x0000012E)
#define IOP321_ERBAR (volatile u32 *)IOP321_REG_ADDR(0x00000130)
/* Reserved 0x00000134 through 0x0000013B */
#define IOP321_ATUILR (volatile u8 *)IOP321_REG_ADDR(0x0000013C)
#define IOP321_ATUIPR (volatile u8 *)IOP321_REG_ADDR(0x0000013D)
#define IOP321_ATUMGNT (volatile u8 *)IOP321_REG_ADDR(0x0000013E)
#define IOP321_ATUMLAT (volatile u8 *)IOP321_REG_ADDR(0x0000013F)
#define IOP321_IALR0 (volatile u32 *)IOP321_REG_ADDR(0x00000140)
#define IOP321_IATVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000144)
#define IOP321_ERLR (volatile u32 *)IOP321_REG_ADDR(0x00000148)
#define IOP321_ERTVR (volatile u32 *)IOP321_REG_ADDR(0x0000014C)
#define IOP321_IALR1 (volatile u32 *)IOP321_REG_ADDR(0x00000150)
#define IOP321_IALR2 (volatile u32 *)IOP321_REG_ADDR(0x00000154)
#define IOP321_IATVR2 (volatile u32 *)IOP321_REG_ADDR(0x00000158)
#define IOP321_OIOWTVR (volatile u32 *)IOP321_REG_ADDR(0x0000015C)
#define IOP321_OMWTVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000160)
#define IOP321_OUMWTVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000164)
#define IOP321_OMWTVR1 (volatile u32 *)IOP321_REG_ADDR(0x00000168)
#define IOP321_OUMWTVR1 (volatile u32 *)IOP321_REG_ADDR(0x0000016C)
/* Reserved 0x00000170 through 0x00000177*/
#define IOP321_OUDWTVR (volatile u32 *)IOP321_REG_ADDR(0x00000178)
/* Reserved 0x0000017C through 0x0000017F*/
#define IOP321_ATUCR (volatile u32 *)IOP321_REG_ADDR(0x00000180)
#define IOP321_PCSR (volatile u32 *)IOP321_REG_ADDR(0x00000184)
#define IOP321_ATUISR (volatile u32 *)IOP321_REG_ADDR(0x00000188)
#define IOP321_ATUIMR (volatile u32 *)IOP321_REG_ADDR(0x0000018C)
#define IOP321_IABAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000190)
#define IOP321_IAUBAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000194)
#define IOP321_IALR3 (volatile u32 *)IOP321_REG_ADDR(0x00000198)
#define IOP321_IATVR3 (volatile u32 *)IOP321_REG_ADDR(0x0000019C)
/* Reserved 0x000001A0 through 0x000001A3*/
#define IOP321_OCCAR (volatile u32 *)IOP321_REG_ADDR(0x000001A4)
/* Reserved 0x000001A8 through 0x000001AB*/
#define IOP321_OCCDR (volatile u32 *)IOP321_REG_ADDR(0x000001AC)
/* Reserved 0x000001B0 through 0x000001BB*/
#define IOP321_PDSCR (volatile u32 *)IOP321_REG_ADDR(0x000001BC)
#define IOP321_PMCAPID (volatile u8 *)IOP321_REG_ADDR(0x000001C0)
#define IOP321_PMNEXT (volatile u8 *)IOP321_REG_ADDR(0x000001C1)
#define IOP321_APMCR (volatile u16 *)IOP321_REG_ADDR(0x000001C2)
#define IOP321_APMCSR (volatile u16 *)IOP321_REG_ADDR(0x000001C4)
/* Reserved 0x000001C6 through 0x000001DF */
#define IOP321_PCIXCAPID (volatile u8 *)IOP321_REG_ADDR(0x000001E0)
#define IOP321_PCIXNEXT (volatile u8 *)IOP321_REG_ADDR(0x000001E1)
#define IOP321_PCIXCMD (volatile u16 *)IOP321_REG_ADDR(0x000001E2)
#define IOP321_PCIXSR (volatile u32 *)IOP321_REG_ADDR(0x000001E4)
#define IOP321_PCIIRSR (volatile u32 *)IOP321_REG_ADDR(0x000001EC)
/* Messaging Unit 0x00000300 through 0x000003FF */
/* DMA Controller 0x00000400 through 0x000004FF */
/* Memory controller 0x00000500 through 0x0005FF */
/* Peripheral bus interface unit 0x00000680 through 0x0006FF */
/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */
/* Internal arbitration unit 0x00000780 through 0x0007BF */
/* Interrupt Controller */
#define IOP321_INTCTL (volatile u32 *)IOP321_REG_ADDR(0x000007D0)
#define IOP321_INTSTR (volatile u32 *)IOP321_REG_ADDR(0x000007D4)
#define IOP321_IINTSRC (volatile u32 *)IOP321_REG_ADDR(0x000007D8)
#define IOP321_FINTSRC (volatile u32 *)IOP321_REG_ADDR(0x000007DC)
/* Timers */
#define IOP321_TU_TMR0 (volatile u32 *)IOP321_REG_ADDR(0x000007E0)
#define IOP321_TU_TMR1 (volatile u32 *)IOP321_REG_ADDR(0x000007E4)
#define IOP321_TMR_TC 0x01
#define IOP321_TMR_EN 0x02
#define IOP321_TMR_RELOAD 0x04
#define IOP321_TMR_PRIVILEGED 0x09
#define IOP321_TMR_RATIO_1_1 0x00
#define IOP321_TMR_RATIO_4_1 0x10
#define IOP321_TMR_RATIO_8_1 0x20
#define IOP321_TMR_RATIO_16_1 0x30
#define IOP321_TU_TCR0 (volatile u32 *)IOP321_REG_ADDR(0x000007E8)
#define IOP321_TU_TCR1 (volatile u32 *)IOP321_REG_ADDR(0x000007EC)
#define IOP321_TU_TRR0 (volatile u32 *)IOP321_REG_ADDR(0x000007F0)
#define IOP321_TU_TRR1 (volatile u32 *)IOP321_REG_ADDR(0x000007F4)
#define IOP321_TU_TISR (volatile u32 *)IOP321_REG_ADDR(0x000007F8)
#define IOP321_TU_WDTCR (volatile u32 *)IOP321_REG_ADDR(0x000007FC)
/* Application accelerator unit 0x00000800 - 0x000008FF */
#define IOP321_AAUACR (volatile u32 *)IOP321_REG_ADDR(0x00000800)
#define IOP321_AAUASR (volatile u32 *)IOP321_REG_ADDR(0x00000804)
#define IOP321_AAUANDAR (volatile u32 *)IOP321_REG_ADDR(0x0000080C)
/* SSP serial port unit 0x00001600 - 0x0000167F */
/* I2C bus interface unit 0x00001680 - 0x000016FF */
#endif // _IOP321_HW_H_
/*
* linux/include/asm/arch-iop3xx/iq80321.h
*
* Intel IQ-80321 evaluation board registers
*/
#ifndef _IQ80321_H_
#define _IQ80321_H_
#define IQ80321_RAMBASE 0xa0000000
#define IQ80321_UART1 0xfe800000 /* UART #1 */
#define IQ80321_7SEG_1 0xfe840000 /* 7-Segment MSB */
#define IQ80321_7SEG_0 0xfe850000 /* 7-Segment LSB (WO) */
#define IQ80321_ROTARY_SW 0xfe8d0000 /* Rotary Switch */
#define IQ80321_BATT_STAT 0xfe8f0000 /* Battery Status */
#endif // _IQ80321_H_
/*
* linux/include/asm-arm/arch-iop3xx/irqs.h
*
* Author: Nicolas Pitre
* Copyright: (C) 2001 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.
*
* 06/13/01: Added 80310 on-chip interrupt sources <dsaxena@mvista.com>
*
*/
#include <linux/config.h>
/*
* XS80200 specific IRQs
* Whic iop3xx implementation is this?
*/
#define IRQ_XS80200_BCU 0 /* Bus Control Unit */
#define IRQ_XS80200_PMU 1 /* Performance Monitoring Unit */
#define IRQ_XS80200_EXTIRQ 2 /* external IRQ signal */
#define IRQ_XS80200_EXTFIQ 3 /* external IRQ signal */
#ifdef CONFIG_ARCH_IOP310
#define NR_XS80200_IRQS 4
#include "iop310-irqs.h"
#define XSCALE_PMU_IRQ IRQ_XS80200_PMU
#else
/*
* IOP80310 chipset interrupts
*/
#define IOP310_IRQ_OFS NR_XS80200_IRQS
#define IOP310_IRQ(x) (IOP310_IRQ_OFS + (x))
/*
* On FIQ1ISR register
*/
#define IRQ_IOP310_DMA0 IOP310_IRQ(0) /* DMA Channel 0 */
#define IRQ_IOP310_DMA1 IOP310_IRQ(1) /* DMA Channel 1 */
#define IRQ_IOP310_DMA2 IOP310_IRQ(2) /* DMA Channel 2 */
#define IRQ_IOP310_PMON IOP310_IRQ(3) /* Bus performance Unit */
#define IRQ_IOP310_AAU IOP310_IRQ(4) /* Application Accelator Unit */
/*
* On FIQ2ISR register
*/
#define IRQ_IOP310_I2C IOP310_IRQ(5) /* I2C unit */
#define IRQ_IOP310_MU IOP310_IRQ(6) /* messaging unit */
#define NR_IOP310_IRQS (IOP310_IRQ(6) + 1)
#define NR_IRQS NR_IOP310_IRQS
/*
* Interrupts available on the Cyclone IQ80310 board
*/
#ifdef CONFIG_ARCH_IQ80310
#define IQ80310_IRQ_OFS NR_IOP310_IRQS
#define IQ80310_IRQ(y) ((IQ80310_IRQ_OFS) + (y))
#define IRQ_IQ80310_TIMER IQ80310_IRQ(0) /* Timer Interrupt */
#define IRQ_IQ80310_I82559 IQ80310_IRQ(1) /* I82559 Ethernet Interrupt */
#define IRQ_IQ80310_UART1 IQ80310_IRQ(2) /* UART1 Interrupt */
#define IRQ_IQ80310_UART2 IQ80310_IRQ(3) /* UART2 Interrupt */
#define IRQ_IQ80310_INTD IQ80310_IRQ(4) /* PCI INTD */
/*
* ONLY AVAILABLE ON REV F OR NEWER BOARDS!
*/
#define IRQ_IQ80310_INTA IQ80310_IRQ(5) /* PCI INTA */
#define IRQ_IQ80310_INTB IQ80310_IRQ(6) /* PCI INTB */
#define IRQ_IQ80310_INTC IQ80310_IRQ(7) /* PCI INTC */
#undef NR_IRQS
#define NR_IRQS (IQ80310_IRQ(7) + 1)
#include "iop321-irqs.h"
#endif // CONFIG_ARCH_IQ80310
#endif
......@@ -7,6 +7,7 @@
#include <linux/config.h>
#include <asm/arch/iop310.h>
#include <asm/arch/iop321.h>
/*
* Task size: 3GB
......@@ -47,9 +48,19 @@
*/
#define __virt_to_bus__is_a_macro
#define __bus_to_virt__is_a_macro
#ifdef CONFIG_ARCH_IOP310
#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP310_SIATVR)) | ((*IOP310_SIABAR) & 0xfffffff0))
#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP310_SIALR)) | ( *IOP310_SIATVR)))
#elif defined(CONFIG_ARCH_IOP321)
#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP321_IATVR2)) | ((*IOP321_IABAR2) & 0xfffffff0))
#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP321_IALR2)) | ( *IOP321_IATVR2)))
#endif
/* boot mem allocate global pointer for MU circular queues QBAR */
#ifdef CONFIG_IOP3XX_MU
extern void *mu_mem;
......
......@@ -29,6 +29,17 @@
#endif // CONFIG_ARCH_IQ80310
#ifdef CONFIG_ARCH_IQ80321
#define IRQ_UART1 IRQ_IQ80321_UART
#define RS_TABLE_SIZE 1
#define STD_SERIAL_PORT_DEFNS \
/* UART CLK PORT IRQ FLAGS */ \
{ 0, BASE_BAUD, 0xfe800000, IRQ_UART1, STD_COM_FLAGS }, /* ttyS0 */
#endif // CONFIG_ARCH_IQ80321
#define EXTRA_SERIAL_PORT_DEFNS
......@@ -14,7 +14,11 @@
#else
/* This is for the underlying xs80200 PMU clock. We run the core @ 733MHz */
#define CLOCK_TICK_RATE 733000000
#endif
#endif // IQ80310
#elif defined(CONFIG_ARCH_IQ80321)
#define CLOCK_TICK_RATE 200000000
#else
......
......@@ -2,10 +2,13 @@
* linux/include/asm-arm/arch-iop80310/uncompress.h
*/
#include <linux/config.h>
#include <linux/serial_reg.h>
#include <asm/hardware.h>
#ifdef CONFIG_ARCH_IQ80310
#define UART1_BASE ((volatile unsigned char *)0xfe800000)
#define UART2_BASE ((volatile unsigned char *)0xfe810000)
#define UART2_BASE ((volatile unsigned char *)IQ80310_UART2)
#elif defined(CONFIG_ARCH_IQ80321)
#define UART2_BASE ((volatile unsigned char *)IQ80321_UART1)
#endif
static __inline__ void putc(char c)
......
......@@ -56,6 +56,10 @@ extern int iop310_setup(int nr, struct pci_sys_data *);
extern struct pci_bus *iop310_scan_bus(int nr, struct pci_sys_data *);
extern void iop310_init(void);
extern int iop321_setup(int nr, struct pci_sys_data *);
extern struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *);
extern void iop321_init(void);
extern int dc21285_setup(int nr, struct pci_sys_data *);
extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *);
extern void dc21285_preinit(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment