mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 07:18:51 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
27
arch/arm/plat-iop/Makefile
Normal file
27
arch/arm/plat-iop/Makefile
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
# IOP32X
|
||||
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) += cp6.o
|
||||
obj-$(CONFIG_ARCH_IOP32X) += adma.o
|
||||
obj-$(CONFIG_ARCH_IOP32X) += pmu.o
|
||||
obj-$(CONFIG_ARCH_IOP32X) += restart.o
|
||||
|
||||
# IOP33X
|
||||
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) += cp6.o
|
||||
obj-$(CONFIG_ARCH_IOP33X) += adma.o
|
||||
obj-$(CONFIG_ARCH_IOP33X) += pmu.o
|
||||
obj-$(CONFIG_ARCH_IOP33X) += restart.o
|
||||
|
||||
# IOP13XX
|
||||
obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
|
||||
obj-$(CONFIG_ARCH_IOP13XX) += time.o
|
||||
205
arch/arm/plat-iop/adma.c
Normal file
205
arch/arm/plat-iop/adma.c
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* 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_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_INTERRUPT, iop3xx_aau_data.cap_mask);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(iop3xx_adma_cap_init);
|
||||
51
arch/arm/plat-iop/cp6.c
Normal file
51
arch/arm/plat-iop/cp6.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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>
|
||||
#include <asm/ptrace.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);
|
||||
}
|
||||
79
arch/arm/plat-iop/i2c.c
Normal file
79
arch/arm/plat-iop/i2c.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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/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,
|
||||
};
|
||||
404
arch/arm/plat-iop/pci.c
Normal file
404
arch/arm/plat-iop/pci.c
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* 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 <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;
|
||||
}
|
||||
|
||||
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(sizeof(struct resource), GFP_KERNEL);
|
||||
if (!res)
|
||||
panic("PCI: unable to alloc resources");
|
||||
|
||||
res->start = IOP3XX_PCI_LOWER_MEM_PA;
|
||||
res->end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
|
||||
res->name = "IOP3XX PCI Memory Space";
|
||||
res->flags = IORESOURCE_MEM;
|
||||
request_resource(&iomem_resource, res);
|
||||
|
||||
/*
|
||||
* Use whatever translation is already setup.
|
||||
*/
|
||||
sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
|
||||
|
||||
pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
|
||||
|
||||
pci_ioremap_io(0, IOP3XX_PCI_LOWER_IO_PA);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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, 0, "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)
|
||||
{
|
||||
pcibios_min_mem = 0;
|
||||
|
||||
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);
|
||||
|
||||
39
arch/arm/plat-iop/pmu.c
Normal file
39
arch/arm/plat-iop/pmu.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* PMU IRQ registration for the iop3xx xscale PMU families.
|
||||
* Copyright (C) 2010 Will Deacon, ARM Ltd.
|
||||
*
|
||||
* 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/platform_device.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
static struct resource pmu_resource = {
|
||||
#ifdef CONFIG_ARCH_IOP32X
|
||||
.start = IRQ_IOP32X_CORE_PMU,
|
||||
.end = IRQ_IOP32X_CORE_PMU,
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_IOP33X
|
||||
.start = IRQ_IOP33X_CORE_PMU,
|
||||
.end = IRQ_IOP33X_CORE_PMU,
|
||||
#endif
|
||||
.flags = IORESOURCE_IRQ,
|
||||
};
|
||||
|
||||
static struct platform_device pmu_device = {
|
||||
.name = "arm-pmu",
|
||||
.id = -1,
|
||||
.resource = &pmu_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
static int __init iop3xx_pmu_init(void)
|
||||
{
|
||||
platform_device_register(&pmu_device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(iop3xx_pmu_init);
|
||||
20
arch/arm/plat-iop/restart.c
Normal file
20
arch/arm/plat-iop/restart.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* restart.c
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <asm/hardware/iop3xx.h>
|
||||
#include <asm/system_misc.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
void iop3xx_restart(enum reboot_mode mode, const char *cmd)
|
||||
{
|
||||
*IOP3XX_PCSR = 0x30;
|
||||
|
||||
/* Jump into ROM at address 0 */
|
||||
soft_restart(0);
|
||||
}
|
||||
34
arch/arm/plat-iop/setup.c
Normal file
34
arch/arm/plat-iop/setup.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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,
|
||||
},
|
||||
};
|
||||
|
||||
void __init iop3xx_map_io(void)
|
||||
{
|
||||
iotable_init(iop3xx_std_desc, ARRAY_SIZE(iop3xx_std_desc));
|
||||
}
|
||||
170
arch/arm/plat-iop/time.c
Normal file
170
arch/arm/plat-iop/time.c
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* 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 <linux/clocksource.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/sched_clock.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>
|
||||
|
||||
/*
|
||||
* Minimum clocksource/clockevent timer range in seconds
|
||||
*/
|
||||
#define IOP_MIN_RANGE 4
|
||||
|
||||
/*
|
||||
* IOP clocksource (free-running timer 1).
|
||||
*/
|
||||
static cycle_t notrace iop_clocksource_read(struct clocksource *unused)
|
||||
{
|
||||
return 0xffffffffu - read_tcr1();
|
||||
}
|
||||
|
||||
static struct clocksource iop_clocksource = {
|
||||
.name = "iop_timer1",
|
||||
.rating = 300,
|
||||
.read = iop_clocksource_read,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
/*
|
||||
* IOP sched_clock() implementation via its clocksource.
|
||||
*/
|
||||
static u64 notrace iop_read_sched_clock(void)
|
||||
{
|
||||
return 0xffffffffu - read_tcr1();
|
||||
}
|
||||
|
||||
/*
|
||||
* IOP clockevents (interrupting timer 0).
|
||||
*/
|
||||
static int iop_set_next_event(unsigned long delta,
|
||||
struct clock_event_device *unused)
|
||||
{
|
||||
u32 tmr = IOP_TMR_PRIVILEGED | IOP_TMR_RATIO_1_1;
|
||||
|
||||
BUG_ON(delta == 0);
|
||||
write_tmr0(tmr & ~(IOP_TMR_EN | IOP_TMR_RELOAD));
|
||||
write_tcr0(delta);
|
||||
write_tmr0((tmr & ~IOP_TMR_RELOAD) | IOP_TMR_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long ticks_per_jiffy;
|
||||
|
||||
static void iop_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *unused)
|
||||
{
|
||||
u32 tmr = read_tmr0();
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
write_tmr0(tmr & ~IOP_TMR_EN);
|
||||
write_tcr0(ticks_per_jiffy - 1);
|
||||
write_trr0(ticks_per_jiffy - 1);
|
||||
tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
/* ->set_next_event sets period and enables timer */
|
||||
tmr &= ~(IOP_TMR_RELOAD | IOP_TMR_EN);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
tmr |= IOP_TMR_EN;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
default:
|
||||
tmr &= ~IOP_TMR_EN;
|
||||
break;
|
||||
}
|
||||
|
||||
write_tmr0(tmr);
|
||||
}
|
||||
|
||||
static struct clock_event_device iop_clockevent = {
|
||||
.name = "iop_timer0",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 300,
|
||||
.set_next_event = iop_set_next_event,
|
||||
.set_mode = iop_set_mode,
|
||||
};
|
||||
|
||||
static irqreturn_t
|
||||
iop_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = dev_id;
|
||||
|
||||
write_tisr(1);
|
||||
evt->event_handler(evt);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction iop_timer_irq = {
|
||||
.name = "IOP Timer Tick",
|
||||
.handler = iop_timer_interrupt,
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.dev_id = &iop_clockevent,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
sched_clock_register(iop_read_sched_clock, 32, tick_rate);
|
||||
|
||||
ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
|
||||
iop_tick_rate = tick_rate;
|
||||
|
||||
timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED |
|
||||
IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1;
|
||||
|
||||
/*
|
||||
* Set up interrupting clockevent timer 0.
|
||||
*/
|
||||
write_tmr0(timer_ctl & ~IOP_TMR_EN);
|
||||
write_tisr(1);
|
||||
setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
|
||||
iop_clockevent.cpumask = cpumask_of(0);
|
||||
clockevents_config_and_register(&iop_clockevent, tick_rate,
|
||||
0xf, 0xfffffffe);
|
||||
|
||||
/*
|
||||
* Set up free-running clocksource timer 1.
|
||||
*/
|
||||
write_trr1(0xffffffff);
|
||||
write_tcr1(0xffffffff);
|
||||
write_tmr1(timer_ctl);
|
||||
clocksource_register_hz(&iop_clocksource, tick_rate);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue