Merge branch 'for-rmk' of git://git.marvell.com/orion into devel-stable

This commit is contained in:
Russell King 2009-12-01 18:22:54 +00:00
commit d7931d9f7a
39 changed files with 4356 additions and 110 deletions

View File

@ -433,6 +433,17 @@ config ARCH_L7200
If you have any questions or comments about the Linux kernel port
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
bool "Marvell Kirkwood"
select CPU_FEROCEON
@ -747,6 +758,8 @@ source "arch/arm/mach-orion5x/Kconfig"
source "arch/arm/mach-kirkwood/Kconfig"
source "arch/arm/mach-dove/Kconfig"
source "arch/arm/plat-s3c24xx/Kconfig"
source "arch/arm/plat-s3c64xx/Kconfig"
source "arch/arm/plat-s3c/Kconfig"

View File

@ -122,6 +122,7 @@ machine-$(CONFIG_ARCH_AT91) := at91
machine-$(CONFIG_ARCH_BCMRING) := bcmring
machine-$(CONFIG_ARCH_CLPS711X) := clps711x
machine-$(CONFIG_ARCH_DAVINCI) := davinci
machine-$(CONFIG_ARCH_DOVE) := dove
machine-$(CONFIG_ARCH_EBSA110) := ebsa110
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_GEMINI) := gemini

View File

@ -743,6 +743,12 @@ proc_types:
W(b) __armv4_mmu_cache_off
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
W(b) __armv7_mmu_cache_on

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
/*
* arch/arm/include/asm/hardware/cache-tauros2.h
*
* Copyright (C) 2008 Marvell Semiconductor
*
* 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.
*/
extern void __init tauros2_init(void);

View File

@ -0,0 +1,14 @@
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

View File

@ -0,0 +1,3 @@
obj-y += common.o addr-map.o irq.o pcie.o
obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o

View File

@ -0,0 +1,3 @@
zreladdr-y := 0x00008000
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000

View File

@ -0,0 +1,149 @@
/*
* 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;
}

781
arch/arm/mach-dove/common.c Normal file
View File

@ -0,0 +1,781 @@
/*
* 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/hardware/cache-tauros2.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);
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init();
#endif
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();
}

View File

@ -0,0 +1,40 @@
/*
* 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

View File

@ -0,0 +1,102 @@
/*
* 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

View File

@ -0,0 +1,58 @@
/*
* 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

View File

@ -0,0 +1,20 @@
/*
* 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>

View File

@ -0,0 +1,180 @@
/*
* 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

View File

@ -0,0 +1,39 @@
/*
* 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

View File

@ -0,0 +1,49 @@
/*
* 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

View File

@ -0,0 +1,26 @@
/*
* 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

View File

@ -0,0 +1,20 @@
/*
* 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

View File

@ -0,0 +1,101 @@
/*
* 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

View File

@ -0,0 +1,10 @@
/*
* arch/arm/mach-dove/include/mach/memory.h
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
#define PHYS_OFFSET UL(0x00000000)
#endif

View File

@ -0,0 +1,54 @@
/*
* 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

View File

@ -0,0 +1,36 @@
/*
* 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

View File

@ -0,0 +1,9 @@
/*
* 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)

View File

@ -0,0 +1,37 @@
/*
* 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()

View File

@ -0,0 +1,5 @@
/*
* arch/arm/mach-dove/include/mach/vmalloc.h
*/
#define VMALLOC_END 0xfd800000

133
arch/arm/mach-dove/irq.c Normal file
View File

