add idl4k kernel firmware version 1.13.0.105

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

View File

@@ -0,0 +1,33 @@
#
# Makefile for the linux kernel.
#
obj-y :=
# IOP32X
obj-$(CONFIG_ARCH_IOP32X) += gpio.o
obj-$(CONFIG_ARCH_IOP32X) += i2c.o
obj-$(CONFIG_ARCH_IOP32X) += pci.o
obj-$(CONFIG_ARCH_IOP32X) += setup.o
obj-$(CONFIG_ARCH_IOP32X) += time.o
obj-$(CONFIG_ARCH_IOP32X) += io.o
obj-$(CONFIG_ARCH_IOP32X) += cp6.o
obj-$(CONFIG_ARCH_IOP32X) += adma.o
# IOP33X
obj-$(CONFIG_ARCH_IOP33X) += gpio.o
obj-$(CONFIG_ARCH_IOP33X) += i2c.o
obj-$(CONFIG_ARCH_IOP33X) += pci.o
obj-$(CONFIG_ARCH_IOP33X) += setup.o
obj-$(CONFIG_ARCH_IOP33X) += time.o
obj-$(CONFIG_ARCH_IOP33X) += io.o
obj-$(CONFIG_ARCH_IOP33X) += cp6.o
obj-$(CONFIG_ARCH_IOP33X) += adma.o
# IOP13XX
obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
obj-$(CONFIG_ARCH_IOP13XX) += time.o
obj-m :=
obj-n :=
obj- :=

View File

@@ -0,0 +1,207 @@
/*
* platform device definitions for the iop3xx dma/xor engines
* Copyright © 2006, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <linux/platform_device.h>
#include <asm/hardware/iop3xx.h>
#include <linux/dma-mapping.h>
#include <mach/adma.h>
#include <asm/hardware/iop_adma.h>
#ifdef CONFIG_ARCH_IOP32X
#define IRQ_DMA0_EOT IRQ_IOP32X_DMA0_EOT
#define IRQ_DMA0_EOC IRQ_IOP32X_DMA0_EOC
#define IRQ_DMA0_ERR IRQ_IOP32X_DMA0_ERR
#define IRQ_DMA1_EOT IRQ_IOP32X_DMA1_EOT
#define IRQ_DMA1_EOC IRQ_IOP32X_DMA1_EOC
#define IRQ_DMA1_ERR IRQ_IOP32X_DMA1_ERR
#define IRQ_AA_EOT IRQ_IOP32X_AA_EOT
#define IRQ_AA_EOC IRQ_IOP32X_AA_EOC
#define IRQ_AA_ERR IRQ_IOP32X_AA_ERR
#endif
#ifdef CONFIG_ARCH_IOP33X
#define IRQ_DMA0_EOT IRQ_IOP33X_DMA0_EOT
#define IRQ_DMA0_EOC IRQ_IOP33X_DMA0_EOC
#define IRQ_DMA0_ERR IRQ_IOP33X_DMA0_ERR
#define IRQ_DMA1_EOT IRQ_IOP33X_DMA1_EOT
#define IRQ_DMA1_EOC IRQ_IOP33X_DMA1_EOC
#define IRQ_DMA1_ERR IRQ_IOP33X_DMA1_ERR
#define IRQ_AA_EOT IRQ_IOP33X_AA_EOT
#define IRQ_AA_EOC IRQ_IOP33X_AA_EOC
#define IRQ_AA_ERR IRQ_IOP33X_AA_ERR
#endif
/* AAU and DMA Channels */
static struct resource iop3xx_dma_0_resources[] = {
[0] = {
.start = IOP3XX_DMA_PHYS_BASE(0),
.end = IOP3XX_DMA_UPPER_PA(0),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_DMA0_EOT,
.end = IRQ_DMA0_EOT,
.flags = IORESOURCE_IRQ
},
[2] = {
.start = IRQ_DMA0_EOC,
.end = IRQ_DMA0_EOC,
.flags = IORESOURCE_IRQ
},
[3] = {
.start = IRQ_DMA0_ERR,
.end = IRQ_DMA0_ERR,
.flags = IORESOURCE_IRQ
}
};
static struct resource iop3xx_dma_1_resources[] = {
[0] = {
.start = IOP3XX_DMA_PHYS_BASE(1),
.end = IOP3XX_DMA_UPPER_PA(1),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_DMA1_EOT,
.end = IRQ_DMA1_EOT,
.flags = IORESOURCE_IRQ
},
[2] = {
.start = IRQ_DMA1_EOC,
.end = IRQ_DMA1_EOC,
.flags = IORESOURCE_IRQ
},
[3] = {
.start = IRQ_DMA1_ERR,
.end = IRQ_DMA1_ERR,
.flags = IORESOURCE_IRQ
}
};
static struct resource iop3xx_aau_resources[] = {
[0] = {
.start = IOP3XX_AAU_PHYS_BASE,
.end = IOP3XX_AAU_UPPER_PA,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_AA_EOT,
.end = IRQ_AA_EOT,
.flags = IORESOURCE_IRQ
},
[2] = {
.start = IRQ_AA_EOC,
.end = IRQ_AA_EOC,
.flags = IORESOURCE_IRQ
},
[3] = {
.start = IRQ_AA_ERR,
.end = IRQ_AA_ERR,
.flags = IORESOURCE_IRQ
}
};
static u64 iop3xx_adma_dmamask = DMA_BIT_MASK(32);
static struct iop_adma_platform_data iop3xx_dma_0_data = {
.hw_id = DMA0_ID,
.pool_size = PAGE_SIZE,
};
static struct iop_adma_platform_data iop3xx_dma_1_data = {
.hw_id = DMA1_ID,
.pool_size = PAGE_SIZE,
};
static struct iop_adma_platform_data iop3xx_aau_data = {
.hw_id = AAU_ID,
.pool_size = 3 * PAGE_SIZE,
};
struct platform_device iop3xx_dma_0_channel = {
.name = "iop-adma",
.id = 0,
.num_resources = 4,
.resource = iop3xx_dma_0_resources,
.dev = {
.dma_mask = &iop3xx_adma_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop3xx_dma_0_data,
},
};
struct platform_device iop3xx_dma_1_channel = {
.name = "iop-adma",
.id = 1,
.num_resources = 4,
.resource = iop3xx_dma_1_resources,
.dev = {
.dma_mask = &iop3xx_adma_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop3xx_dma_1_data,
},
};
struct platform_device iop3xx_aau_channel = {
.name = "iop-adma",
.id = 2,
.num_resources = 4,
.resource = iop3xx_aau_resources,
.dev = {
.dma_mask = &iop3xx_adma_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop3xx_aau_data,
},
};
static int __init iop3xx_adma_cap_init(void)
{
#ifdef CONFIG_ARCH_IOP32X /* the 32x DMA does not perform CRC32C */
dma_cap_set(DMA_MEMCPY, iop3xx_dma_0_data.cap_mask);
dma_cap_set(DMA_INTERRUPT, iop3xx_dma_0_data.cap_mask);
#else
dma_cap_set(DMA_MEMCPY, iop3xx_dma_0_data.cap_mask);
dma_cap_set(DMA_INTERRUPT, iop3xx_dma_0_data.cap_mask);
#endif
#ifdef CONFIG_ARCH_IOP32X /* the 32x DMA does not perform CRC32C */
dma_cap_set(DMA_MEMCPY, iop3xx_dma_1_data.cap_mask);
dma_cap_set(DMA_INTERRUPT, iop3xx_dma_1_data.cap_mask);
#else
dma_cap_set(DMA_MEMCPY, iop3xx_dma_1_data.cap_mask);
dma_cap_set(DMA_INTERRUPT, iop3xx_dma_1_data.cap_mask);
#endif
#ifdef CONFIG_ARCH_IOP32X /* the 32x AAU does not perform zero sum */
dma_cap_set(DMA_XOR, iop3xx_aau_data.cap_mask);
dma_cap_set(DMA_MEMSET, iop3xx_aau_data.cap_mask);
dma_cap_set(DMA_INTERRUPT, iop3xx_aau_data.cap_mask);
#else
dma_cap_set(DMA_XOR, iop3xx_aau_data.cap_mask);
dma_cap_set(DMA_XOR_VAL, iop3xx_aau_data.cap_mask);
dma_cap_set(DMA_MEMSET, iop3xx_aau_data.cap_mask);
dma_cap_set(DMA_INTERRUPT, iop3xx_aau_data.cap_mask);
#endif
return 0;
}
arch_initcall(iop3xx_adma_cap_init);

