提交 edabd38e 编写于 作者: S Saeed Bishara 提交者: Nicolas Pitre

ARM: add base support for Marvell Dove SoC

The Marvell Dove (88AP510) is a high-performance, highly integrated,
low power SoC with high-end ARM-compatible processor (known as PJ4),
graphics processing unit, high-definition video decoding acceleration
hardware, and a broad range of peripherals.
Signed-off-by: NLennert Buytenhek <buytenh@marvell.com>
Signed-off-by: NSaeed Bishara <saeed@marvell.com>
Signed-off-by: NNicolas Pitre <nico@marvell.com>
上级 8d27b2f7
...@@ -433,6 +433,17 @@ config ARCH_L7200 ...@@ -433,6 +433,17 @@ config ARCH_L7200
If you have any questions or comments about the Linux kernel port If you have any questions or comments about the Linux kernel port
to this board, send e-mail to <sjhill@cotw.com>. to this board, send e-mail to <sjhill@cotw.com>.
config ARCH_DOVE
bool "Marvell Dove"
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
help
Support for the Marvell Dove SoC 88AP510
config ARCH_KIRKWOOD config ARCH_KIRKWOOD
bool "Marvell Kirkwood" bool "Marvell Kirkwood"
select CPU_FEROCEON select CPU_FEROCEON
...@@ -747,6 +758,8 @@ source "arch/arm/mach-orion5x/Kconfig" ...@@ -747,6 +758,8 @@ source "arch/arm/mach-orion5x/Kconfig"
source "arch/arm/mach-kirkwood/Kconfig" source "arch/arm/mach-kirkwood/Kconfig"
source "arch/arm/mach-dove/Kconfig"
source "arch/arm/plat-s3c24xx/Kconfig" source "arch/arm/plat-s3c24xx/Kconfig"
source "arch/arm/plat-s3c64xx/Kconfig" source "arch/arm/plat-s3c64xx/Kconfig"
source "arch/arm/plat-s3c/Kconfig" source "arch/arm/plat-s3c/Kconfig"
......
...@@ -122,6 +122,7 @@ machine-$(CONFIG_ARCH_AT91) := at91 ...@@ -122,6 +122,7 @@ machine-$(CONFIG_ARCH_AT91) := at91
machine-$(CONFIG_ARCH_BCMRING) := bcmring machine-$(CONFIG_ARCH_BCMRING) := bcmring
machine-$(CONFIG_ARCH_CLPS711X) := clps711x machine-$(CONFIG_ARCH_CLPS711X) := clps711x
machine-$(CONFIG_ARCH_DAVINCI) := davinci machine-$(CONFIG_ARCH_DAVINCI) := davinci
machine-$(CONFIG_ARCH_DOVE) := dove
machine-$(CONFIG_ARCH_EBSA110) := ebsa110 machine-$(CONFIG_ARCH_EBSA110) := ebsa110
machine-$(CONFIG_ARCH_EP93XX) := ep93xx machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_GEMINI) := gemini machine-$(CONFIG_ARCH_GEMINI) := gemini
......
...@@ -743,6 +743,12 @@ proc_types: ...@@ -743,6 +743,12 @@ proc_types:
W(b) __armv4_mmu_cache_off W(b) __armv4_mmu_cache_off
W(b) __armv6_mmu_cache_flush W(b) __armv6_mmu_cache_flush
.word 0x560f5810 @ Marvell PJ4 ARMv6
.word 0xff0ffff0
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv6_mmu_cache_flush
.word 0x000f0000 @ new CPU Id .word 0x000f0000 @ new CPU Id
.word 0x000f0000 .word 0x000f0000
W(b) __armv7_mmu_cache_on W(b) __armv7_mmu_cache_on
......
此差异已折叠。
if ARCH_DOVE
menu "Marvell Dove Implementations"
config MACH_DOVE_DB
bool "Marvell DB-MV88AP510 Development Board"
select I2C_BOARDINFO
help
Say 'Y' here if you want your kernel to support the
Marvell DB-MV88AP510 Development Board.
endmenu
endif
obj-y += common.o addr-map.o irq.o pcie.o
obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o
zreladdr-y := 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
/*
* arch/arm/mach-dove/addr-map.c
*
* Address map functions for Marvell Dove 88AP510 SoC
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <asm/mach/arch.h>
#include <asm/setup.h>
#include "common.h"
/*
* Generic Address Decode Windows bit settings
*/
#define TARGET_DDR 0x0
#define TARGET_BOOTROM 0x1
#define TARGET_CESA 0x3
#define TARGET_PCIE0 0x4
#define TARGET_PCIE1 0x8
#define TARGET_SCRATCHPAD 0xd
#define ATTR_CESA 0x01
#define ATTR_BOOTROM 0xfd
#define ATTR_DEV_SPI0_ROM 0xfe
#define ATTR_DEV_SPI1_ROM 0xfb
#define ATTR_PCIE_IO 0xe0
#define ATTR_PCIE_MEM 0xe8
#define ATTR_SCRATCHPAD 0x0
/*
* CPU Address Decode Windows registers
*/
#define WIN_CTRL(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x0)
#define WIN_BASE(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x4)
#define WIN_REMAP_LO(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x8)
#define WIN_REMAP_HI(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0xc)
struct mbus_dram_target_info dove_mbus_dram_info;
static inline void __iomem *ddr_map_sc(int i)
{
return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
}
static int cpu_win_can_remap(int win)
{
if (win < 4)
return 1;
return 0;
}
static void __init setup_cpu_win(int win, u32 base, u32 size,
u8 target, u8 attr, int remap)
{
u32 ctrl;
base &= 0xffff0000;
ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
writel(base, WIN_BASE(win));
writel(ctrl, WIN_CTRL(win));
if (cpu_win_can_remap(win)) {
if (remap < 0)
remap = base;
writel(remap & 0xffff0000, WIN_REMAP_LO(win));
writel(0, WIN_REMAP_HI(win));
}
}
void __init dove_setup_cpu_mbus(void)
{
int i;
int cs;
/*
* First, disable and clear windows.
*/
for (i = 0; i < 8; i++) {
writel(0, WIN_BASE(i));
writel(0, WIN_CTRL(i));
if (cpu_win_can_remap(i)) {
writel(0, WIN_REMAP_LO(i));
writel(0, WIN_REMAP_HI(i));
}
}
/*
* Setup windows for PCIe IO+MEM space.
*/
setup_cpu_win(0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE);
setup_cpu_win(1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE);
setup_cpu_win(2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
TARGET_PCIE0, ATTR_PCIE_MEM, -1);
setup_cpu_win(3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
TARGET_PCIE1, ATTR_PCIE_MEM, -1);
/*
* Setup window for CESA engine.
*/
setup_cpu_win(4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
TARGET_CESA, ATTR_CESA, -1);
/*
* Setup the Window to the BootROM for Standby and Sleep Resume
*/
setup_cpu_win(5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
TARGET_BOOTROM, ATTR_BOOTROM, -1);
/*
* Setup the Window to the PMU Scratch Pad space
*/
setup_cpu_win(6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1);
/*
* Setup MBUS dram target info.
*/
dove_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
for (i = 0, cs = 0; i < 2; i++) {
u32 map = readl(ddr_map_sc(i));
/*
* Chip select enabled?
*/
if (map & 1) {
struct mbus_dram_window *w;
w = &dove_mbus_dram_info.cs[cs++];
w->cs_index = i;
w->mbus_attr = 0; /* CS address decoding done inside */
/* the DDR controller, no need to */
/* provide attributes */
w->base = map & 0xff800000;
w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
}
}
dove_mbus_dram_info.num_cs = cs;
}
/*
* arch/arm/mach-dove/common.c
*
* Core functions for Marvell Dove 88AP510 System On Chip
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/serial_8250.h>
#include <linux/clk.h>
#include <linux/mbus.h>
#include <linux/mv643xx_eth.h>
#include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h>
#include <linux/spi/orion_spi.h>
#include <linux/gpio.h>
#include <asm/page.h>
#include <asm/setup.h>
#include <asm/timex.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/mach/pci.h>
#include <mach/dove.h>
#include <mach/bridge-regs.h>
#include <asm/mach/arch.h>
#include <linux/irq.h>
#include <plat/mv_xor.h>
#include <plat/ehci-orion.h>
#include <plat/time.h>
#include "common.h"
/*****************************************************************************
* I/O Address Mapping
****************************************************************************/
static struct map_desc dove_io_desc[] __initdata = {
{
.virtual = DOVE_SB_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE),
.length = DOVE_SB_REGS_SIZE,
.type = MT_DEVICE,
}, {
.virtual = DOVE_NB_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
.length = DOVE_NB_REGS_SIZE,
.type = MT_DEVICE,
}, {
.virtual = DOVE_PCIE0_IO_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_PCIE0_IO_PHYS_BASE),
.length = DOVE_PCIE0_IO_SIZE,
.type = MT_DEVICE,
}, {
.virtual = DOVE_PCIE1_IO_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_PCIE1_IO_PHYS_BASE),
.length = DOVE_PCIE1_IO_SIZE,
.type = MT_DEVICE,
},
};
void __init dove_map_io(void)
{
iotable_init(dove_io_desc, ARRAY_SIZE(dove_io_desc));
}
/*****************************************************************************
* EHCI
****************************************************************************/
static struct orion_ehci_data dove_ehci_data = {
.dram = &dove_mbus_dram_info,
.phy_version = EHCI_PHY_NA,
};
static u64 ehci_dmamask = DMA_BIT_MASK(32);
/*****************************************************************************
* EHCI0
****************************************************************************/
static struct resource dove_ehci0_resources[] = {
{
.start = DOVE_USB0_PHYS_BASE,
.end = DOVE_USB0_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_USB0,
.end = IRQ_DOVE_USB0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_ehci0 = {
.name = "orion-ehci",
.id = 0,
.dev = {
.dma_mask = &ehci_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &dove_ehci_data,
},
.resource = dove_ehci0_resources,
.num_resources = ARRAY_SIZE(dove_ehci0_resources),
};
void __init dove_ehci0_init(void)
{
platform_device_register(&dove_ehci0);
}
/*****************************************************************************
* EHCI1
****************************************************************************/
static struct resource dove_ehci1_resources[] = {
{
.start = DOVE_USB1_PHYS_BASE,
.end = DOVE_USB1_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_USB1,
.end = IRQ_DOVE_USB1,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_ehci1 = {
.name = "orion-ehci",
.id = 1,
.dev = {
.dma_mask = &ehci_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &dove_ehci_data,
},
.resource = dove_ehci1_resources,
.num_resources = ARRAY_SIZE(dove_ehci1_resources),
};
void __init dove_ehci1_init(void)
{
platform_device_register(&dove_ehci1);
}
/*****************************************************************************
* GE00
****************************************************************************/
struct mv643xx_eth_shared_platform_data dove_ge00_shared_data = {
.t_clk = 0,
.dram = &dove_mbus_dram_info,
};
static struct resource dove_ge00_shared_resources[] = {
{
.name = "ge00 base",
.start = DOVE_GE00_PHYS_BASE + 0x2000,
.end = DOVE_GE00_PHYS_BASE + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device dove_ge00_shared = {
.name = MV643XX_ETH_SHARED_NAME,
.id = 0,
.dev = {
.platform_data = &dove_ge00_shared_data,
},
.num_resources = 1,
.resource = dove_ge00_shared_resources,
};
static struct resource dove_ge00_resources[] = {
{
.name = "ge00 irq",
.start = IRQ_DOVE_GE00_SUM,
.end = IRQ_DOVE_GE00_SUM,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_ge00 = {
.name = MV643XX_ETH_NAME,
.id = 0,
.num_resources = 1,
.resource = dove_ge00_resources,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
eth_data->shared = &dove_ge00_shared;
dove_ge00.dev.platform_data = eth_data;
platform_device_register(&dove_ge00_shared);
platform_device_register(&dove_ge00);
}
/*****************************************************************************
* SoC RTC
****************************************************************************/
static struct resource dove_rtc_resource[] = {
{
.start = DOVE_RTC_PHYS_BASE,
.end = DOVE_RTC_PHYS_BASE + 32 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_RTC,
.flags = IORESOURCE_IRQ,
}
};
void __init dove_rtc_init(void)
{
platform_device_register_simple("rtc-mv", -1, dove_rtc_resource, 2);
}
/*****************************************************************************
* SATA
****************************************************************************/
static struct resource dove_sata_resources[] = {
{
.name = "sata base",
.start = DOVE_SATA_PHYS_BASE,
.end = DOVE_SATA_PHYS_BASE + 0x5000 - 1,
.flags = IORESOURCE_MEM,
}, {
.name = "sata irq",
.start = IRQ_DOVE_SATA,
.end = IRQ_DOVE_SATA,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_sata = {
.name = "sata_mv",
.id = 0,
.dev = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(dove_sata_resources),
.resource = dove_sata_resources,
};
void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
{
sata_data->dram = &dove_mbus_dram_info;
dove_sata.dev.platform_data = sata_data;
platform_device_register(&dove_sata);
}
/*****************************************************************************
* UART0
****************************************************************************/
static struct plat_serial8250_port dove_uart0_data[] = {
{
.mapbase = DOVE_UART0_PHYS_BASE,
.membase = (char *)DOVE_UART0_VIRT_BASE,
.irq = IRQ_DOVE_UART_0,
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 0,
}, {
},
};
static struct resource dove_uart0_resources[] = {
{
.start = DOVE_UART0_PHYS_BASE,
.end = DOVE_UART0_PHYS_BASE + SZ_256 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_UART_0,
.end = IRQ_DOVE_UART_0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_uart0 = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = dove_uart0_data,
},
.resource = dove_uart0_resources,
.num_resources = ARRAY_SIZE(dove_uart0_resources),
};
void __init dove_uart0_init(void)
{
platform_device_register(&dove_uart0);
}
/*****************************************************************************
* UART1
****************************************************************************/
static struct plat_serial8250_port dove_uart1_data[] = {
{
.mapbase = DOVE_UART1_PHYS_BASE,
.membase = (char *)DOVE_UART1_VIRT_BASE,
.irq = IRQ_DOVE_UART_1,
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 0,
}, {
},
};
static struct resource dove_uart1_resources[] = {
{
.start = DOVE_UART1_PHYS_BASE,
.end = DOVE_UART1_PHYS_BASE + SZ_256 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_UART_1,
.end = IRQ_DOVE_UART_1,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_uart1 = {
.name = "serial8250",
.id = 1,
.dev = {
.platform_data = dove_uart1_data,
},
.resource = dove_uart1_resources,
.num_resources = ARRAY_SIZE(dove_uart1_resources),
};
void __init dove_uart1_init(void)
{
platform_device_register(&dove_uart1);
}
/*****************************************************************************
* UART2
****************************************************************************/
static struct plat_serial8250_port dove_uart2_data[] = {
{
.mapbase = DOVE_UART2_PHYS_BASE,
.membase = (char *)DOVE_UART2_VIRT_BASE,
.irq = IRQ_DOVE_UART_2,
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 0,
}, {
},
};
static struct resource dove_uart2_resources[] = {
{
.start = DOVE_UART2_PHYS_BASE,
.end = DOVE_UART2_PHYS_BASE + SZ_256 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_UART_2,
.end = IRQ_DOVE_UART_2,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_uart2 = {
.name = "serial8250",
.id = 2,
.dev = {
.platform_data = dove_uart2_data,
},
.resource = dove_uart2_resources,
.num_resources = ARRAY_SIZE(dove_uart2_resources),
};
void __init dove_uart2_init(void)
{
platform_device_register(&dove_uart2);
}
/*****************************************************************************
* UART3
****************************************************************************/
static struct plat_serial8250_port dove_uart3_data[] = {
{
.mapbase = DOVE_UART3_PHYS_BASE,
.membase = (char *)DOVE_UART3_VIRT_BASE,
.irq = IRQ_DOVE_UART_3,
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 0,
}, {
},
};
static struct resource dove_uart3_resources[] = {
{
.start = DOVE_UART3_PHYS_BASE,
.end = DOVE_UART3_PHYS_BASE + SZ_256 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_UART_3,
.end = IRQ_DOVE_UART_3,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_uart3 = {
.name = "serial8250",
.id = 3,
.dev = {
.platform_data = dove_uart3_data,
},
.resource = dove_uart3_resources,
.num_resources = ARRAY_SIZE(dove_uart3_resources),
};
void __init dove_uart3_init(void)
{
platform_device_register(&dove_uart3);
}
/*****************************************************************************
* SPI0
****************************************************************************/
static struct orion_spi_info dove_spi0_data = {
.tclk = 0,
};
static struct resource dove_spi0_resources[] = {
{
.start = DOVE_SPI0_PHYS_BASE,
.end = DOVE_SPI0_PHYS_BASE + SZ_512 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_SPI0,
.end = IRQ_DOVE_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_spi0 = {
.name = "orion_spi",
.id = 0,
.resource = dove_spi0_resources,
.dev = {
.platform_data = &dove_spi0_data,
},
.num_resources = ARRAY_SIZE(dove_spi0_resources),
};
void __init dove_spi0_init(void)
{
platform_device_register(&dove_spi0);
}
/*****************************************************************************
* SPI1
****************************************************************************/
static struct orion_spi_info dove_spi1_data = {
.tclk = 0,
};
static struct resource dove_spi1_resources[] = {
{
.start = DOVE_SPI1_PHYS_BASE,
.end = DOVE_SPI1_PHYS_BASE + SZ_512 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_DOVE_SPI1,
.end = IRQ_DOVE_SPI1,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_spi1 = {
.name = "orion_spi",
.id = 1,
.resource = dove_spi1_resources,
.dev = {
.platform_data = &dove_spi1_data,
},
.num_resources = ARRAY_SIZE(dove_spi1_resources),
};
void __init dove_spi1_init(void)
{
platform_device_register(&dove_spi1);
}
/*****************************************************************************
* I2C
****************************************************************************/
static struct mv64xxx_i2c_pdata dove_i2c_data = {
.freq_m = 10, /* assumes 166 MHz TCLK gets 94.3kHz */
.freq_n = 3,
.timeout = 1000, /* Default timeout of 1 second */
};
static struct resource dove_i2c_resources[] = {
{
.name = "i2c base",
.start = DOVE_I2C_PHYS_BASE,
.end = DOVE_I2C_PHYS_BASE + 0x20 - 1,
.flags = IORESOURCE_MEM,
}, {
.name = "i2c irq",
.start = IRQ_DOVE_I2C,
.end = IRQ_DOVE_I2C,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dove_i2c = {
.name = MV64XXX_I2C_CTLR_NAME,
.id = 0,
.num_resources = ARRAY_SIZE(dove_i2c_resources),
.resource = dove_i2c_resources,
.dev = {
.platform_data = &dove_i2c_data,
},
};
void __init dove_i2c_init(void)
{
platform_device_register(&dove_i2c);
}
/*****************************************************************************
* Time handling
****************************************************************************/
static int get_tclk(void)
{
/* use DOVE_RESET_SAMPLE_HI/LO to detect tclk */
return 166666667;
}
static void dove_timer_init(void)
{
orion_time_init(IRQ_DOVE_BRIDGE, get_tclk());
}
struct sys_timer dove_timer = {
.init = dove_timer_init,
};
/*****************************************************************************
* XOR
****************************************************************************/
static struct mv_xor_platform_shared_data dove_xor_shared_data = {
.dram = &dove_mbus_dram_info,
};
/*****************************************************************************
* XOR 0
****************************************************************************/
static u64 dove_xor0_dmamask = DMA_BIT_MASK(32);
static struct resource dove_xor0_shared_resources[] = {
{
.name = "xor 0 low",
.start = DOVE_XOR0_PHYS_BASE,
.end = DOVE_XOR0_PHYS_BASE + 0xff,
.flags = IORESOURCE_MEM,
}, {
.name = "xor 0 high",
.start = DOVE_XOR0_HIGH_PHYS_BASE,
.end = DOVE_XOR0_HIGH_PHYS_BASE + 0xff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device dove_xor0_shared = {
.name = MV_XOR_SHARED_NAME,
.id = 0,
.dev = {
.platform_data = &dove_xor_shared_data,
},
.num_resources = ARRAY_SIZE(dove_xor0_shared_resources),
.resource = dove_xor0_shared_resources,
};
static struct resource dove_xor00_resources[] = {
[0] = {
.start = IRQ_DOVE_XOR_00,
.end = IRQ_DOVE_XOR_00,
.flags = IORESOURCE_IRQ,
},
};
static struct mv_xor_platform_data dove_xor00_data = {
.shared = &dove_xor0_shared,
.hw_id = 0,
.pool_size = PAGE_SIZE,
};
static struct platform_device dove_xor00_channel = {
.name = MV_XOR_NAME,
.id = 0,
.num_resources = ARRAY_SIZE(dove_xor00_resources),
.resource = dove_xor00_resources,
.dev = {
.dma_mask = &dove_xor0_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&dove_xor00_data,
},
};
static struct resource dove_xor01_resources[] = {
[0] = {
.start = IRQ_DOVE_XOR_01,
.end = IRQ_DOVE_XOR_01,
.flags = IORESOURCE_IRQ,
},
};
static struct mv_xor_platform_data dove_xor01_data = {
.shared = &dove_xor0_shared,
.hw_id = 1,
.pool_size = PAGE_SIZE,
};
static struct platform_device dove_xor01_channel = {
.name = MV_XOR_NAME,
.id = 1,
.num_resources = ARRAY_SIZE(dove_xor01_resources),
.resource = dove_xor01_resources,
.dev = {
.dma_mask = &dove_xor0_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&dove_xor01_data,
},
};
void __init dove_xor0_init(void)
{
platform_device_register(&dove_xor0_shared);
/*
* two engines can't do memset simultaneously, this limitation
* satisfied by removing memset support from one of the engines.
*/
dma_cap_set(DMA_MEMCPY, dove_xor00_data.cap_mask);
dma_cap_set(DMA_XOR, dove_xor00_data.cap_mask);
platform_device_register(&dove_xor00_channel);
dma_cap_set(DMA_MEMCPY, dove_xor01_data.cap_mask);
dma_cap_set(DMA_MEMSET, dove_xor01_data.cap_mask);
dma_cap_set(DMA_XOR, dove_xor01_data.cap_mask);
platform_device_register(&dove_xor01_channel);
}
/*****************************************************************************
* XOR 1
****************************************************************************/
static u64 dove_xor1_dmamask = DMA_BIT_MASK(32);
static struct resource dove_xor1_shared_resources[] = {
{
.name = "xor 0 low",
.start = DOVE_XOR1_PHYS_BASE,
.end = DOVE_XOR1_PHYS_BASE + 0xff,
.flags = IORESOURCE_MEM,
}, {
.name = "xor 0 high",
.start = DOVE_XOR1_HIGH_PHYS_BASE,
.end = DOVE_XOR1_HIGH_PHYS_BASE + 0xff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device dove_xor1_shared = {
.name = MV_XOR_SHARED_NAME,
.id = 1,
.dev = {
.platform_data = &dove_xor_shared_data,
},
.num_resources = ARRAY_SIZE(dove_xor1_shared_resources),
.resource = dove_xor1_shared_resources,
};
static struct resource dove_xor10_resources[] = {
[0] = {
.start = IRQ_DOVE_XOR_10,
.end = IRQ_DOVE_XOR_10,
.flags = IORESOURCE_IRQ,
},
};
static struct mv_xor_platform_data dove_xor10_data = {
.shared = &dove_xor1_shared,
.hw_id = 0,
.pool_size = PAGE_SIZE,
};
static struct platform_device dove_xor10_channel = {
.name = MV_XOR_NAME,
.id = 2,
.num_resources = ARRAY_SIZE(dove_xor10_resources),
.resource = dove_xor10_resources,
.dev = {
.dma_mask = &dove_xor1_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&dove_xor10_data,
},
};
static struct resource dove_xor11_resources[] = {
[0] = {
.start = IRQ_DOVE_XOR_11,
.end = IRQ_DOVE_XOR_11,
.flags = IORESOURCE_IRQ,
},
};
static struct mv_xor_platform_data dove_xor11_data = {
.shared = &dove_xor1_shared,
.hw_id = 1,
.pool_size = PAGE_SIZE,
};
static struct platform_device dove_xor11_channel = {
.name = MV_XOR_NAME,
.id = 3,
.num_resources = ARRAY_SIZE(dove_xor11_resources),
.resource = dove_xor11_resources,
.dev = {
.dma_mask = &dove_xor1_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&dove_xor11_data,
},
};
void __init dove_xor1_init(void)
{
platform_device_register(&dove_xor1_shared);
/*
* two engines can't do memset simultaneously, this limitation
* satisfied by removing memset support from one of the engines.
*/
dma_cap_set(DMA_MEMCPY, dove_xor10_data.cap_mask);
dma_cap_set(DMA_XOR, dove_xor10_data.cap_mask);
platform_device_register(&dove_xor10_channel);
dma_cap_set(DMA_MEMCPY, dove_xor11_data.cap_mask);
dma_cap_set(DMA_MEMSET, dove_xor11_data.cap_mask);
dma_cap_set(DMA_XOR, dove_xor11_data.cap_mask);
platform_device_register(&dove_xor11_channel);
}
void __init dove_init(void)
{
int tclk;
tclk = get_tclk();
printk(KERN_INFO "Dove 88AP510 SoC, ");
printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000);
dove_setup_cpu_mbus();
dove_ge00_shared_data.t_clk = tclk;
dove_uart0_data[0].uartclk = tclk;
dove_uart1_data[0].uartclk = tclk;
dove_uart2_data[0].uartclk = tclk;
dove_uart3_data[0].uartclk = tclk;
dove_spi0_data.tclk = tclk;
dove_spi1_data.tclk = tclk;
/* internal devices that every board has */
dove_rtc_init();
dove_xor0_init();
dove_xor1_init();
}
/*
* arch/arm/mach-dove/common.h
*
* Core functions for Marvell Dove 88AP510 System On Chip
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ARCH_DOVE_COMMON_H
#define __ARCH_DOVE_COMMON_H
struct mv643xx_eth_platform_data;
struct mv_sata_platform_data;
extern struct sys_timer dove_timer;
extern struct mbus_dram_target_info dove_mbus_dram_info;
/*
* Basic Dove init functions used early by machine-setup.
*/
void dove_map_io(void);
void dove_init(void);
void dove_init_irq(void);
void dove_setup_cpu_mbus(void);
void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
void dove_sata_init(struct mv_sata_platform_data *sata_data);
void dove_pcie_init(int init_port0, int init_port1);
void dove_ehci0_init(void);
void dove_ehci1_init(void);
void dove_uart0_init(void);
void dove_uart1_init(void);
void dove_uart2_init(void);
void dove_uart3_init(void);
void dove_spi0_init(void);
void dove_spi1_init(void);
void dove_i2c_init(void);
#endif
/*
* arch/arm/mach-dove/dove-db-setup.c
*
* Marvell DB-MV88AP510-BP Development Board Setup
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
#include <linux/timer.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/i2c.h>
#include <linux/pci.h>
#include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/spi/flash.h>
#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/dove.h>
#include "common.h"
static struct mv643xx_eth_platform_data dove_db_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT,
};
static struct mv_sata_platform_data dove_db_sata_data = {
.n_ports = 1,
};
/*****************************************************************************
* SPI Devices:
* SPI0: 4M Flash ST-M25P32-VMF6P
****************************************************************************/
static const struct flash_platform_data dove_db_spi_flash_data = {
.type = "m25p64",
};
static struct spi_board_info __initdata dove_db_spi_flash_info[] = {
{
.modalias = "m25p80",
.platform_data = &dove_db_spi_flash_data,
.irq = -1,
.max_speed_hz = 20000000,
.bus_num = 0,
.chip_select = 0,
},
};
/*****************************************************************************
* PCI
****************************************************************************/
static int __init dove_db_pci_init(void)
{
if (machine_is_dove_db())
dove_pcie_init(1, 1);
return 0;
}
subsys_initcall(dove_db_pci_init);
/*****************************************************************************
* Board Init
****************************************************************************/
static void __init dove_db_init(void)
{
/*
* Basic Dove setup. Needs to be called early.
*/
dove_init();
dove_ge00_init(&dove_db_ge00_data);
dove_ehci0_init();
dove_ehci1_init();
dove_sata_init(&dove_db_sata_data);
dove_spi0_init();
dove_spi1_init();
dove_uart0_init();
dove_uart1_init();
dove_i2c_init();
spi_register_board_info(dove_db_spi_flash_info,
ARRAY_SIZE(dove_db_spi_flash_info));
}
MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board")
.phys_io = DOVE_SB_REGS_PHYS_BASE,
.io_pg_offst = ((DOVE_SB_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = dove_db_init,
.map_io = dove_map_io,
.init_irq = dove_init_irq,
.timer = &dove_timer,
MACHINE_END
/*
* arch/arm/mach-dove/include/mach/bridge-regs.h
*
* Mbus-L to Mbus Bridge Registers
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_BRIDGE_REGS_H
#define __ASM_ARCH_BRIDGE_REGS_H
#include <mach/dove.h>
#define CPU_CONFIG (BRIDGE_VIRT_BASE | 0x0000)
#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104)
#define CPU_CTRL_PCIE0_LINK 0x00000001
#define CPU_RESET 0x00000002
#define CPU_CTRL_PCIE1_LINK 0x00000008
#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
#define SOFT_RESET_OUT_EN 0x00000004
#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
#define SOFT_RESET 0x00000001
#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE | 0x0110)
#define BRIDGE_MASK (BRIDGE_VIRT_BASE | 0x0114)
#define BRIDGE_INT_TIMER0 0x0002
#define BRIDGE_INT_TIMER1 0x0004
#define BRIDGE_INT_TIMER1_CLR (~0x0004)
#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
#define IRQ_CAUSE_LOW_OFF 0x0000
#define IRQ_MASK_LOW_OFF 0x0004
#define FIQ_MASK_LOW_OFF 0x0008
#define ENDPOINT_MASK_LOW_OFF 0x000c
#define IRQ_CAUSE_HIGH_OFF 0x0010
#define IRQ_MASK_HIGH_OFF 0x0014
#define FIQ_MASK_HIGH_OFF 0x0018
#define ENDPOINT_MASK_HIGH_OFF 0x001c
#define PCIE_INTERRUPT_MASK_OFF 0x0020
#define IRQ_MASK_LOW (IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)
#define FIQ_MASK_LOW (IRQ_VIRT_BASE + FIQ_MASK_LOW_OFF)
#define ENDPOINT_MASK_LOW (IRQ_VIRT_BASE + ENDPOINT_MASK_LOW_OFF)
#define IRQ_MASK_HIGH (IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)
#define FIQ_MASK_HIGH (IRQ_VIRT_BASE + FIQ_MASK_HIGH_OFF)
#define ENDPOINT_MASK_HIGH (IRQ_VIRT_BASE + ENDPOINT_MASK_HIGH_OFF)
#define PCIE_INTERRUPT_MASK (IRQ_VIRT_BASE + PCIE_INTERRUPT_MASK_OFF)
#define POWER_MANAGEMENT (BRIDGE_VIRT_BASE | 0x011c)
#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
#endif
/*
* arch/arm/mach-dove/include/mach/debug-macro.S
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <mach/bridge-regs.h>
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
ldreq \rx, =DOVE_SB_REGS_PHYS_BASE
ldrne \rx, =DOVE_SB_REGS_VIRT_BASE
orr \rx, \rx, #0x00012000
.endm
#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>
/*
* arch/arm/mach-dove/include/mach/dove.h
*
* Generic definitions for Marvell Dove 88AP510 SoC
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_DOVE_H
#define __ASM_ARCH_DOVE_H
#include <mach/vmalloc.h>
/*
* Marvell Dove address maps.
*
* phys virt size
* c8000000 fdb00000 1M Cryptographic SRAM
* e0000000 @runtime 128M PCIe-0 Memory space
* e8000000 @runtime 128M PCIe-1 Memory space
* f1000000 fde00000 8M on-chip south-bridge registers
* f1800000 fe600000 8M on-chip north-bridge registers
* f2000000 fee00000 1M PCIe-0 I/O space
* f2100000 fef00000 1M PCIe-1 I/O space
*/
#define DOVE_CESA_PHYS_BASE 0xc8000000
#define DOVE_CESA_VIRT_BASE 0xfdb00000
#define DOVE_CESA_SIZE SZ_1M
#define DOVE_PCIE0_MEM_PHYS_BASE 0xe0000000
#define DOVE_PCIE0_MEM_SIZE SZ_128M
#define DOVE_PCIE1_MEM_PHYS_BASE 0xe8000000
#define DOVE_PCIE1_MEM_SIZE SZ_128M
#define DOVE_BOOTROM_PHYS_BASE 0xf8000000
#define DOVE_BOOTROM_SIZE SZ_128M
#define DOVE_SCRATCHPAD_PHYS_BASE 0xf0000000
#define DOVE_SCRATCHPAD_VIRT_BASE 0xfdd00000
#define DOVE_SCRATCHPAD_SIZE SZ_1M
#define DOVE_SB_REGS_PHYS_BASE 0xf1000000
#define DOVE_SB_REGS_VIRT_BASE 0xfde00000
#define DOVE_SB_REGS_SIZE SZ_8M
#define DOVE_NB_REGS_PHYS_BASE 0xf1800000
#define DOVE_NB_REGS_VIRT_BASE 0xfe600000
#define DOVE_NB_REGS_SIZE SZ_8M
#define DOVE_PCIE0_IO_PHYS_BASE 0xf2000000
#define DOVE_PCIE0_IO_VIRT_BASE 0xfee00000
#define DOVE_PCIE0_IO_BUS_BASE 0x00000000
#define DOVE_PCIE0_IO_SIZE SZ_1M
#define DOVE_PCIE1_IO_PHYS_BASE 0xf2100000
#define DOVE_PCIE1_IO_VIRT_BASE 0xfef00000
#define DOVE_PCIE1_IO_BUS_BASE 0x00100000
#define DOVE_PCIE1_IO_SIZE SZ_1M
/*
* Dove Core Registers Map
*/
/* SPI, I2C, UART */
#define DOVE_I2C_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x11000)
#define DOVE_UART0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12000)
#define DOVE_UART0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12000)
#define DOVE_UART1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12100)
#define DOVE_UART1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12100)
#define DOVE_UART2_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12200)
#define DOVE_UART2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12200)
#define DOVE_UART3_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12300)
#define DOVE_UART3_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12300)
#define DOVE_SPI0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x10600)
#define DOVE_SPI1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x14600)
/* North-South Bridge */
#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x20000)
/* Cryptographic Engine */
#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x30000)
/* PCIe 0 */
#define DOVE_PCIE0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x40000)
/* USB */
#define DOVE_USB0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x50000)
#define DOVE_USB1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x51000)
/* XOR 0 Engine */
#define DOVE_XOR0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60800)
#define DOVE_XOR0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60800)
#define DOVE_XOR0_HIGH_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60A00)
#define DOVE_XOR0_HIGH_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60A00)
/* XOR 1 Engine */
#define DOVE_XOR1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60900)
#define DOVE_XOR1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60900)
#define DOVE_XOR1_HIGH_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60B00)
#define DOVE_XOR1_HIGH_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60B00)
/* Gigabit Ethernet */
#define DOVE_GE00_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x70000)
/* PCIe 1 */
#define DOVE_PCIE1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x80000)
/* CAFE */
#define DOVE_SDIO0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x92000)
#define DOVE_SDIO1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x90000)
#define DOVE_CAM_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x94000)
#define DOVE_CAFE_WIN_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x98000)
/* SATA */
#define DOVE_SATA_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xa0000)
/* I2S/SPDIF */
#define DOVE_AUD0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xb0000)
#define DOVE_AUD1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xb4000)
/* NAND Flash Controller */
#define DOVE_NFC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xc0000)
/* MPP, GPIO, Reset Sampling */
#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200)
#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10)
#define DOVE_RESET_SAMPLE_LO (DOVE_MPP_VIRT_BASE | 0x014)
#define DOVE_RESET_SAMPLE_HI (DOVE_MPP_VIRT_BASE | 0x018)
#define DOVE_GPIO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400)
#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c)
#define DOVE_AU1_SPDIFO_GPIO_EN (1 << 1)
#define DOVE_NAND_GPIO_EN (1 << 0)
#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_VIRT_BASE + 0x40)
/* Power Management */
#define DOVE_PMU_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0000)
/* Real Time Clock */
#define DOVE_RTC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xd8500)
/* AC97 */
#define DOVE_AC97_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xe0000)
#define DOVE_AC97_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe0000)
/* Peripheral DMA */
#define DOVE_PDMA_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xe4000)
#define DOVE_PDMA_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe4000)
#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C)
#define DOVE_TWSI_ENABLE_OPTION1 (1 << 7)
#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030)
#define DOVE_TWSI_ENABLE_OPTION2 (1 << 20)
#define DOVE_TWSI_ENABLE_OPTION3 (1 << 21)
#define DOVE_TWSI_OPTION3_GPIO (1 << 22)
#define DOVE_SSP_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xec000)
#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034)
#define DOVE_SSP_ON_AU1 (1 << 0)
#define DOVE_SSP_CLOCK_ENABLE (1 << 1)
#define DOVE_SSP_BPB_CLOCK_SRC_SSP (1 << 11)
/* Memory Controller */
#define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE | 0x00000)
/* LCD Controller */
#define DOVE_LCD_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x10000)
#define DOVE_LCD1_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x20000)
#define DOVE_LCD2_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x10000)
#define DOVE_LCD_DCON_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x30000)
/* Graphic Engine */
#define DOVE_GPU_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x40000)
/* Video Engine */
#define DOVE_VPU_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x400000)
#endif
/*
* arch/arm/mach-dove/include/mach/entry-macro.S
*
* Low-level IRQ helper macros for Marvell Dove platforms
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <mach/bridge-regs.h>
.macro disable_fiq
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_preamble, base, tmp
ldr \base, =IRQ_VIRT_BASE
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
@ check low interrupts
ldr \irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
ldr \tmp, [\base, #IRQ_MASK_LOW_OFF]
mov \irqnr, #31
ands \irqstat, \irqstat, \tmp
@ if no low interrupts set, check high interrupts
ldreq \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
ldreq \tmp, [\base, #IRQ_MASK_HIGH_OFF]
moveq \irqnr, #63
andeqs \irqstat, \irqstat, \tmp
@ find first active interrupt source
clzne \irqstat, \irqstat
subne \irqnr, \irqnr, \irqstat
.endm
/*
* arch/arm/mach-dove/include/mach/gpio.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H
#include <asm/errno.h>
#include <mach/irqs.h>
#include <plat/gpio.h>
#include <asm-generic/gpio.h> /* cansleep wrappers */
#define GPIO_MAX 64
#define GPIO_BASE_LO (DOVE_GPIO_VIRT_BASE + 0x00)
#define GPIO_BASE_HI (DOVE_GPIO_VIRT_BASE + 0x20)
#define GPIO_BASE(pin) ((pin < 32) ? GPIO_BASE_LO : GPIO_BASE_HI)
#define GPIO_OUT(pin) (GPIO_BASE(pin) + 0x00)
#define GPIO_IO_CONF(pin) (GPIO_BASE(pin) + 0x04)
#define GPIO_BLINK_EN(pin) (GPIO_BASE(pin) + 0x08)
#define GPIO_IN_POL(pin) (GPIO_BASE(pin) + 0x0c)
#define GPIO_DATA_IN(pin) (GPIO_BASE(pin) + 0x10)
#define GPIO_EDGE_CAUSE(pin) (GPIO_BASE(pin) + 0x14)
#define GPIO_EDGE_MASK(pin) (GPIO_BASE(pin) + 0x18)
#define GPIO_LEVEL_MASK(pin) (GPIO_BASE(pin) + 0x1c)
static inline int gpio_to_irq(int pin)
{
if (pin < NR_GPIO_IRQS)
return pin + IRQ_DOVE_GPIO_START;
return -EINVAL;
}
static inline int irq_to_gpio(int irq)
{
if (IRQ_DOVE_GPIO_START < irq && irq < NR_IRQS)
return irq - IRQ_DOVE_GPIO_START;
return -EINVAL;
}
#endif
/*
* arch/arm/mach-dove/include/mach/hardware.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
#include "dove.h"
#define pcibios_assign_all_busses() 1
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x01000000
#define PCIMEM_BASE DOVE_PCIE0_MEM_PHYS_BASE
/* Macros below are required for compatibility with PXA AC'97 driver. */
#define __REG(x) (*((volatile u32 *)((x) - DOVE_SB_REGS_PHYS_BASE + \
DOVE_SB_REGS_VIRT_BASE)))
#define __PREG(x) (((u32)&(x)) - DOVE_SB_REGS_VIRT_BASE + \
DOVE_SB_REGS_PHYS_BASE)
#endif
/*
* arch/arm/mach-dove/include/mach/io.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#include "dove.h"
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\
DOVE_PCIE0_IO_VIRT_BASE))
#define __mem_pci(a) (a)
#endif
/*
* arch/arm/mach-dove/include/mach/irqs.h
*
* IRQ definitions for Marvell Dove 88AP510 SoC
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H
/*
* Dove Low Interrupt Controller
*/
#define IRQ_DOVE_BRIDGE 0
#define IRQ_DOVE_H2C 1
#define IRQ_DOVE_C2H 2
#define IRQ_DOVE_NAND 3
#define IRQ_DOVE_PDMA 4
#define IRQ_DOVE_SPI1 5
#define IRQ_DOVE_SPI0 6
#define IRQ_DOVE_UART_0 7
#define IRQ_DOVE_UART_1 8
#define IRQ_DOVE_UART_2 9
#define IRQ_DOVE_UART_3 10
#define IRQ_DOVE_I2C 11
#define IRQ_DOVE_GPIO_0_7 12
#define IRQ_DOVE_GPIO_8_15 13
#define IRQ_DOVE_GPIO_16_23 14
#define IRQ_DOVE_PCIE0_ERR 15
#define IRQ_DOVE_PCIE0 16
#define IRQ_DOVE_PCIE1_ERR 17
#define IRQ_DOVE_PCIE1 18
#define IRQ_DOVE_I2S0 19
#define IRQ_DOVE_I2S0_ERR 20
#define IRQ_DOVE_I2S1 21
#define IRQ_DOVE_I2S1_ERR 22
#define IRQ_DOVE_USB_ERR 23
#define IRQ_DOVE_USB0 24
#define IRQ_DOVE_USB1 25
#define IRQ_DOVE_GE00_RX 26
#define IRQ_DOVE_GE00_TX 27
#define IRQ_DOVE_GE00_MISC 28
#define IRQ_DOVE_GE00_SUM 29
#define IRQ_DOVE_GE00_ERR 30
#define IRQ_DOVE_CRYPTO 31
/*
* Dove High Interrupt Controller
*/
#define IRQ_DOVE_AC97 32
#define IRQ_DOVE_PMU 33
#define IRQ_DOVE_CAM 34
#define IRQ_DOVE_SDIO0 35
#define IRQ_DOVE_SDIO1 36
#define IRQ_DOVE_SDIO0_WAKEUP 37
#define IRQ_DOVE_SDIO1_WAKEUP 38
#define IRQ_DOVE_XOR_00 39
#define IRQ_DOVE_XOR_01 40
#define IRQ_DOVE_XOR0_ERR 41
#define IRQ_DOVE_XOR_10 42
#define IRQ_DOVE_XOR_11 43
#define IRQ_DOVE_XOR1_ERR 44
#define IRQ_DOVE_LCD_DCON 45
#define IRQ_DOVE_LCD1 46
#define IRQ_DOVE_LCD0 47
#define IRQ_DOVE_GPU 48
#define IRQ_DOVE_PERFORM_MNTR 49
#define IRQ_DOVE_VPRO_DMA1 51
#define IRQ_DOVE_SSP_TIMER 54
#define IRQ_DOVE_SSP 55
#define IRQ_DOVE_MC_L2_ERR 56
#define IRQ_DOVE_CRYPTO_ERR 59
#define IRQ_DOVE_GPIO_24_31 60
#define IRQ_DOVE_HIGH_GPIO 61
#define IRQ_DOVE_SATA 62
/*
* DOVE General Purpose Pins
*/
#define IRQ_DOVE_GPIO_START 64
#define NR_GPIO_IRQS 64
/*
* PMU interrupts
*/
#define IRQ_DOVE_PMU_START (IRQ_DOVE_GPIO_START + NR_GPIO_IRQS)
#define NR_PMU_IRQS 7
#define IRQ_DOVE_RTC (IRQ_DOVE_PMU_START + 5)
#define NR_IRQS (IRQ_DOVE_PMU_START + NR_PMU_IRQS)
/* Required for compatability with PXA AC97 driver. */
#define IRQ_AC97 IRQ_DOVE_AC97
/* Required for compatability with PXA DMA driver. */
#define IRQ_DMA IRQ_DOVE_PDMA
/* Required for compatability with PXA NAND driver */
#define IRQ_NAND IRQ_DOVE_NAND
#endif
/*
* arch/arm/mach-dove/include/mach/memory.h
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
#define PHYS_OFFSET UL(0x00000000)
#endif
/*
* arch/arm/mach-dove/include/mach/pm.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_PM_H
#define __ASM_ARCH_PM_H
#include <asm/errno.h>
#include <mach/irqs.h>
#define CLOCK_GATING_CONTROL (DOVE_PMU_VIRT_BASE + 0x38)
#define CLOCK_GATING_USB0_MASK (1 << 0)
#define CLOCK_GATING_USB1_MASK (1 << 1)
#define CLOCK_GATING_GBE_MASK (1 << 2)
#define CLOCK_GATING_SATA_MASK (1 << 3)
#define CLOCK_GATING_PCIE0_MASK (1 << 4)
#define CLOCK_GATING_PCIE1_MASK (1 << 5)
#define CLOCK_GATING_SDIO0_MASK (1 << 8)
#define CLOCK_GATING_SDIO1_MASK (1 << 9)
#define CLOCK_GATING_NAND_MASK (1 << 10)
#define CLOCK_GATING_CAMERA_MASK (1 << 11)
#define CLOCK_GATING_I2S0_MASK (1 << 12)
#define CLOCK_GATING_I2S1_MASK (1 << 13)
#define CLOCK_GATING_CRYPTO_MASK (1 << 15)
#define CLOCK_GATING_AC97_MASK (1 << 21)
#define CLOCK_GATING_PDMA_MASK (1 << 22)
#define CLOCK_GATING_XOR0_MASK (1 << 23)
#define CLOCK_GATING_XOR1_MASK (1 << 24)
#define CLOCK_GATING_GIGA_PHY_MASK (1 << 30)
#define PMU_INTERRUPT_CAUSE (DOVE_PMU_VIRT_BASE + 0x50)
#define PMU_INTERRUPT_MASK (DOVE_PMU_VIRT_BASE + 0x54)
static inline int pmu_to_irq(int pin)
{
if (pin < NR_PMU_IRQS)
return pin + IRQ_DOVE_PMU_START;
return -EINVAL;
}
static inline int irq_to_pmu(int irq)
{
if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
return irq - IRQ_DOVE_PMU_START;
return -EINVAL;
}
#endif
/*
* arch/arm/mach-dove/include/mach/system.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H
#include <mach/bridge-regs.h>
static inline void arch_idle(void)
{
cpu_do_idle();
}
static inline void arch_reset(char mode, const char *cmd)
{
/*
* Enable soft reset to assert RSTOUTn.
*/
writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
/*
* Assert soft reset.
*/
writel(SOFT_RESET, SYSTEM_SOFT_RESET);
while (1)
;
}
#endif
/*
* arch/arm/mach-dove/include/mach/timex.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#define CLOCK_TICK_RATE (100 * HZ)
/*
* arch/arm/mach-dove/include/mach/uncompress.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <mach/dove.h>
#define UART_THR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x0))
#define UART_LSR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x14))
#define LSR_THRE 0x20
static void putc(const char c)
{
int i;
for (i = 0; i < 0x1000; i++) {
/* Transmit fifo not full? */
if (*UART_LSR & LSR_THRE)
break;
}
*UART_THR = c;
}
static void flush(void)
{
}
/*
* nothing to do
*/
#define arch_decomp_setup()
#define arch_decomp_wdog()
/*
* arch/arm/mach-dove/include/mach/vmalloc.h
*/
#define VMALLOC_END 0xfd800000
/*
* arch/arm/mach-dove/irq.c
*
* Dove IRQ handling.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <asm/mach/arch.h>
#include <plat/irq.h>
#include <asm/mach/irq.h>
#include <mach/pm.h>
#include <mach/bridge-regs.h>
#include "common.h"
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
int irqoff;
BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO);
irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 :
3 + irq - IRQ_DOVE_GPIO_24_31;
orion_gpio_irq_handler(irqoff << 3);
if (irq == IRQ_DOVE_HIGH_GPIO) {
orion_gpio_irq_handler(40);
orion_gpio_irq_handler(48);
orion_gpio_irq_handler(56);
}
}
static void pmu_irq_mask(unsigned int irq)
{
int pin = irq_to_pmu(irq);
u32 u;
u = readl(PMU_INTERRUPT_MASK);
u &= ~(1 << (pin & 31));
writel(u, PMU_INTERRUPT_MASK);
}
static void pmu_irq_unmask(unsigned int irq)
{
int pin = irq_to_pmu(irq);
u32 u;
u = readl(PMU_INTERRUPT_MASK);
u |= 1 << (pin & 31);
writel(u, PMU_INTERRUPT_MASK);
}
static void pmu_irq_ack(unsigned int irq)
{
int pin = irq_to_pmu(irq);
u32 u;
u = ~(1 << (pin & 31));
writel(u, PMU_INTERRUPT_CAUSE);
}
static struct irq_chip pmu_irq_chip = {
.name = "pmu_irq",
.mask = pmu_irq_mask,
.unmask = pmu_irq_unmask,
.ack = pmu_irq_ack,
};
static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
{
unsigned long cause = readl(PMU_INTERRUPT_CAUSE);
cause &= readl(PMU_INTERRUPT_MASK);
if (cause == 0) {
do_bad_IRQ(irq, desc);
return;
}
for (irq = 0; irq < NR_PMU_IRQS; irq++) {
if (!(cause & (1 << irq)))
continue;
irq = pmu_to_irq(irq);
desc = irq_desc + irq;
desc_handle_irq(irq, desc);
}
}
void __init dove_init_irq(void)
{
int i;
orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
/*
* Mask and clear GPIO IRQ interrupts.
*/
writel(0, GPIO_LEVEL_MASK(0));
writel(0, GPIO_EDGE_MASK(0));
writel(0, GPIO_EDGE_CAUSE(0));
/*
* Mask and clear PMU interrupts
*/
writel(0, PMU_INTERRUPT_MASK);
writel(0, PMU_INTERRUPT_CAUSE);
for (i = IRQ_DOVE_GPIO_START; i < IRQ_DOVE_PMU_START; i++) {
set_irq_chip(i, &orion_gpio_irq_chip);
set_irq_handler(i, handle_level_irq);
irq_desc[i].status |= IRQ_LEVEL;
set_irq_flags(i, IRQF_VALID);
}
set_irq_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
set_irq_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
set_irq_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
set_irq_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);
set_irq_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);
for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) {
set_irq_chip(i, &pmu_irq_chip);
set_irq_handler(i, handle_level_irq);
irq_desc[i].status |= IRQ_LEVEL;
set_irq_flags(i, IRQF_VALID);
}
set_irq_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
}
/*
* arch/arm/mach-dove/pcie.c
*
* PCIe functions for Marvell Dove 88AP510 SoC
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/mbus.h>
#include <asm/mach/pci.h>
#include <asm/mach/arch.h>
#include <asm/setup.h>
#include <asm/delay.h>
#include <plat/pcie.h>
#include <mach/irqs.h>
#include <mach/bridge-regs.h>
#include "common.h"
struct pcie_port {
u8 index;
u8 root_bus_nr;
void __iomem *base;
spinlock_t conf_lock;
char io_space_name[16];
char mem_space_name[16];
struct resource res[2];
};
static struct pcie_port pcie_port[2];
static int num_pcie_ports;
static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
{
struct pcie_port *pp;
if (nr >= num_pcie_ports)
return 0;
pp = &pcie_port[nr];
pp->root_bus_nr = sys->busnr;
/*
* Generic PCIe unit setup.
*/
orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
orion_pcie_setup(pp->base, &dove_mbus_dram_info);
/*
* IORESOURCE_IO
*/
snprintf(pp->io_space_name, sizeof(pp->io_space_name),
"PCIe %d I/O", pp->index);
pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
pp->res[0].name = pp->io_space_name;
if (pp->index == 0) {
pp->res[0].start = DOVE_PCIE0_IO_PHYS_BASE;
pp->res[0].end = pp->res[0].start + DOVE_PCIE0_IO_SIZE - 1;
} else {
pp->res[0].start = DOVE_PCIE1_IO_PHYS_BASE;
pp->res[0].end = pp->res[0].start + DOVE_PCIE1_IO_SIZE - 1;
}
pp->res[0].flags = IORESOURCE_IO;
if (request_resource(&ioport_resource, &pp->res[0]))
panic("Request PCIe IO resource failed\n");
sys->resource[0] = &pp->res[0];
/*
* IORESOURCE_MEM
*/
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d MEM", pp->index);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
pp->res[1].name = pp->mem_space_name;
if (pp->index == 0) {
pp->res[1].start = DOVE_PCIE0_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + DOVE_PCIE0_MEM_SIZE - 1;
} else {
pp->res[1].start = DOVE_PCIE1_MEM_PHYS_BASE;
pp->res[1].end = pp->res[1].start + DOVE_PCIE1_MEM_SIZE - 1;
}
pp->res[1].flags = IORESOURCE_MEM;
if (request_resource(&iomem_resource, &pp->res[1]))
panic("Request PCIe Memory resource failed\n");
sys->resource[1] = &pp->res[1];
sys->resource[2] = NULL;
return 1;
}
static struct pcie_port *bus_to_port(int bus)
{
int i;
for (i = num_pcie_ports - 1; i >= 0; i--) {
int rbus = pcie_port[i].root_bus_nr;
if (rbus != -1 && rbus <= bus)
break;
}
return i >= 0 ? pcie_port + i : NULL;
}
static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
{
/*
* Don't go out when trying to access nonexisting devices
* on the local bus.
*/
if (bus == pp->root_bus_nr && dev > 1)
return 0;
return 1;
}
static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int size, u32 *val)
{
struct pcie_port *pp = bus_to_port(bus->number);
unsigned long flags;
int ret;
if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
*val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND;
}
spin_lock_irqsave(&pp->conf_lock, flags);
ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
spin_unlock_irqrestore(&pp->conf_lock, flags);
return ret;
}
static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 val)
{
struct pcie_port *pp = bus_to_port(bus->number);
unsigned long flags;
int ret;
if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
return PCIBIOS_DEVICE_NOT_FOUND;
spin_lock_irqsave(&pp->conf_lock, flags);
ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
spin_unlock_irqrestore(&pp->conf_lock, flags);
return ret;
}
static struct pci_ops pcie_ops = {
.read = pcie_rd_conf,
.write = pcie_wr_conf,
};
static void __devinit rc_pci_fixup(struct pci_dev *dev)
{
/*
* Prevent enumeration of root complex.
*/
if (dev->bus->parent == NULL && dev->devfn == 0) {
int i;
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
dev->resource[i].start = 0;
dev->resource[i].end = 0;
dev->resource[i].flags = 0;
}
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
static struct pci_bus __init *
dove_pcie_scan_bus(int nr, struct pci_sys_data *sys)
{
struct pci_bus *bus;
if (nr < num_pcie_ports) {
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
} else {
bus = NULL;
BUG();
}
return bus;
}
static int __init dove_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
struct pcie_port *pp = bus_to_port(dev->bus->number);
return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0;
}
static struct hw_pci dove_pci __initdata = {
.nr_controllers = 2,
.swizzle = pci_std_swizzle,
.setup = dove_pcie_setup,
.scan = dove_pcie_scan_bus,
.map_irq = dove_pcie_map_irq,
};
static void __init add_pcie_port(int index, unsigned long base)
{
printk(KERN_INFO "Dove PCIe port %d: ", index);
if (orion_pcie_link_up((void __iomem *)base)) {
struct pcie_port *pp = &pcie_port[num_pcie_ports++];
printk(KERN_INFO "link up\n");
pp->index = index;
pp->root_bus_nr = -1;
pp->base = (void __iomem *)base;
spin_lock_init(&pp->conf_lock);
memset(pp->res, 0, sizeof(pp->res));
} else {
printk(KERN_INFO "link down, ignoring\n");
}
}
void __init dove_pcie_init(int init_port0, int init_port1)
{
if (init_port0)
add_pcie_port(0, DOVE_PCIE0_VIRT_BASE);
if (init_port1)
add_pcie_port(1, DOVE_PCIE1_VIRT_BASE);
pci_common_init(&dove_pci);
}
...@@ -388,7 +388,7 @@ config CPU_FEROCEON_OLD_ID ...@@ -388,7 +388,7 @@ config CPU_FEROCEON_OLD_ID
# ARMv6 # ARMv6
config CPU_V6 config CPU_V6
bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || ARCH_DOVE
select CPU_32v6 select CPU_32v6
select CPU_ABRT_EV6 select CPU_ABRT_EV6
select CPU_PABRT_V6 select CPU_PABRT_V6
......
...@@ -130,9 +130,16 @@ ENTRY(cpu_v6_set_pte_ext) ...@@ -130,9 +130,16 @@ ENTRY(cpu_v6_set_pte_ext)
.type cpu_v6_name, #object
cpu_v6_name: cpu_v6_name:
.asciz "ARMv6-compatible processor" .asciz "ARMv6-compatible processor"
.size cpu_v6_name, . - cpu_v6_name
.type cpu_pj4_name, #object
cpu_pj4_name:
.asciz "Marvell PJ4 processor"
.size cpu_pj4_name, . - cpu_pj4_name
.align .align
__INIT __INIT
...@@ -241,3 +248,27 @@ __v6_proc_info: ...@@ -241,3 +248,27 @@ __v6_proc_info:
.long v6_user_fns .long v6_user_fns
.long v6_cache_fns .long v6_cache_fns
.size __v6_proc_info, . - __v6_proc_info .size __v6_proc_info, . - __v6_proc_info
.type __pj4_v6_proc_info, #object
__pj4_v6_proc_info:
.long 0x560f5810
.long 0xff0ffff0
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
b __v6_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
.long cpu_pj4_name
.long v6_processor_functions
.long v6wbi_tlb_fns
.long v6_user_fns
.long v6_cache_fns
.size __pj4_v6_proc_info, . - __pj4_v6_proc_info
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册