@ -0,0 +1,133 @@
/*
* 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);
}

238
arch/arm/mach-dove/pcie.c Normal file
View File

@ -0,0 +1,238 @@
/*
* 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);
}

View File

@ -33,10 +33,18 @@ config MACH_SHEEVAPLUG
Marvell SheevaPlug Reference Board.
config MACH_TS219
bool "QNAP TS-119 and TS-219 Turbo NAS"
bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS"
help
Say 'Y' here if you want your kernel to support the
QNAP TS-119 and TS-219 Turbo NAS devices.
QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS
devices.
config MACH_TS41X
bool "QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS"
help
Say 'Y' here if you want your kernel to support the
QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
devices.
config MACH_OPENRD_BASE
bool "Marvell OpenRD Base Board"

View File

@ -5,7 +5,8 @@ obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o
obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o
obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o
obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
obj-$(CONFIG_MACH_TS219) += ts219-setup.o
obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o
obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o
obj-$(CONFIG_MACH_OPENRD_BASE) += openrd_base-setup.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o

View File

@ -1,6 +1,6 @@
/*
*
* QNAP TS-119/TS-219 Turbo NAS Board Setup
* QNAP TS-11x/TS-21x Turbo NAS Board Setup
*
* Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com>
* Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com>
@ -14,87 +14,17 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/i2c.h>
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/timex.h>
#include <linux/serial_reg.h>
#include <linux/pci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
/****************************************************************************
* 16 MiB NOR flash. The struct mtd_partition is not in the same order as the
* partitions on the device because we want to keep compatability with
* the QNAP firmware.
* Layout as used by QNAP:
* 0x00000000-0x00080000 : "U-Boot"
* 0x00200000-0x00400000 : "Kernel"
* 0x00400000-0x00d00000 : "RootFS"
* 0x00d00000-0x01000000 : "RootFS2"
* 0x00080000-0x000c0000 : "U-Boot Config"
* 0x000c0000-0x00200000 : "NAS Config"
*
* We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout
* used by the QNAP TS-109/TS-209.
*
***************************************************************************/
static struct mtd_partition qnap_ts219_partitions[] = {
{
.name = "U-Boot",
.size = 0x00080000,
.offset = 0,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "Kernel",
.size = 0x00200000,
.offset = 0x00200000,
}, {
.name = "RootFS1",
.size = 0x00900000,
.offset = 0x00400000,
}, {
.name = "RootFS2",
.size = 0x00300000,
.offset = 0x00d00000,
}, {
.name = "U-Boot Config",
.size = 0x00040000,
.offset = 0x00080000,
}, {
.name = "NAS Config",
.size = 0x00140000,
.offset = 0x000c0000,
},
};
static const struct flash_platform_data qnap_ts219_flash = {
.type = "m25p128",
.name = "spi_flash",
.parts = qnap_ts219_partitions,
.nr_parts = ARRAY_SIZE(qnap_ts219_partitions),
};
static struct spi_board_info __initdata qnap_ts219_spi_slave_info[] = {
{
.modalias = "m25p80",
.platform_data = &qnap_ts219_flash,
.irq = -1,
.max_speed_hz = 20000000,
.bus_num = 0,
.chip_select = 0,
},
};
#include "tsx1x-common.h"
static struct i2c_board_info __initdata qnap_ts219_i2c_rtc = {
I2C_BOARD_INFO("s35390a", 0x30),
@ -152,36 +82,10 @@ static unsigned int qnap_ts219_mpp_config[] __initdata = {
MPP14_UART1_RXD, /* PIC controller */
MPP15_GPIO, /* USB Copy button */
MPP16_GPIO, /* Reset button */
MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */
0
};
/*****************************************************************************
* QNAP TS-x19 specific power off method via UART1-attached PIC
****************************************************************************/
#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
void qnap_ts219_power_off(void)
{
/* 19200 baud divisor */
const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200));
pr_info("%s: triggering power-off...\n", __func__);
/* hijack UART1 and reset into sane state (19200,8n1) */
writel(0x83, UART1_REG(LCR));
writel(divisor & 0xff, UART1_REG(DLL));
writel((divisor >> 8) & 0xff, UART1_REG(DLM));
writel(0x03, UART1_REG(LCR));
writel(0x00, UART1_REG(IER));
writel(0x00, UART1_REG(FCR));
writel(0x00, UART1_REG(MCR));
/* send the power-off command 'A' to PIC */
writel('A', UART1_REG(TX));
}
static void __init qnap_ts219_init(void)
{
/*
@ -192,9 +96,7 @@ static void __init qnap_ts219_init(void)
kirkwood_uart0_init();
kirkwood_uart1_init(); /* A PIC controller is connected here. */
spi_register_board_info(qnap_ts219_spi_slave_info,
ARRAY_SIZE(qnap_ts219_spi_slave_info));
kirkwood_spi_init();
qnap_tsx1x_register_flash();
kirkwood_i2c_init();
i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1);
kirkwood_ge00_init(&qnap_ts219_ge00_data);
@ -202,7 +104,7 @@ static void __init qnap_ts219_init(void)
kirkwood_ehci_init();
platform_device_register(&qnap_ts219_button_device);
pm_power_off = qnap_ts219_power_off;
pm_power_off = qnap_tsx1x_power_off;
}