View File

@@ -0,0 +1,50 @@
/*
* IOP Coprocessor-6 access handler
* Copyright (c) 2006, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
#include <linux/init.h>
#include <asm/traps.h>
static int cp6_trap(struct pt_regs *regs, unsigned int instr)
{
u32 temp;
/* enable cp6 access */
asm volatile (
"mrc p15, 0, %0, c15, c1, 0\n\t"
"orr %0, %0, #(1 << 6)\n\t"
"mcr p15, 0, %0, c15, c1, 0\n\t"
: "=r"(temp));
return 0;
}
/* permit kernel space cp6 access
* deny user space cp6 access
*/
static struct undef_hook cp6_hook = {
.instr_mask = 0x0f000ff0,
.instr_val = 0x0e000610,
.cpsr_mask = MODE_MASK,
.cpsr_val = SVC_MODE,
.fn = cp6_trap,
};
void __init iop_init_cp6_handler(void)
{
register_undef_hook(&cp6_hook);
}

View File

@@ -0,0 +1,91 @@
/*
* arch/arm/plat-iop/gpio.c
* GPIO handling for Intel IOP3xx processors.
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* 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/device.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <asm/hardware/iop3xx.h>
void gpio_line_config(int line, int direction)
{
unsigned long flags;
local_irq_save(flags);
if (direction == GPIO_IN) {
*IOP3XX_GPOE |= 1 << line;
} else if (direction == GPIO_OUT) {
*IOP3XX_GPOE &= ~(1 << line);
}
local_irq_restore(flags);
}
EXPORT_SYMBOL(gpio_line_config);
int gpio_line_get(int line)
{
return !!(*IOP3XX_GPID & (1 << line));
}
EXPORT_SYMBOL(gpio_line_get);
void gpio_line_set(int line, int value)
{
unsigned long flags;
local_irq_save(flags);
if (value == GPIO_LOW) {
*IOP3XX_GPOD &= ~(1 << line);
} else if (value == GPIO_HIGH) {
*IOP3XX_GPOD |= 1 << line;
}
local_irq_restore(flags);
}
EXPORT_SYMBOL(gpio_line_set);
static int iop3xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
gpio_line_config(gpio, GPIO_IN);
return 0;
}
static int iop3xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
{
gpio_line_set(gpio, level);
gpio_line_config(gpio, GPIO_OUT);
return 0;
}
static int iop3xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
return gpio_line_get(gpio);
}
static void iop3xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
{
gpio_line_set(gpio, value);
}
static struct gpio_chip iop3xx_chip = {
.label = "iop3xx",
.direction_input = iop3xx_gpio_direction_input,
.get = iop3xx_gpio_get_value,
.direction_output = iop3xx_gpio_direction_output,
.set = iop3xx_gpio_set_value,
.base = 0,
.ngpio = IOP3XX_N_GPIOS,
};
static int __init iop3xx_gpio_setup(void)
{
return gpiochip_add(&iop3xx_chip);
}
arch_initcall(iop3xx_gpio_setup);

View File

@@ -0,0 +1,80 @@
/*
* arch/arm/plat-iop/i2c.c
*
* Author: Nicolas Pitre <nico@cam.org>
* Copyright (C) 2001 MontaVista Software, Inc.
* Copyright (C) 2004 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/io.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/mach/map.h>
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/memory.h>
#include <mach/hardware.h>
#include <asm/hardware/iop3xx.h>
#include <asm/mach/arch.h>
#ifdef CONFIG_ARCH_IOP32X
#define IRQ_IOP3XX_I2C_0 IRQ_IOP32X_I2C_0
#define IRQ_IOP3XX_I2C_1 IRQ_IOP32X_I2C_1
#endif
#ifdef CONFIG_ARCH_IOP33X
#define IRQ_IOP3XX_I2C_0 IRQ_IOP33X_I2C_0
#define IRQ_IOP3XX_I2C_1 IRQ_IOP33X_I2C_1
#endif
static struct resource iop3xx_i2c0_resources[] = {
[0] = {
.start = 0xfffff680,
.end = 0xfffff697,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IOP3XX_I2C_0,
.end = IRQ_IOP3XX_I2C_0,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device iop3xx_i2c0_device = {
.name = "IOP3xx-I2C",
.id = 0,
.num_resources = 2,
.resource = iop3xx_i2c0_resources,
};
static struct resource iop3xx_i2c1_resources[] = {
[0] = {
.start = 0xfffff6a0,
.end = 0xfffff6b7,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IOP3XX_I2C_1,
.end = IRQ_IOP3XX_I2C_1,
.flags = IORESOURCE_IRQ,
}
};
struct platform_device iop3xx_i2c1_device = {
.name = "IOP3xx-I2C",
.id = 1,
.num_resources = 2,
.resource = iop3xx_i2c1_resources,
};

View File

@@ -0,0 +1,58 @@
/*
* iop3xx custom ioremap implementation
* Copyright (c) 2006, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <mach/hardware.h>
void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
unsigned int mtype)
{
void __iomem * retval;
switch (cookie) {
case IOP3XX_PCI_LOWER_IO_PA ... IOP3XX_PCI_UPPER_IO_PA:
retval = (void *) IOP3XX_PCI_IO_PHYS_TO_VIRT(cookie);
break;
case IOP3XX_PERIPHERAL_PHYS_BASE ... IOP3XX_PERIPHERAL_UPPER_PA:
retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
break;
default:
retval = __arm_ioremap(cookie, size, mtype);
}
return retval;
}
EXPORT_SYMBOL(__iop3xx_ioremap);
void __iop3xx_iounmap(void __iomem *addr)
{
extern void __iounmap(volatile void __iomem *addr);
switch ((u32) addr) {
case IOP3XX_PCI_LOWER_IO_VA ... IOP3XX_PCI_UPPER_IO_VA:
case IOP3XX_PERIPHERAL_VIRT_BASE ... IOP3XX_PERIPHERAL_UPPER_VA:
goto skip;
}
__iounmap(addr);
skip:
return;
}
EXPORT_SYMBOL(__iop3xx_iounmap);

View File

@@ -0,0 +1,415 @@
/*
* arch/arm/plat-iop/pci.c
*
* PCI support for the Intel IOP32X and IOP33X processors
*
* 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 <linux/io.h>
#include <asm/irq.h>
#include <asm/signal.h>
#include <asm/system.h>
#include <mach/hardware.h>
#include <asm/mach/pci.h>
#include <asm/hardware/iop3xx.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 803xx then a type0 made, else a type1 is created.
*/
static u32 iop3xx_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) | (PCI_SLOT(devfn) << 11);
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 occur during a config cycle where there is no device, like during
* the discovery stage.
*/
static int iop3xx_pci_status(void)
{
unsigned int status;
int ret = 0;
/*
* Check the status registers.
*/
status = *IOP3XX_ATUSR;
if (status & 0xf900) {
DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
*IOP3XX_ATUSR = status & 0xf900;
ret = 1;
}
status = *IOP3XX_ATUISR;
if (status & 0x679f) {
DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
*IOP3XX_ATUISR = status & 0x679f;
ret = 1;
}
return ret;
}
/*
* Simply write the address register and read the configuration
* data. Note that the 4 nops ensure that we are able to handle
* a delayed abort (in theory.)
*/
static u32 iop3xx_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" (IOP3XX_OCCAR), "r" (IOP3XX_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
iop3xx_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
unsigned long addr = iop3xx_cfg_address(bus, devfn, where);
u32 val = iop3xx_read(addr) >> ((where & 3) * 8);
if (iop3xx_pci_status())
val = 0xffffffff;
*value = val;
return PCIBIOS_SUCCESSFUL;
}
static int
iop3xx_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value)
{
unsigned long addr = iop3xx_cfg_address(bus, devfn, where);
u32 val;
if (size != 4) {
val = iop3xx_read(addr);
if (iop3xx_pci_status())
return PCIBIOS_SUCCESSFUL;
where = (where & 3) * 8;
if (size == 1)
val &= ~(0xff << where);
else
val &= ~(0xffff << where);
*IOP3XX_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" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR));
}
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops iop3xx_ops = {
.read = iop3xx_read_config,
.write = iop3xx_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.
*/
static int
iop3xx_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;
}
int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
{
struct resource *res;
if (nr != 0)
return 0;
res = kzalloc(2 * sizeof(struct resource), GFP_KERNEL);
if (!res)
panic("PCI: unable to alloc resources");
res[0].start = IOP3XX_PCI_LOWER_IO_PA;
res[0].end = IOP3XX_PCI_LOWER_IO_PA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
res[0].name = "IOP3XX PCI I/O Space";
res[0].flags = IORESOURCE_IO;
request_resource(&ioport_resource, &res[0]);
res[1].start = IOP3XX_PCI_LOWER_MEM_PA;
res[1].end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
res[1].name = "IOP3XX PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
request_resource(&iomem_resource, &res[1]);
/*
* Use whatever translation is already setup.
*/
sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR;
sys->resource[0] = &res[0];
sys->resource[1] = &res[1];
sys->resource[2] = NULL;
return 1;
}
struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys)
{
return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
}
void __init iop3xx_atu_setup(void)
{
/* BAR 0 ( Disabled ) */
*IOP3XX_IAUBAR0 = 0x0;
*IOP3XX_IABAR0 = 0x0;
*IOP3XX_IATVR0 = 0x0;
*IOP3XX_IALR0 = 0x0;
/* BAR 1 ( Disabled ) */
*IOP3XX_IAUBAR1 = 0x0;
*IOP3XX_IABAR1 = 0x0;
*IOP3XX_IALR1 = 0x0;
/* BAR 2 (1:1 mapping with Physical RAM) */
/* Set limit and enable */
*IOP3XX_IALR2 = ~((u32)IOP3XX_MAX_RAM_SIZE - 1) & ~0x1;
*IOP3XX_IAUBAR2 = 0x0;
/* Align the inbound bar with the base of memory */
*IOP3XX_IABAR2 = PHYS_OFFSET |
PCI_BASE_ADDRESS_MEM_TYPE_64 |
PCI_BASE_ADDRESS_MEM_PREFETCH;
*IOP3XX_IATVR2 = PHYS_OFFSET;
/* Outbound window 0 */
*IOP3XX_OMWTVR0 = IOP3XX_PCI_LOWER_MEM_BA;
*IOP3XX_OUMWTVR0 = 0;
/* Outbound window 1 */
*IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_BA +
IOP3XX_PCI_MEM_WINDOW_SIZE / 2;
*IOP3XX_OUMWTVR1 = 0;
/* BAR 3 ( Disabled ) */
*IOP3XX_IAUBAR3 = 0x0;
*IOP3XX_IABAR3 = 0x0;
*IOP3XX_IATVR3 = 0x0;
*IOP3XX_IALR3 = 0x0;
/* Setup the I/O Bar
*/
*IOP3XX_OIOWTVR = IOP3XX_PCI_LOWER_IO_BA;
/* Enable inbound and outbound cycles
*/
*IOP3XX_ATUCMD |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
*IOP3XX_ATUCR |= IOP3XX_ATUCR_OUT_EN;
}
void __init iop3xx_atu_disable(void)
{
*IOP3XX_ATUCMD = 0;
*IOP3XX_ATUCR = 0;
/* wait for cycles to quiesce */
while (*IOP3XX_PCSR & (IOP3XX_PCSR_OUT_Q_BUSY |
IOP3XX_PCSR_IN_Q_BUSY))
cpu_relax();
/* BAR 0 ( Disabled ) */
*IOP3XX_IAUBAR0 = 0x0;
*IOP3XX_IABAR0 = 0x0;
*IOP3XX_IATVR0 = 0x0;
*IOP3XX_IALR0 = 0x0;
/* BAR 1 ( Disabled ) */
*IOP3XX_IAUBAR1 = 0x0;
*IOP3XX_IABAR1 = 0x0;
*IOP3XX_IALR1 = 0x0;
/* BAR 2 ( Disabled ) */
*IOP3XX_IAUBAR2 = 0x0;
*IOP3XX_IABAR2 = 0x0;
*IOP3XX_IATVR2 = 0x0;
*IOP3XX_IALR2 = 0x0;
/* BAR 3 ( Disabled ) */
*IOP3XX_IAUBAR3 = 0x0;
*IOP3XX_IABAR3 = 0x0;
*IOP3XX_IATVR3 = 0x0;
*IOP3XX_IALR3 = 0x0;
/* Clear the outbound windows */
*IOP3XX_OIOWTVR = 0;
/* Outbound window 0 */
*IOP3XX_OMWTVR0 = 0;
*IOP3XX_OUMWTVR0 = 0;
/* Outbound window 1 */
*IOP3XX_OMWTVR1 = 0;
*IOP3XX_OUMWTVR1 = 0;
}
/* Flag to determine whether the ATU is initialized and the PCI bus scanned */
int init_atu;
int iop3xx_get_init_atu(void) {
/* check if default has been overridden */
if (init_atu != IOP3XX_INIT_ATU_DEFAULT)
return init_atu;
else
return IOP3XX_INIT_ATU_DISABLE;
}
static void __init iop3xx_atu_debug(void)
{
DBG("PCI: Intel IOP3xx PCI init.\n");
DBG("PCI: Outbound memory window 0: PCI 0x%08x%08x\n",
*IOP3XX_OUMWTVR0, *IOP3XX_OMWTVR0);
DBG("PCI: Outbound memory window 1: PCI 0x%08x%08x\n",
*IOP3XX_OUMWTVR1, *IOP3XX_OMWTVR1);
DBG("PCI: Outbound IO window: PCI 0x%08x\n",
*IOP3XX_OIOWTVR);
DBG("PCI: Inbound memory window 0: PCI 0x%08x%08x 0x%08x -> 0x%08x\n",
*IOP3XX_IAUBAR0, *IOP3XX_IABAR0, *IOP3XX_IALR0, *IOP3XX_IATVR0);
DBG("PCI: Inbound memory window 1: PCI 0x%08x%08x 0x%08x\n",
*IOP3XX_IAUBAR1, *IOP3XX_IABAR1, *IOP3XX_IALR1);
DBG("PCI: Inbound memory window 2: PCI 0x%08x%08x 0x%08x -> 0x%08x\n",
*IOP3XX_IAUBAR2, *IOP3XX_IABAR2, *IOP3XX_IALR2, *IOP3XX_IATVR2);
DBG("PCI: Inbound memory window 3: PCI 0x%08x%08x 0x%08x -> 0x%08x\n",
*IOP3XX_IAUBAR3, *IOP3XX_IABAR3, *IOP3XX_IALR3, *IOP3XX_IATVR3);
DBG("PCI: Expansion ROM window: PCI 0x%08x%08x 0x%08x -> 0x%08x\n",
0, *IOP3XX_ERBAR, *IOP3XX_ERLR, *IOP3XX_ERTVR);
DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD);
DBG("ATU: IOP3XX_ATUCR=0x%08x\n", *IOP3XX_ATUCR);
hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort");
}
/* for platforms that might be host-bus-adapters */
void __init iop3xx_pci_preinit_cond(void)
{
if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) {
iop3xx_atu_disable();
iop3xx_atu_setup();
iop3xx_atu_debug();
}
}
void __init iop3xx_pci_preinit(void)
{
iop3xx_atu_disable();
iop3xx_atu_setup();
iop3xx_atu_debug();
}
/* allow init_atu to be user overridden */
static int __init iop3xx_init_atu_setup(char *str)
{
init_atu = IOP3XX_INIT_ATU_DEFAULT;
if (str) {
while (*str != '\0') {
switch (*str) {
case 'y':
case 'Y':
init_atu = IOP3XX_INIT_ATU_ENABLE;
break;
case 'n':
case 'N':
init_atu = IOP3XX_INIT_ATU_DISABLE;
break;
case ',':
case '=':
break;
default:
printk(KERN_DEBUG "\"%s\" malformed at "
"character: \'%c\'",
__func__,
*str);
*(str + 1) = '\0';
}
str++;
}
}
return 1;
}
__setup("iop3xx_init_atu", iop3xx_init_atu_setup);

View File

@@ -0,0 +1,39 @@
/*
* arch/arm/plat-iop/setup.c
*
* Author: Nicolas Pitre <nico@fluxnic.net>
* Copyright (C) 2001 MontaVista Software, Inc.
* Copyright (C) 2004 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/mm.h>
#include <linux/init.h>
#include <asm/mach/map.h>
#include <asm/hardware/iop3xx.h>
/*
* Standard IO mapping for all IOP3xx based systems. Note that
* the IOP3xx OCCDR must be mapped uncached and unbuffered.
*/
static struct map_desc iop3xx_std_desc[] __initdata = {
{ /* mem mapped registers */
.virtual = IOP3XX_PERIPHERAL_VIRT_BASE,
.pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE),
.length = IOP3XX_PERIPHERAL_SIZE,
.type = MT_UNCACHED,
}, { /* PCI IO space */
.virtual = IOP3XX_PCI_LOWER_IO_VA,
.pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA),
.length = IOP3XX_PCI_IO_WINDOW_SIZE,
.type = MT_DEVICE,
},
};
void __init iop3xx_map_io(void)
{
iotable_init(iop3xx_std_desc, ARRAY_SIZE(iop3xx_std_desc));
}

View File

@@ -0,0 +1,106 @@
/*
* arch/arm/plat-iop/time.c
*
* Timer code for IOP32x and IOP33x based systems
*
* Author: Deepak Saxena <dsaxena@mvista.com>
*
* Copyright 2002-2003 MontaVista Software Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License 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 <linux/io.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <mach/time.h>
static unsigned long ticks_per_jiffy;
static unsigned long ticks_per_usec;
static unsigned long next_jiffy_time;
unsigned long iop_gettimeoffset(void)
{
unsigned long offset, temp;
/* enable cp6, if necessary, to avoid taking the overhead of an
* undefined instruction trap
*/
asm volatile (
"mrc p15, 0, %0, c15, c1, 0\n\t"
"tst %0, #(1 << 6)\n\t"
"orreq %0, %0, #(1 << 6)\n\t"
"mcreq p15, 0, %0, c15, c1, 0\n\t"
#ifdef CONFIG_CPU_XSCALE
"mrceq p15, 0, %0, c15, c1, 0\n\t"
"moveq %0, %0\n\t"
"subeq pc, pc, #4\n\t"
#endif
: "=r"(temp) : : "cc");
offset = next_jiffy_time - read_tcr1();
return offset / ticks_per_usec;
}
static irqreturn_t
iop_timer_interrupt(int irq, void *dev_id)
{
write_tisr(1);
while ((signed long)(next_jiffy_time - read_tcr1())
>= ticks_per_jiffy) {
timer_tick();
next_jiffy_time -= ticks_per_jiffy;
}
return IRQ_HANDLED;
}
static struct irqaction iop_timer_irq = {
.name = "IOP Timer Tick",
.handler = iop_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
static unsigned long iop_tick_rate;
unsigned long get_iop_tick_rate(void)
{
return iop_tick_rate;
}
EXPORT_SYMBOL(get_iop_tick_rate);
void __init iop_init_time(unsigned long tick_rate)
{
u32 timer_ctl;
ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
ticks_per_usec = tick_rate / 1000000;
next_jiffy_time = 0xffffffff;
iop_tick_rate = tick_rate;
timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED |
IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1;
/*
* We use timer 0 for our timer interrupt, and timer 1 as
* monotonic counter for tracking missed jiffies.
*/
write_trr0(ticks_per_jiffy - 1);
write_tmr0(timer_ctl);
write_trr1(0xffffffff);
write_tmr1(timer_ctl);
setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
}