View File

@ -0,0 +1,154 @@
/*
*
* QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS Board Setup
*
* Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com>
* Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com>
*
* 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/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
#include "tsx1x-common.h"
static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = {
I2C_BOARD_INFO("s35390a", 0x30),
};
static struct mv643xx_eth_platform_data qnap_ts41x_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
static struct mv643xx_eth_platform_data qnap_ts41x_ge01_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
};
static struct mv_sata_platform_data qnap_ts41x_sata_data = {
.n_ports = 2,
};
static struct gpio_keys_button qnap_ts41x_buttons[] = {
{
.code = KEY_COPY,
.gpio = 43,
.desc = "USB Copy",
.active_low = 1,
},
{
.code = KEY_RESTART,
.gpio = 37,
.desc = "Reset",
.active_low = 1,
},
};
static struct gpio_keys_platform_data qnap_ts41x_button_data = {
.buttons = qnap_ts41x_buttons,
.nbuttons = ARRAY_SIZE(qnap_ts41x_buttons),
};
static struct platform_device qnap_ts41x_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.dev = {
.platform_data = &qnap_ts41x_button_data,
}
};
static unsigned int qnap_ts41x_mpp_config[] __initdata = {
MPP0_SPI_SCn,
MPP1_SPI_MOSI,
MPP2_SPI_SCK,
MPP3_SPI_MISO,
MPP6_SYSRST_OUTn,
MPP7_PEX_RST_OUTn,
MPP8_TW_SDA,
MPP9_TW_SCK,
MPP10_UART0_TXD,
MPP11_UART0_RXD,
MPP13_UART1_TXD, /* PIC controller */
MPP14_UART1_RXD, /* PIC controller */
MPP15_SATA0_ACTn,
MPP16_SATA1_ACTn,
MPP20_GE1_0,
MPP21_GE1_1,
MPP22_GE1_2,
MPP23_GE1_3,
MPP24_GE1_4,
MPP25_GE1_5,
MPP26_GE1_6,
MPP27_GE1_7,
MPP30_GE1_10,
MPP31_GE1_11,
MPP32_GE1_12,
MPP33_GE1_13,
MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */
MPP37_GPIO, /* Reset button */
MPP43_GPIO, /* USB Copy button */
MPP44_GPIO, /* Board ID: 0: TS-419U, 1: TS-419 */
MPP45_GPIO, /* JP1: 0: console, 1: LCD */
MPP46_GPIO, /* External SATA HDD1 error indicator */
MPP47_GPIO, /* External SATA HDD2 error indicator */
MPP48_GPIO, /* External SATA HDD3 error indicator */
MPP49_GPIO, /* External SATA HDD4 error indicator */
0
};
static void __init qnap_ts41x_init(void)
{
/*
* Basic setup. Needs to be called early.
*/
kirkwood_init();
kirkwood_mpp_conf(qnap_ts41x_mpp_config);
kirkwood_uart0_init();
kirkwood_uart1_init(); /* A PIC controller is connected here. */
qnap_tsx1x_register_flash();
kirkwood_i2c_init();
i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1);
kirkwood_ge00_init(&qnap_ts41x_ge00_data);
kirkwood_ge01_init(&qnap_ts41x_ge01_data);
kirkwood_sata_init(&qnap_ts41x_sata_data);
kirkwood_ehci_init();
platform_device_register(&qnap_ts41x_button_device);
pm_power_off = qnap_tsx1x_power_off;
}
static int __init ts41x_pci_init(void)
{
if (machine_is_ts41x())
kirkwood_pcie_init();
return 0;
}
subsys_initcall(ts41x_pci_init);
MACHINE_START(TS41X, "QNAP TS-41x")
/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
.phys_io = KIRKWOOD_REGS_PHYS_BASE,
.io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.init_machine = qnap_ts41x_init,
.map_io = kirkwood_map_io,
.init_irq = kirkwood_init_irq,
.timer = &kirkwood_timer,
MACHINE_END

View File

@ -0,0 +1,113 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/serial_reg.h>
#include <mach/kirkwood.h>
#include "common.h"
/*
* QNAP TS-x1x Boards flash
*/
/****************************************************************************
* 16 MiB NOR flash. The struct mtd_partition is not in the same order as the
* partitions on the device because we want to keep compatability with
* the QNAP firmware.
* Layout as used by QNAP:
* 0x00000000-0x00080000 : "U-Boot"
* 0x00200000-0x00400000 : "Kernel"
* 0x00400000-0x00d00000 : "RootFS"
* 0x00d00000-0x01000000 : "RootFS2"
* 0x00080000-0x000c0000 : "U-Boot Config"
* 0x000c0000-0x00200000 : "NAS Config"
*
* We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout
* used by the QNAP TS-109/TS-209.
*
***************************************************************************/
struct mtd_partition qnap_tsx1x_partitions[] = {
{
.name = "U-Boot",
.size = 0x00080000,
.offset = 0,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "Kernel",
.size = 0x00200000,
.offset = 0x00200000,
}, {
.name = "RootFS1",
.size = 0x00900000,
.offset = 0x00400000,
}, {
.name = "RootFS2",
.size = 0x00300000,
.offset = 0x00d00000,
}, {
.name = "U-Boot Config",
.size = 0x00040000,
.offset = 0x00080000,
}, {
.name = "NAS Config",
.size = 0x00140000,
.offset = 0x000c0000,
},
};
const struct flash_platform_data qnap_tsx1x_flash = {
.type = "m25p128",
.name = "spi_flash",
.parts = qnap_tsx1x_partitions,
.nr_parts = ARRAY_SIZE(qnap_tsx1x_partitions),
};
struct spi_board_info __initdata qnap_tsx1x_spi_slave_info[] = {
{
.modalias = "m25p80",
.platform_data = &qnap_tsx1x_flash,
.irq = -1,
.max_speed_hz = 20000000,
.bus_num = 0,
.chip_select = 0,
},
};
void qnap_tsx1x_register_flash(void)
{
spi_register_board_info(qnap_tsx1x_spi_slave_info,
ARRAY_SIZE(qnap_tsx1x_spi_slave_info));
kirkwood_spi_init();
}
/*****************************************************************************
* QNAP TS-x1x specific power off method via UART1-attached PIC
****************************************************************************/
#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
void qnap_tsx1x_power_off(void)
{
/* 19200 baud divisor */
const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200));
pr_info("%s: triggering power-off...\n", __func__);
/* hijack UART1 and reset into sane state (19200,8n1) */
writel(0x83, UART1_REG(LCR));
writel(divisor & 0xff, UART1_REG(DLL));
writel((divisor >> 8) & 0xff, UART1_REG(DLM));
writel(0x03, UART1_REG(LCR));
writel(0x00, UART1_REG(IER));
writel(0x00, UART1_REG(FCR));
writel(0x00, UART1_REG(MCR));
/* send the power-off command 'A' to PIC */
writel('A', UART1_REG(TX));
}

View File

@ -0,0 +1,7 @@
#ifndef __ARCH_KIRKWOOD_TSX1X_COMMON_H
#define __ARCH_KIRKWOOD_TSX1X_COMMON_H
extern void qnap_tsx1x_register_flash(void);
extern void qnap_tsx1x_power_off(void);
#endif

View File

@ -388,7 +388,7 @@ config CPU_FEROCEON_OLD_ID
# ARMv6
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_ABRT_EV6
select CPU_PABRT_V6
@ -764,6 +764,15 @@ config CACHE_L2X0
help
This option enables the L2x0 PrimeCell.
config CACHE_TAUROS2
bool "Enable the Tauros2 L2 cache controller"
depends on ARCH_DOVE
default y
select OUTER_CACHE
help
This option enables the Tauros2 L2 cache controller (as
found on PJ1/PJ4).
config CACHE_XSC3L2
bool "Enable the L2 cache on XScale3"
depends on CPU_XSC3

View File

@ -87,4 +87,4 @@ obj-$(CONFIG_CPU_V7) += proc-v7.o
obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o
obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o

263
arch/arm/mm/cache-tauros2.c Normal file
View File

@ -0,0 +1,263 @@
/*
* arch/arm/mm/cache-tauros2.c - Tauros2 L2 cache controller support
*
* Copyright (C) 2008 Marvell Semiconductor
*
* 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.
*
* References:
* - PJ1 CPU Core Datasheet,
* Document ID MV-S104837-01, Rev 0.7, January 24 2008.
* - PJ4 CPU Core Datasheet,
* Document ID MV-S105190-00, Rev 0.7, March 14 2008.
*/
#include <linux/init.h>
#include <asm/cacheflush.h>
#include <asm/hardware/cache-tauros2.h>
/*
* When Tauros2 is used on a CPU that supports the v7 hierarchical
* cache operations, the cache handling code in proc-v7.S takes care
* of everything, including handling DMA coherency.
*
* So, we only need to register outer cache operations here if we're
* being used on a pre-v7 CPU, and we only need to build support for
* outer cache operations into the kernel image if the kernel has been
* configured to support a pre-v7 CPU.
*/
#if __LINUX_ARM_ARCH__ < 7
/*
* Low-level cache maintenance operations.
*/
static inline void tauros2_clean_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c7, c11, 3" : : "r" (addr));
}
static inline void tauros2_clean_inv_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c7, c15, 3" : : "r" (addr));
}
static inline void tauros2_inv_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c7, c7, 3" : : "r" (addr));
}
/*
* Linux primitives.
*
* Note that the end addresses passed to Linux primitives are
* noninclusive.
*/
#define CACHE_LINE_SIZE 32
static void tauros2_inv_range(unsigned long start, unsigned long end)
{
/*
* Clean and invalidate partial first cache line.
*/
if (start & (CACHE_LINE_SIZE - 1)) {
tauros2_clean_inv_pa(start & ~(CACHE_LINE_SIZE - 1));
start = (start | (CACHE_LINE_SIZE - 1)) + 1;
}
/*
* Clean and invalidate partial last cache line.
*/
if (end & (CACHE_LINE_SIZE - 1)) {
tauros2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
end &= ~(CACHE_LINE_SIZE - 1);
}
/*
* Invalidate all full cache lines between 'start' and 'end'.
*/
while (start < end) {
tauros2_inv_pa(start);
start += CACHE_LINE_SIZE;
}
dsb();
}
static void tauros2_clean_range(unsigned long start, unsigned long end)
{
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
tauros2_clean_pa(start);
start += CACHE_LINE_SIZE;
}
dsb();
}
static void tauros2_flush_range(unsigned long start, unsigned long end)
{
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
tauros2_clean_inv_pa(start);
start += CACHE_LINE_SIZE;
}
dsb();
}
#endif
static inline u32 __init read_extra_features(void)
{
u32 u;
__asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (u));
return u;
}
static inline void __init write_extra_features(u32 u)
{
__asm__("mcr p15, 1, %0, c15, c1, 0" : : "r" (u));
}
static void __init disable_l2_prefetch(void)
{
u32 u;
/*
* Read the CPU Extra Features register and verify that the
* Disable L2 Prefetch bit is set.
*/
u = read_extra_features();
if (!(u & 0x01000000)) {
printk(KERN_INFO "Tauros2: Disabling L2 prefetch.\n");
write_extra_features(u | 0x01000000);
}
}
static inline int __init cpuid_scheme(void)
{
extern int processor_id;
return !!((processor_id & 0x000f0000) == 0x000f0000);
}
static inline u32 __init read_mmfr3(void)
{
u32 mmfr3;
__asm__("mrc p15, 0, %0, c0, c1, 7\n" : "=r" (mmfr3));
return mmfr3;
}
static inline u32 __init read_actlr(void)
{
u32 actlr;
__asm__("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
return actlr;
}
static inline void __init write_actlr(u32 actlr)
{
__asm__("mcr p15, 0, %0, c1, c0, 1\n" : : "r" (actlr));
}
void __init tauros2_init(void)
{
extern int processor_id;
char *mode;
disable_l2_prefetch();
#ifdef CONFIG_CPU_32v5
if ((processor_id & 0xff0f0000) == 0x56050000) {
u32 feat;
/*
* v5 CPUs with Tauros2 have the L2 cache enable bit
* located in the CPU Extra Features register.
*/
feat = read_extra_features();
if (!(feat & 0x00400000)) {
printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
write_extra_features(feat | 0x00400000);
}
mode = "ARMv5";
outer_cache.inv_range = tauros2_inv_range;
outer_cache.clean_range = tauros2_clean_range;
outer_cache.flush_range = tauros2_flush_range;
}
#endif
#ifdef CONFIG_CPU_32v6
/*
* Check whether this CPU lacks support for the v7 hierarchical
* cache ops. (PJ4 is in its v6 personality mode if the MMFR3
* register indicates no support for the v7 hierarchical cache
* ops.)
*/
if (cpuid_scheme() && (read_mmfr3() & 0xf) == 0) {
/*
* When Tauros2 is used in an ARMv6 system, the L2
* enable bit is in the ARMv6 ARM-mandated position
* (bit [26] of the System Control Register).
*/
if (!(get_cr() & 0x04000000)) {
printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
adjust_cr(0x04000000, 0x04000000);
}
mode = "ARMv6";
outer_cache.inv_range = tauros2_inv_range;
outer_cache.clean_range = tauros2_clean_range;
outer_cache.flush_range = tauros2_flush_range;
}
#endif
#ifdef CONFIG_CPU_32v7
/*
* Check whether this CPU has support for the v7 hierarchical
* cache ops. (PJ4 is in its v7 personality mode if the MMFR3
* register indicates support for the v7 hierarchical cache
* ops.)
*
* (Although strictly speaking there may exist CPUs that
* implement the v7 cache ops but are only ARMv6 CPUs (due to
* not complying with all of the other ARMv7 requirements),
* there are no real-life examples of Tauros2 being used on
* such CPUs as of yet.)
*/
if (cpuid_scheme() && (read_mmfr3() & 0xf) == 1) {
u32 actlr;
/*
* When Tauros2 is used in an ARMv7 system, the L2
* enable bit is located in the Auxiliary System Control
* Register (which is the only register allowed by the
* ARMv7 spec to contain fine-grained cache control bits).
*/
actlr = read_actlr();
if (!(actlr & 0x00000002)) {
printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
write_actlr(actlr | 0x00000002);
}
mode = "ARMv7";
}
#endif
if (mode == NULL) {
printk(KERN_CRIT "Tauros2: Unable to detect CPU mode.\n");
return;
}
printk(KERN_INFO "Tauros2: L2 cache support initialised "
"in %s mode.\n", mode);
}

View File

@ -130,9 +130,16 @@ ENTRY(cpu_v6_set_pte_ext)
.type cpu_v6_name, #object
cpu_v6_name:
.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
__INIT
@ -241,3 +248,27 @@ __v6_proc_info:
.long v6_user_fns
.long v6_cache_fns
.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

View File

@ -780,7 +780,7 @@ config RTC_DRV_TX4939
config RTC_DRV_MV
tristate "Marvell SoC RTC"
depends on ARCH_KIRKWOOD
depends on ARCH_KIRKWOOD || ARCH_DOVE
help
If you say yes here you will get support for the in-chip RTC
that can be found in some of Marvell's SoC devices, such as