Commit 6defd904 authored by Russell King's avatar Russell King Committed by Russell King

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

Merge branch 'orion-devel' into devel
parents c97f6814 99c6bb39
......@@ -441,7 +441,7 @@ config ARCH_ORION5X
help
Support for the following Marvell Orion 5x series SoCs:
Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
Orion-2 (5281).
Orion-2 (5281), Orion-1-90 (6183).
config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile"
......
......@@ -176,14 +176,17 @@ CONFIG_MACH_KUROBOX_PRO=y
CONFIG_MACH_DNS323=y
CONFIG_MACH_TS209=y
CONFIG_MACH_LINKSTATION_PRO=y
CONFIG_MACH_LINKSTATION_MINI=y
CONFIG_MACH_TS409=y
CONFIG_MACH_WRT350N_V2=y
CONFIG_MACH_TS78XX=y
CONFIG_MACH_MV2120=y
CONFIG_MACH_EDMINI_V2=y
CONFIG_MACH_MSS2=y
CONFIG_MACH_WNR854T=y
CONFIG_MACH_RD88F5181L_GE=y
CONFIG_MACH_RD88F5181L_FXO=y
CONFIG_MACH_RD88F6183AP_GE=y
#
# Boot options
......
......@@ -48,6 +48,7 @@
struct mbus_dram_target_info kirkwood_mbus_dram_info;
static int __initdata win_alloc_count;
static int __init cpu_win_can_remap(int win)
{
......@@ -111,6 +112,8 @@ void __init kirkwood_setup_cpu_mbus(void)
setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
win_alloc_count = 3;
/*
* Setup MBUS dram target info.
*/
......@@ -137,3 +140,8 @@ void __init kirkwood_setup_cpu_mbus(void)
}
kirkwood_mbus_dram_info.num_cs = cs;
}
void __init kirkwood_setup_sram_win(u32 base, u32 size)
{
setup_cpu_win(win_alloc_count++, base, size, 0x03, 0x00, -1);
}
......@@ -98,7 +98,6 @@ void __init kirkwood_ehci_init(void)
* GE00
****************************************************************************/
struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = {
.t_clk = KIRKWOOD_TCLK,
.dram = &kirkwood_mbus_dram_info,
};
......@@ -108,6 +107,11 @@ static struct resource kirkwood_ge00_shared_resources[] = {
.start = GE00_PHYS_BASE + 0x2000,
.end = GE00_PHYS_BASE + 0x3fff,
.flags = IORESOURCE_MEM,
}, {
.name = "ge00 err irq",
.start = IRQ_KIRKWOOD_GE00_ERR,
.end = IRQ_KIRKWOOD_GE00_ERR,
.flags = IORESOURCE_IRQ,
},
};
......@@ -117,7 +121,7 @@ static struct platform_device kirkwood_ge00_shared = {
.dev = {
.platform_data = &kirkwood_ge00_shared_data,
},
.num_resources = 1,
.num_resources = ARRAY_SIZE(kirkwood_ge00_shared_resources),
.resource = kirkwood_ge00_shared_resources,
};
......@@ -201,7 +205,6 @@ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
* SPI
****************************************************************************/
static struct orion_spi_info kirkwood_spi_plat_data = {
.tclk = KIRKWOOD_TCLK,
};
static struct resource kirkwood_spi_resources[] = {
......@@ -239,7 +242,7 @@ static struct plat_serial8250_port kirkwood_uart0_data[] = {
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = KIRKWOOD_TCLK,
.uartclk = 0,
}, {
},
};
......@@ -283,7 +286,7 @@ static struct plat_serial8250_port kirkwood_uart1_data[] = {
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = KIRKWOOD_TCLK,
.uartclk = 0,
}, {
},
};
......@@ -525,9 +528,23 @@ void __init kirkwood_xor1_init(void)
/*****************************************************************************
* Time handling
****************************************************************************/
int kirkwood_tclk;
int __init kirkwood_find_tclk(void)
{
u32 dev, rev;
kirkwood_pcie_id(&dev, &rev);
if (dev == MV88F6281_DEV_ID && rev == MV88F6281_REV_A0)
return 200000000;
return 166666667;
}
static void kirkwood_timer_init(void)
{
orion_time_init(IRQ_KIRKWOOD_BRIDGE, KIRKWOOD_TCLK);
kirkwood_tclk = kirkwood_find_tclk();
orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
}
struct sys_timer kirkwood_timer = {
......@@ -538,33 +555,62 @@ struct sys_timer kirkwood_timer = {
/*****************************************************************************
* General
****************************************************************************/
/*
* Identify device ID and revision.
*/
static char * __init kirkwood_id(void)
{
switch (readl(DEVICE_ID) & 0x3) {
case 0:
return "88F6180";
case 1:
return "88F6192";
case 2:
return "88F6281";
u32 dev, rev;
kirkwood_pcie_id(&dev, &rev);
if (dev == MV88F6281_DEV_ID) {
if (rev == MV88F6281_REV_Z0)
return "MV88F6281-Z0";
else if (rev == MV88F6281_REV_A0)
return "MV88F6281-A0";
else
return "MV88F6281-Rev-Unsupported";
} else if (dev == MV88F6192_DEV_ID) {
if (rev == MV88F6192_REV_Z0)
return "MV88F6192-Z0";
else if (rev == MV88F6192_REV_A0)
return "MV88F6192-A0";
else
return "MV88F6192-Rev-Unsupported";
} else if (dev == MV88F6180_DEV_ID) {
if (rev == MV88F6180_REV_A0)
return "MV88F6180-Rev-A0";
else
return "MV88F6180-Rev-Unsupported";
} else {
return "Device-Unknown";
}
return "unknown 88F6000 variant";
}
static int __init is_l2_writethrough(void)
static void __init kirkwood_l2_init(void)
{
return !!(readl(L2_CONFIG_REG) & L2_WRITETHROUGH);
#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
feroceon_l2_init(1);
#else
writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
feroceon_l2_init(0);
#endif
}
void __init kirkwood_init(void)
{
printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
kirkwood_id(), KIRKWOOD_TCLK);
kirkwood_id(), kirkwood_tclk);
kirkwood_ge00_shared_data.t_clk = kirkwood_tclk;
kirkwood_spi_plat_data.tclk = kirkwood_tclk;
kirkwood_uart0_data[0].uartclk = kirkwood_tclk;
kirkwood_uart1_data[0].uartclk = kirkwood_tclk;
kirkwood_setup_cpu_mbus();
#ifdef CONFIG_CACHE_FEROCEON_L2
feroceon_l2_init(is_l2_writethrough());
kirkwood_l2_init();
#endif
}
......@@ -23,10 +23,9 @@ void kirkwood_init_irq(void);
extern struct mbus_dram_target_info kirkwood_mbus_dram_info;
void kirkwood_setup_cpu_mbus(void);
void kirkwood_setup_pcie_io_win(int window, u32 base, u32 size,
int maj, int min);
void kirkwood_setup_pcie_mem_win(int window, u32 base, u32 size,
int maj, int min);
void kirkwood_setup_sram_win(u32 base, u32 size);
void kirkwood_pcie_id(u32 *dev, u32 *rev);
void kirkwood_ehci_init(void);
void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
......
......@@ -44,7 +44,6 @@ static void __init db88f6281_init(void)
kirkwood_rtc_init();
kirkwood_sata_init(&db88f6281_sata_data);
kirkwood_uart0_init();
kirkwood_uart1_init();
}
static int __init db88f6281_pci_init(void)
......
......@@ -50,6 +50,7 @@
#define IRQ_KIRKWOOD_GPIO_HIGH_0_7 39
#define IRQ_KIRKWOOD_GPIO_HIGH_8_15 40
#define IRQ_KIRKWOOD_GPIO_HIGH_16_23 41
#define IRQ_KIRKWOOD_GE00_ERR 46
/*
* KIRKWOOD General Purpose Pins
......
......@@ -67,6 +67,20 @@
#define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128)
#define L2_WRITETHROUGH 0x00000010
/*
* Supported devices and revisions.
*/
#define MV88F6281_DEV_ID 0x6281
#define MV88F6281_REV_Z0 0
#define MV88F6281_REV_A0 2
#define MV88F6192_DEV_ID 0x6192
#define MV88F6192_REV_Z0 0
#define MV88F6192_REV_A0 2
#define MV88F6180_DEV_ID 0x6180
#define MV88F6180_REV_A0 2
/*
* Register Map
*/
......
......@@ -8,4 +8,3 @@
#define CLOCK_TICK_RATE (100 * HZ)
#define KIRKWOOD_TCLK 166666667
......@@ -18,6 +18,12 @@
#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE)
void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
{
*dev = orion_pcie_dev_id(PCIE_BASE);
*rev = orion_pcie_rev(PCIE_BASE);
}
static int pcie_valid_config(int bus, int dev)
{
/*
......
......@@ -90,7 +90,6 @@ static void __init rd88f6281_init(void)
kirkwood_rtc_init();
kirkwood_sata_init(&rd88f6281_sata_data);
kirkwood_uart0_init();
kirkwood_uart1_init();
platform_device_register(&rd88f6281_nand_flash);
}
......
......@@ -285,6 +285,11 @@ static struct resource mv78xx0_ge00_shared_resources[] = {
.start = GE00_PHYS_BASE + 0x2000,
.end = GE00_PHYS_BASE + 0x3fff,
.flags = IORESOURCE_MEM,
}, {
.name = "ge err irq",
.start = IRQ_MV78XX0_GE_ERR,
.end = IRQ_MV78XX0_GE_ERR,
.flags = IORESOURCE_IRQ,
},
};
......@@ -294,7 +299,7 @@ static struct platform_device mv78xx0_ge00_shared = {
.dev = {
.platform_data = &mv78xx0_ge00_shared_data,
},
.num_resources = 1,
.num_resources = ARRAY_SIZE(mv78xx0_ge00_shared_resources),
.resource = mv78xx0_ge00_shared_resources,
};
......
......@@ -26,14 +26,22 @@
ldr \tmp, [\base, #IRQ_MASK_LOW_OFF]
mov \irqnr, #31
ands \irqstat, \irqstat, \tmp
bne 1001f
@ 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
ldr \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
ldr \tmp, [\base, #IRQ_MASK_HIGH_OFF]
mov \irqnr, #63
ands \irqstat, \irqstat, \tmp
bne 1001f
@ if no high interrupts set, check error interrupts
ldr \irqstat, [\base, #IRQ_CAUSE_ERR_OFF]
ldr \tmp, [\base, #IRQ_MASK_ERR_OFF]
mov \irqnr, #95
ands \irqstat, \irqstat, \tmp
@ find first active interrupt source
clzne \irqstat, \irqstat
1001: clzne \irqstat, \irqstat
subne \irqnr, \irqnr, \irqstat
.endm
......@@ -79,10 +79,15 @@
#define IRQ_MV78XX0_DB_IN 60
#define IRQ_MV78XX0_DB_OUT 61
/*
* MV78xx0 Error Interrupt Controller
*/
#define IRQ_MV78XX0_GE_ERR 70
/*
* MV78XX0 General Purpose Pins
*/
#define IRQ_MV78XX0_GPIO_START 64
#define IRQ_MV78XX0_GPIO_START 96
#define NR_GPIO_IRQS GPIO_MAX
#define NR_IRQS (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
......
......@@ -71,8 +71,10 @@
#define BRIDGE_INT_TIMER1 0x0004
#define BRIDGE_INT_TIMER1_CLR (~0x0004)
#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
#define IRQ_CAUSE_ERR_OFF 0x0000
#define IRQ_CAUSE_LOW_OFF 0x0004
#define IRQ_CAUSE_HIGH_OFF 0x0008
#define IRQ_MASK_ERR_OFF 0x000c
#define IRQ_MASK_LOW_OFF 0x0010
#define IRQ_MASK_HIGH_OFF 0x0014
#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
......
......@@ -19,4 +19,5 @@ void __init mv78xx0_init_irq(void)
{
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));
orion_irq_init(64, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF));
}
......@@ -36,6 +36,12 @@ config MACH_TS209
Say 'Y' here if you want your kernel to support the
QNAP TS-109/TS-209 platform.
config MACH_TERASTATION_PRO2
bool "Buffalo Terastation Pro II/Live"
help
Say 'Y' here if you want your kernel to support the
Buffalo Terastation Pro II/Live platform.
config MACH_LINKSTATION_PRO
bool "Buffalo Linkstation Pro/Live"
select I2C_BOARDINFO
......@@ -44,6 +50,13 @@ config MACH_LINKSTATION_PRO
Buffalo Linkstation Pro/Live platform. Both v1 and
v2 devices are supported.
config MACH_LINKSTATION_MINI
bool "Buffalo Linkstation Mini"
select I2C_BOARDINFO
help
Say 'Y' here if you want your kernel to support the
Buffalo Linkstation Mini platform.
config MACH_TS409
bool "QNAP TS-409"
help
......@@ -68,6 +81,13 @@ config MACH_MV2120
Say 'Y' here if you want your kernel to support the
HP Media Vault mv2120 or mv5100.
config MACH_EDMINI_V2
bool "LaCie Ethernet Disk mini V2"
select I2C_BOARDINFO
help
Say 'Y' here if you want your kernel to support the
LaCie Ethernet Disk mini V2.
config MACH_MSS2
bool "Maxtor Shared Storage II"
help
......@@ -92,6 +112,12 @@ config MACH_RD88F5181L_FXO
Say 'Y' here if you want your kernel to support the
Marvell Orion-VoIP FXO (88F5181L) RD.
config MACH_RD88F6183AP_GE
bool "Marvell Orion-1-90 AP GE Reference Design"
help
Say 'Y' here if you want your kernel to support the
Marvell Orion-1-90 (88F6183) AP GE RD.
endmenu
endif
......@@ -2,14 +2,18 @@ obj-y += common.o addr-map.o pci.o gpio.o irq.o mpp.o
obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o
obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
obj-$(CONFIG_MACH_TERASTATION_PRO2) += terastation_pro2-setup.o
obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o
obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
obj-$(CONFIG_MACH_DNS323) += dns323-setup.o
obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o
obj-$(CONFIG_MACH_TS409) += ts409-setup.o tsx09-common.o
obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o
obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o
obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o
obj-$(CONFIG_MACH_EDMINI_V2) += edmini_v2-setup.o
obj-$(CONFIG_MACH_MSS2) += mss2-setup.o
obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o
obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o
obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o
obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o
......@@ -18,6 +18,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h>
#include <linux/spi/orion_spi.h>
#include <asm/page.h>
#include <asm/setup.h>
#include <asm/timex.h>
......@@ -146,7 +147,6 @@ void __init orion5x_ehci1_init(void)
****************************************************************************/
struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
.dram = &orion5x_mbus_dram_info,
.t_clk = ORION5X_TCLK,
};
static struct resource orion5x_eth_shared_resources[] = {
......@@ -154,6 +154,10 @@ static struct resource orion5x_eth_shared_resources[] = {
.start = ORION5X_ETH_PHYS_BASE + 0x2000,
.end = ORION5X_ETH_PHYS_BASE + 0x3fff,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_ORION5X_ETH_ERR,
.end = IRQ_ORION5X_ETH_ERR,
.flags = IORESOURCE_IRQ,
},
};
......@@ -163,7 +167,7 @@ static struct platform_device orion5x_eth_shared = {
.dev = {
.platform_data = &orion5x_eth_shared_data,
},
.num_resources = 1,
.num_resources = ARRAY_SIZE(orion5x_eth_shared_resources),
.resource = orion5x_eth_shared_resources,
};
......@@ -267,6 +271,38 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
}
/*****************************************************************************
* SPI
****************************************************************************/
static struct orion_spi_info orion5x_spi_plat_data = {
.tclk = 0,
};
static struct resource orion5x_spi_resources[] = {
{
.name = "spi base",
.start = SPI_PHYS_BASE,
.end = SPI_PHYS_BASE + 0x1f,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device orion5x_spi = {
.name = "orion_spi",
.id = 0,
.dev = {
.platform_data = &orion5x_spi_plat_data,
},
.num_resources = ARRAY_SIZE(orion5x_spi_resources),
.resource = orion5x_spi_resources,
};
void __init orion5x_spi_init()
{
platform_device_register(&orion5x_spi);
}
/*****************************************************************************
* UART0
****************************************************************************/
......@@ -278,7 +314,7 @@ static struct plat_serial8250_port orion5x_uart0_data[] = {
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = ORION5X_TCLK,
.uartclk = 0,
}, {
},
};
......@@ -322,7 +358,7 @@ static struct plat_serial8250_port orion5x_uart1_data[] = {
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = ORION5X_TCLK,
.uartclk = 0,
}, {
},
};
......@@ -455,9 +491,24 @@ void __init orion5x_xor_init(void)
/*****************************************************************************
* Time handling
****************************************************************************/
int orion5x_tclk;
int __init orion5x_find_tclk(void)
{
u32 dev, rev;
orion5x_pcie_id(&dev, &rev);
if (dev == MV88F6183_DEV_ID &&
(readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
return 133333333;
return 166666667;
}
static void orion5x_timer_init(void)
{
orion_time_init(IRQ_ORION5X_BRIDGE, ORION5X_TCLK);
orion5x_tclk = orion5x_find_tclk();
orion_time_init(IRQ_ORION5X_BRIDGE, orion5x_tclk);
}
struct sys_timer orion5x_timer = {
......@@ -499,6 +550,12 @@ static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
} else {
*dev_name = "MV88F5181(L)-Rev-Unsupported";
}
} else if (*dev == MV88F6183_DEV_ID) {
if (*rev == MV88F6183_REV_B0) {
*dev_name = "MV88F6183-Rev-B0";
} else {
*dev_name = "MV88F6183-Rev-Unsupported";
}
} else {
*dev_name = "Device-Unknown";
}
......@@ -510,7 +567,12 @@ void __init orion5x_init(void)
u32 dev, rev;
orion5x_id(&dev, &rev, &dev_name);
printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, ORION5X_TCLK);
printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
orion5x_eth_shared_data.t_clk = orion5x_tclk;
orion5x_spi_plat_data.tclk = orion5x_tclk;
orion5x_uart0_data[0].uartclk = orion5x_tclk;
orion5x_uart1_data[0].uartclk = orion5x_tclk;
/*
* Setup Orion address map
......
......@@ -10,6 +10,7 @@ struct mv_sata_platform_data;
void orion5x_map_io(void);
void orion5x_init_irq(void);
void orion5x_init(void);
extern int orion5x_tclk;
extern struct sys_timer orion5x_timer;
/*
......@@ -30,6 +31,7 @@ void orion5x_ehci1_init(void);
void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
void orion5x_i2c_init(void);
void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
void orion5x_spi_init(void);
void orion5x_uart0_init(void);
void orion5x_uart1_init(void);
void orion5x_xor_init(void);
......
/*
* arch/arm/mach-orion5x/edmini_v2-setup.c
*
* LaCie Ethernet Disk mini V2 Setup
*
* Copyright (C) 2008 Christopher Moore <moore@free.fr>
* Copyright (C) 2008 Albert Aribaud <albert.aribaud@free.fr>
*
* 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.
*/
/*
* TODO: add Orion USB device port init when kernel.org support is added.
* TODO: add flash write support: see below.
* TODO: add power-off support.
* TODO: add I2C EEPROM support.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/irq.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/leds.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/ata_platform.h>
#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
#include "common.h"
#include "mpp.h"
/*****************************************************************************
* EDMINI_V2 Info
****************************************************************************/
/*
* 512KB NOR flash Device bus boot chip select
*/
#define EDMINI_V2_NOR_BOOT_BASE 0xfff80000
#define EDMINI_V2_NOR_BOOT_SIZE SZ_512K
/*****************************************************************************
* 512KB NOR Flash on BOOT Device
****************************************************************************/
/*
* Currently the MTD code does not recognize the MX29LV400CBCT as a bottom
* -type device. This could cause risks of accidentally erasing critical
* flash sectors. We thus define a single, write-protected partition covering
* the whole flash.
* TODO: once the flash part TOP/BOTTOM detection issue is sorted out in the MTD
* code, break this into at least three partitions: 'u-boot code', 'u-boot
* environment' and 'whatever is left'.
*/
static struct mtd_partition edmini_v2_partitions[] = {
{
.name = "Full512kb",
.size = 0x00080000,
.offset = 0x00000000,
.mask_flags = MTD_WRITEABLE,
},
};
static struct physmap_flash_data edmini_v2_nor_flash_data = {
.width = 1,
.parts = edmini_v2_partitions,
.nr_parts = ARRAY_SIZE(edmini_v2_partitions),
};
static struct resource edmini_v2_nor_flash_resource = {
.flags = IORESOURCE_MEM,
.start = EDMINI_V2_NOR_BOOT_BASE,
.end = EDMINI_V2_NOR_BOOT_BASE
+ EDMINI_V2_NOR_BOOT_SIZE - 1,
};
static struct platform_device edmini_v2_nor_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &edmini_v2_nor_flash_data,
},
.num_resources = 1,
.resource = &edmini_v2_nor_flash_resource,
};
/*****************************************************************************
* Ethernet
****************************************************************************/
static struct mv643xx_eth_platform_data edmini_v2_eth_data = {
.phy_addr = 8,
};
/*****************************************************************************
* RTC 5C372a on I2C bus
****************************************************************************/
#define EDMINIV2_RTC_GPIO 3
static struct i2c_board_info __initdata edmini_v2_i2c_rtc = {
I2C_BOARD_INFO("rs5c372a", 0x32),
.irq = 0,
};
/*****************************************************************************
* Sata
****************************************************************************/
static struct mv_sata_platform_data edmini_v2_sata_data = {
.n_ports = 2,
};
/*****************************************************************************
* GPIO LED (simple - doesn't use hardware blinking support)
****************************************************************************/
#define EDMINI_V2_GPIO_LED_POWER 16
static struct gpio_led edmini_v2_leds[] = {
{
.name = "power:blue",
.gpio = EDMINI_V2_GPIO_LED_POWER,
.active_low = 1,
},
};
static struct gpio_led_platform_data edmini_v2_led_data = {
.num_leds = ARRAY_SIZE(edmini_v2_leds),
.leds = edmini_v2_leds,
};
static struct platform_device edmini_v2_gpio_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &edmini_v2_led_data,
},
};
/****************************************************************************
* GPIO key
****************************************************************************/
#define EDMINI_V2_GPIO_KEY_POWER 18
static struct gpio_keys_button edmini_v2_buttons[] = {
{
.code = KEY_POWER,
.gpio = EDMINI_V2_GPIO_KEY_POWER,
.desc = "Power Button",
.active_low = 0,
},
};
static struct gpio_keys_platform_data edmini_v2_button_data = {
.buttons = edmini_v2_buttons,
.nbuttons = ARRAY_SIZE(edmini_v2_buttons),
};
static struct platform_device edmini_v2_gpio_buttons = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &edmini_v2_button_data,
},
};
/*****************************************************************************
* General Setup
****************************************************************************/
static struct orion5x_mpp_mode edminiv2_mpp_modes[] __initdata = {
{ 0, MPP_UNUSED },
{ 1, MPP_UNUSED },
{ 2, MPP_UNUSED },
{ 3, MPP_GPIO }, /* RTC interrupt */
{ 4, MPP_UNUSED },
{ 5, MPP_UNUSED },
{ 6, MPP_UNUSED },
{ 7, MPP_UNUSED },
{ 8, MPP_UNUSED },
{ 9, MPP_UNUSED },
{ 10, MPP_UNUSED },
{ 11, MPP_UNUSED },
{ 12, MPP_SATA_LED }, /* SATA 0 presence */
{ 13, MPP_SATA_LED }, /* SATA 1 presence */
{ 14, MPP_SATA_LED }, /* SATA 0 active */
{ 15, MPP_SATA_LED }, /* SATA 1 active */
/* 16: Power LED control (0 = On, 1 = Off) */
{ 16, MPP_GPIO },
/* 17: Power LED control select (0 = CPLD, 1 = GPIO16) */
{ 17, MPP_GPIO },
/* 18: Power button status (0 = Released, 1 = Pressed) */
{ 18, MPP_GPIO },
{ 19, MPP_UNUSED },
{ -1 }
};
static void __init edmini_v2_init(void)
{
/*
* Setup basic Orion functions. Need to be called early.
*/
orion5x_init();
orion5x_mpp_conf(edminiv2_mpp_modes);
/*
* Configure peripherals.
*/
orion5x_ehci0_init();
orion5x_eth_init(&edmini_v2_eth_data);
orion5x_i2c_init();
orion5x_sata_init(&edmini_v2_sata_data);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE,
EDMINI_V2_NOR_BOOT_SIZE);
platform_device_register(&edmini_v2_nor_flash);
platform_device_register(&edmini_v2_gpio_leds);
platform_device_register(&edmini_v2_gpio_buttons);
pr_notice("edmini_v2: USB device port, flash write and power-off "
"are not yet supported.\n");
/* Get RTC IRQ and register the chip */
if (gpio_request(EDMINIV2_RTC_GPIO, "rtc") == 0) {
if (gpio_direction_input(EDMINIV2_RTC_GPIO) == 0)
edmini_v2_i2c_rtc.irq = gpio_to_irq(EDMINIV2_RTC_GPIO);
else
gpio_free(EDMINIV2_RTC_GPIO);
}
if (edmini_v2_i2c_rtc.irq == 0)
pr_warning("edmini_v2: failed to get RTC IRQ\n");
i2c_register_board_info(0, &edmini_v2_i2c_rtc, 1);
}
/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
MACHINE_START(EDMINI_V2, "LaCie Ethernet Disk mini V2")
/* Maintainer: Christopher Moore <moore@free.fr> */
.phys_io = ORION5X_REGS_PHYS_BASE,
.io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = edmini_v2_init,
.map_io = orion5x_map_io,
.init_irq = orion5x_init_irq,
.timer = &orion5x_timer,
.fixup = tag_fixup_mem32,
MACHINE_END
......@@ -2,7 +2,7 @@
* arch/arm/mach-orion5x/include/mach/orion5x.h
*
* Generic definitions of Orion SoC flavors:
* Orion-1, Orion-VoIP, Orion-NAS, and Orion-2.
* Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90.
*
* Maintainer: Tzachi Perelstein <tzachi@marvell.com>
*
......@@ -76,6 +76,9 @@
#define MV88F5281_REV_D0 4
#define MV88F5281_REV_D1 5
#define MV88F5281_REV_D2 6
/* Orion-1-90 (88F6183) */
#define MV88F6183_DEV_ID 0x6183
#define MV88F6183_REV_B0 3
/*******************************************************************************
* Orion Registers Map
......@@ -86,6 +89,7 @@
#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000)
#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000)
#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x))
#define SPI_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x0600)
#define I2C_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x1000)
#define UART0_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2000)
#define UART0_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2000)
......
......@@ -9,5 +9,3 @@
*/
#define CLOCK_TICK_RATE (100 * HZ)
#define ORION5X_TCLK 166666667
......@@ -293,7 +293,7 @@ static void kurobox_pro_power_off(void)
const unsigned char shutdownwait[] = {0x00, 0x0c};
const unsigned char poweroff[] = {0x00, 0x06};
/* 38400 baud divisor */
const unsigned divisor = ((ORION5X_TCLK + (8 * 38400)) / (16 * 38400));
const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
pr_info("%s: triggering power-off...\n", __func__);
......
/*
* arch/arm/mach-orion5x/lsmini-setup.c
*
* Maintainer: Alexey Kopytko <alexey@kopytko.ru>
*
* 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/pci.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/leds.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/ata_platform.h>
#include <asm/mach-types.h>
#include <linux/gpio.h>
#include <asm/mach/arch.h>
#include "common.h"
#include "mpp.h"
#include "include/mach/system.h"
/*****************************************************************************
* Linkstation Mini Info
****************************************************************************/
/*
* 256K NOR flash Device bus boot chip select
*/
#define LSMINI_NOR_BOOT_BASE 0xf4000000
#define LSMINI_NOR_BOOT_SIZE SZ_256K
/*****************************************************************************
* 256KB NOR Flash on BOOT Device
****************************************************************************/
static struct physmap_flash_data lsmini_nor_flash_data = {
.width = 1,
};
static struct resource lsmini_nor_flash_resource = {
.flags = IORESOURCE_MEM,
.start = LSMINI_NOR_BOOT_BASE,
.end = LSMINI_NOR_BOOT_BASE + LSMINI_NOR_BOOT_SIZE - 1,
};
static struct platform_device lsmini_nor_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &lsmini_nor_flash_data,
},
.num_resources = 1,
.resource = &lsmini_nor_flash_resource,
};
/*****************************************************************************
* Ethernet
****************************************************************************/
static struct mv643xx_eth_platform_data lsmini_eth_data = {
.phy_addr = 8,
};
/*****************************************************************************
* RTC 5C372a on I2C bus
****************************************************************************/
static struct i2c_board_info __initdata lsmini_i2c_rtc = {
I2C_BOARD_INFO("rs5c372a", 0x32),
};
/*****************************************************************************
* LEDs attached to GPIO
****************************************************************************/
#define LSMINI_GPIO_LED_ALARM 2
#define LSMINI_GPIO_LED_INFO 3
#define LSMINI_GPIO_LED_FUNC 9
#define LSMINI_GPIO_LED_PWR 14
static struct gpio_led lsmini_led_pins[] = {
{
.name = "alarm:red",
.gpio = LSMINI_GPIO_LED_ALARM,
.active_low = 1,
}, {
.name = "info:amber",
.gpio = LSMINI_GPIO_LED_INFO,
.active_low = 1,
}, {
.name = "func:blue:top",
.gpio = LSMINI_GPIO_LED_FUNC,
.active_low = 1,
}, {
.name = "power:blue:bottom",
.gpio = LSMINI_GPIO_LED_PWR,
},
};
static struct gpio_led_platform_data lsmini_led_data = {
.leds = lsmini_led_pins,
.num_leds = ARRAY_SIZE(lsmini_led_pins),
};
static struct platform_device lsmini_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &lsmini_led_data,
},
};
/****************************************************************************
* GPIO Attached Keys
****************************************************************************/
#define LSMINI_GPIO_KEY_FUNC 15
#define LSMINI_GPIO_KEY_POWER 18
#define LSMINI_GPIO_KEY_AUTOPOWER 17
#define LSMINI_SW_POWER 0x00
#define LSMINI_SW_AUTOPOWER 0x01
static struct gpio_keys_button lsmini_buttons[] = {
{
.code = KEY_OPTION,
.gpio = LSMINI_GPIO_KEY_FUNC,
.desc = "Function Button",
.active_low = 1,
}, {
.type = EV_SW,
.code = LSMINI_SW_POWER,
.gpio = LSMINI_GPIO_KEY_POWER,
.desc = "Power-on Switch",
.active_low = 1,
}, {
.type = EV_SW,
.code = LSMINI_SW_AUTOPOWER,
.gpio = LSMINI_GPIO_KEY_AUTOPOWER,
.desc = "Power-auto Switch",
.active_low = 1,
},
};
static struct gpio_keys_platform_data lsmini_button_data = {
.buttons = lsmini_buttons,
.nbuttons = ARRAY_SIZE(lsmini_buttons),
};
static struct platform_device lsmini_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.dev = {
.platform_data = &lsmini_button_data,
},
};
/*****************************************************************************
* SATA
****************************************************************************/
static struct mv_sata_platform_data lsmini_sata_data = {
.n_ports = 2,
};
/*****************************************************************************
* Linkstation Mini specific power off method: reboot
****************************************************************************/
/*
* On the Linkstation Mini, the shutdown process is following:
* - Userland monitors key events until the power switch goes to off position
* - The board reboots
* - U-boot starts and goes into an idle mode waiting for the user
* to move the switch to ON position
*/
static void lsmini_power_off(void)
{
arch_reset(0);
}
/*****************************************************************************
* General Setup
****************************************************************************/
#define LSMINI_GPIO_USB_POWER 16
#define LSMINI_GPIO_AUTO_POWER 17
#define LSMINI_GPIO_POWER 18
#define LSMINI_GPIO_HDD_POWER0 1
#define LSMINI_GPIO_HDD_POWER1 19
static struct orion5x_mpp_mode lsmini_mpp_modes[] __initdata = {
{ 0, MPP_UNUSED }, /* LED_RESERVE1 (unused) */
{ 1, MPP_GPIO }, /* HDD_PWR */
{ 2, MPP_GPIO }, /* LED_ALARM */
{ 3, MPP_GPIO }, /* LED_INFO */
{ 4, MPP_UNUSED },
{ 5, MPP_UNUSED },
{ 6, MPP_UNUSED },
{ 7, MPP_UNUSED },
{ 8, MPP_UNUSED },
{ 9, MPP_GPIO }, /* LED_FUNC */
{ 10, MPP_UNUSED },
{ 11, MPP_UNUSED }, /* LED_ETH (dummy) */
{ 12, MPP_UNUSED },
{ 13, MPP_UNUSED },
{ 14, MPP_GPIO }, /* LED_PWR */
{ 15, MPP_GPIO }, /* FUNC */
{ 16, MPP_GPIO }, /* USB_PWR */
{ 17, MPP_GPIO }, /* AUTO_POWER */
{ 18, MPP_GPIO }, /* POWER */
{ 19, MPP_GPIO }, /* HDD_PWR1 */
{ -1 },
};
static void __init lsmini_init(void)
{
/*
* Setup basic Orion functions. Need to be called early.
*/
orion5x_init();
orion5x_mpp_conf(lsmini_mpp_modes);
/*
* Configure peripherals.
*/
orion5x_ehci0_init();
orion5x_ehci1_init();
orion5x_eth_init(&lsmini_eth_data);
orion5x_i2c_init();
orion5x_sata_init(&lsmini_sata_data);
orion5x_uart0_init();
orion5x_xor_init();
orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE,
LSMINI_NOR_BOOT_SIZE);
platform_device_register(&lsmini_nor_flash);
platform_device_register(&lsmini_button_device);
platform_device_register(&lsmini_leds);
i2c_register_board_info(0, &lsmini_i2c_rtc, 1);
/* enable USB power */
gpio_set_value(LSMINI_GPIO_USB_POWER, 1);
/* register power-off method */
pm_power_off = lsmini_power_off;
pr_info("%s: finished\n", __func__);
}
#ifdef CONFIG_MACH_LINKSTATION_MINI
MACHINE_START(LINKSTATION_MINI, "Buffalo Linkstation Mini")
/* Maintainer: Alexey Kopytko <alexey@kopytko.ru> */
.phys_io = ORION5X_REGS_PHYS_BASE,
.io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = lsmini_init,
.map_io = orion5x_map_io,
.init_irq = orion5x_init_irq,
.timer = &orion5x_timer,
.fixup = tag_fixup_mem32,
MACHINE_END
#endif
/*
* arch/arm/mach-orion5x/rd88f6183-ap-ge-setup.c
*
* Marvell Orion-1-90 AP GE Reference Design 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/pci.h>
#include <linux/irq.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/spi/flash.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
#include "common.h"
#include "mpp.h"
static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
.phy_addr = -1,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
};
static struct mtd_partition rd88f6183ap_ge_partitions[] = {
{
.name = "kernel",
.offset = 0x00000000,
.size = 0x00200000,
}, {
.name = "rootfs",
.offset = 0x00200000,
.size = 0x00500000,
}, {
.name = "nvram",
.offset = 0x00700000,
.size = 0x00080000,
},
};
static struct flash_platform_data rd88f6183ap_ge_spi_slave_data = {
.type = "m25p64",
.nr_parts = ARRAY_SIZE(rd88f6183ap_ge_partitions),
.parts = rd88f6183ap_ge_partitions,
};
static struct spi_board_info __initdata rd88f6183ap_ge_spi_slave_info[] = {
{
.modalias = "m25p80",
.platform_data = &rd88f6183ap_ge_spi_slave_data,
.irq = NO_IRQ,
.max_speed_hz = 20000000,
.bus_num = 0,
.chip_select = 0,
},
};
static void __init rd88f6183ap_ge_init(void)
{
/*
* Setup basic Orion functions. Need to be called early.
*/
orion5x_init();
/*
* Configure peripherals.
*/
orion5x_ehci0_init();
orion5x_eth_init(&rd88f6183ap_ge_eth_data);
spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
orion5x_spi_init();
orion5x_uart0_init();
}
static struct hw_pci rd88f6183ap_ge_pci __initdata = {
.nr_controllers = 2,
.swizzle = pci_std_swizzle,
.setup = orion5x_pci_sys_setup,
.scan = orion5x_pci_sys_scan_bus,
.map_irq = orion5x_pci_map_irq,
};
static int __init rd88f6183ap_ge_pci_init(void)
{
if (machine_is_rd88f6183ap_ge()) {
orion5x_pci_disable();
pci_common_init(&rd88f6183ap_ge_pci);
}
return 0;
}
subsys_initcall(rd88f6183ap_ge_pci_init);
MACHINE_START(RD88F6183AP_GE, "Marvell Orion-1-90 AP GE Reference Design")
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
.phys_io = ORION5X_REGS_PHYS_BASE,
.io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = rd88f6183ap_ge_init,
.map_io = orion5x_map_io,
.init_irq = orion5x_init_irq,
.timer = &orion5x_timer,
.fixup = tag_fixup_mem32,
MACHINE_END
/*
* Buffalo Terastation Pro II/Live Board Setup
*
* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.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/pci.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/i2c.h>
#include <linux/serial_reg.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
#include "common.h"
#include "mpp.h"
/*****************************************************************************
* Terastation Pro 2/Live Info
****************************************************************************/
/*
* Terastation Pro 2 hardware :
* - Marvell 88F5281-D0
* - Marvell 88SX6042 SATA controller (PCI)
* - Marvell 88E1118 Gigabit Ethernet PHY
* - 256KB NOR flash
* - 128MB of DDR RAM
* - PCIe port (not equipped)
*/
/*
* 256K NOR flash Device bus boot chip select
*/
#define TSP2_NOR_BOOT_BASE 0xf4000000
#define TSP2_NOR_BOOT_SIZE SZ_256K
/*****************************************************************************
* 256KB NOR Flash on BOOT Device
****************************************************************************/
static struct physmap_flash_data tsp2_nor_flash_data = {
.width = 1,
};
static struct resource tsp2_nor_flash_resource = {
.flags = IORESOURCE_MEM,
.start = TSP2_NOR_BOOT_BASE,
.end = TSP2_NOR_BOOT_BASE + TSP2_NOR_BOOT_SIZE - 1,
};
static struct platform_device tsp2_nor_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &tsp2_nor_flash_data,
},
.num_resources = 1,
.resource = &tsp2_nor_flash_resource,
};
/*****************************************************************************
* PCI
****************************************************************************/
#define TSP2_PCI_SLOT0_OFFS 7
#define TSP2_PCI_SLOT0_IRQ_PIN 11
void __init tsp2_pci_preinit(void)
{
int pin;
/*
* Configure PCI GPIO IRQ pins
*/
pin = TSP2_PCI_SLOT0_IRQ_PIN;
if (gpio_request(pin, "PCI Int1") == 0) {
if (gpio_direction_input(pin) == 0) {
set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "tsp2_pci_preinit failed "
"to set_irq_type pin %d\n", pin);
gpio_free(pin);
}
} else {
printk(KERN_ERR "tsp2_pci_preinit failed to "
"gpio_request %d\n", pin);
}
}
static int __init tsp2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int irq;
/*
* Check for devices with hard-wired IRQs.
*/
irq = orion5x_pci_map_irq(dev, slot, pin);
if (irq != -1)
return irq;
/*
* PCI IRQs are connected via GPIOs.
*/
if (slot == TSP2_PCI_SLOT0_OFFS)
return gpio_to_irq(TSP2_PCI_SLOT0_IRQ_PIN);
return -1;
}
static struct hw_pci tsp2_pci __initdata = {
.nr_controllers = 2,
.preinit = tsp2_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = orion5x_pci_sys_setup,
.scan = orion5x_pci_sys_scan_bus,
.map_irq = tsp2_pci_map_irq,
};
static int __init tsp2_pci_init(void)
{
if (machine_is_terastation_pro2())
pci_common_init(&tsp2_pci);
return 0;
}
subsys_initcall(tsp2_pci_init);
/*****************************************************************************
* Ethernet
****************************************************************************/
static struct mv643xx_eth_platform_data tsp2_eth_data = {
.phy_addr = 0,
};
/*****************************************************************************
* RTC 5C372a on I2C bus
****************************************************************************/
#define TSP2_RTC_GPIO 9
static struct i2c_board_info __initdata tsp2_i2c_rtc = {
I2C_BOARD_INFO("rs5c372a", 0x32),
};
/*****************************************************************************
* Terastation Pro II specific power off method via UART1-attached
* microcontroller
****************************************************************************/
#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
static int tsp2_miconread(unsigned char *buf, int count)
{
int i;
int timeout;
for (i = 0; i < count; i++) {
timeout = 10;
while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
if (--timeout == 0)
break;
udelay(1000);
}
if (timeout == 0)
break;
buf[i] = readl(UART1_REG(RX));
}
/* return read bytes */
return i;
}
static int tsp2_miconwrite(const unsigned char *buf, int count)
{
int i = 0;
while (count--) {
while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
barrier();
writel(buf[i++], UART1_REG(TX));
}
return 0;
}
static int tsp2_miconsend(const unsigned char *data, int count)
{
int i;
unsigned char checksum = 0;
unsigned char recv_buf[40];
unsigned char send_buf[40];
unsigned char correct_ack[3];
int retry = 2;
/* Generate checksum */
for (i = 0; i < count; i++)
checksum -= data[i];
do {
/* Send data */
tsp2_miconwrite(data, count);
/* send checksum */
tsp2_miconwrite(&checksum, 1);
if (tsp2_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
printk(KERN_ERR ">%s: receive failed.\n", __func__);
/* send preamble to clear the receive buffer */
memset(&send_buf, 0xff, sizeof(send_buf));
tsp2_miconwrite(send_buf, sizeof(send_buf));
/* make dummy reads */
mdelay(100);
tsp2_miconread(recv_buf, sizeof(recv_buf));
} else {
/* Generate expected ack */
correct_ack[0] = 0x01;
correct_ack[1] = data[1];
correct_ack[2] = 0x00;
/* checksum Check */
if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
recv_buf[3]) & 0xFF) {
printk(KERN_ERR ">%s: Checksum Error : "
"Received data[%02x, %02x, %02x, %02x]"
"\n", __func__, recv_buf[0],
recv_buf[1], recv_buf[2], recv_buf[3]);
} else {
/* Check Received Data */
if (correct_ack[0] == recv_buf[0] &&
correct_ack[1] == recv_buf[1] &&
correct_ack[2] == recv_buf[2]) {
/* Interval for next command */
mdelay(10);
/* Receive ACK */
return 0;
}
}
/* Received NAK or illegal Data */
printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
"Received\n", __func__);
}
} while (retry--);
/* Interval for next command */
mdelay(10);
return -1;
}
static void tsp2_power_off(void)
{
const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
const unsigned char shutdownwait[] = {0x00, 0x0c};
const unsigned char poweroff[] = {0x00, 0x06};
/* 38400 baud divisor */
const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
pr_info("%s: triggering power-off...\n", __func__);
/* hijack uart1 and reset into sane state (38400,8n1,even parity) */
writel(0x83, UART1_REG(LCR));
writel(divisor & 0xff, UART1_REG(DLL));
writel((divisor >> 8) & 0xff, UART1_REG(DLM));
writel(0x1b, UART1_REG(LCR));
writel(0x00, UART1_REG(IER));
writel(0x07, UART1_REG(FCR));
writel(0x00, UART1_REG(MCR));
/* Send the commands to shutdown the Terastation Pro II */
tsp2_miconsend(watchdogkill, sizeof(watchdogkill)) ;
tsp2_miconsend(shutdownwait, sizeof(shutdownwait)) ;
tsp2_miconsend(poweroff, sizeof(poweroff));
}
/*****************************************************************************
* General Setup
****************************************************************************/
static struct orion5x_mpp_mode tsp2_mpp_modes[] __initdata = {
{ 0, MPP_PCIE_RST_OUTn },
{ 1, MPP_UNUSED },
{ 2, MPP_UNUSED },
{ 3, MPP_UNUSED },
{ 4, MPP_NAND }, /* BOOT NAND Flash REn */
{ 5, MPP_NAND }, /* BOOT NAND Flash WEn */
{ 6, MPP_NAND }, /* BOOT NAND Flash HREn[0] */
{ 7, MPP_NAND }, /* BOOT NAND Flash WEn[0] */
{ 8, MPP_GPIO }, /* MICON int */
{ 9, MPP_GPIO }, /* RTC int */
{ 10, MPP_UNUSED },
{ 11, MPP_GPIO }, /* PCI Int A */
{ 12, MPP_UNUSED },
{ 13, MPP_GPIO }, /* UPS on UART0 enable */
{ 14, MPP_GPIO }, /* UPS low battery detection */
{ 15, MPP_UNUSED },
{ 16, MPP_UART }, /* UART1 RXD */
{ 17, MPP_UART }, /* UART1 TXD */
{ 18, MPP_UART }, /* UART1 CTSn */
{ 19, MPP_UART }, /* UART1 RTSn */
{ -1 },
};
static void __init tsp2_init(void)
{
/*
* Setup basic Orion functions. Need to be called early.
*/
orion5x_init();
orion5x_mpp_conf(tsp2_mpp_modes);
/*
* Configure peripherals.
*/
orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE,
TSP2_NOR_BOOT_SIZE);
platform_device_register(&tsp2_nor_flash);
orion5x_ehci0_init();
orion5x_eth_init(&tsp2_eth_data);
orion5x_i2c_init();
orion5x_uart0_init();
orion5x_uart1_init();
/* Get RTC IRQ and register the chip */
if (gpio_request(TSP2_RTC_GPIO, "rtc") == 0) {
if (gpio_direction_input(TSP2_RTC_GPIO) == 0)
tsp2_i2c_rtc.irq = gpio_to_irq(TSP2_RTC_GPIO);
else
gpio_free(TSP2_RTC_GPIO);
}
if (tsp2_i2c_rtc.irq == 0)
pr_warning("tsp2_init: failed to get RTC IRQ\n");
i2c_register_board_info(0, &tsp2_i2c_rtc, 1);
/* register Terastation Pro II specific power-off method */
pm_power_off = tsp2_power_off;
}
MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
/* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */
.phys_io = ORION5X_REGS_PHYS_BASE,
.io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.init_machine = tsp2_init,
.map_io = orion5x_map_io,
.init_irq = orion5x_init_irq,
.timer = &orion5x_timer,
.fixup = tag_fixup_mem32,
MACHINE_END
......@@ -16,6 +16,7 @@
#include <linux/timex.h>
#include <linux/serial_reg.h>
#include "tsx09-common.h"
#include "common.h"
/*****************************************************************************
* QNAP TS-x09 specific power off method via UART1-attached PIC
......@@ -26,7 +27,7 @@
void qnap_tsx09_power_off(void)
{
/* 19200 baud divisor */
const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200));
const unsigned divisor = ((orion5x_tclk + (8 * 19200)) / (16 * 19200));
pr_info("%s: triggering power-off...\n", __func__);
......
......@@ -735,6 +735,14 @@ config CACHE_FEROCEON_L2
help
This option enables the Feroceon L2 cache controller.
config CACHE_FEROCEON_L2_WRITETHROUGH
bool "Force Feroceon L2 cache write through"
depends on CACHE_FEROCEON_L2
default n
help
Say Y here to use the Feroceon L2 cache in writethrough mode.
Unless you specifically require this, say N for writeback mode.
config CACHE_L2X0
bool "Enable the L2x0 outer cache controller"
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
......
......@@ -48,11 +48,12 @@ static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
* L2 is PIPT and range operations only do a TLB lookup on
* the start address.
*/
BUG_ON((start ^ end) & ~(PAGE_SIZE - 1));
BUG_ON((start ^ end) >> PAGE_SHIFT);
raw_local_irq_save(flags);
__asm__("mcr p15, 1, %0, c15, c9, 4" : : "r" (start));
__asm__("mcr p15, 1, %0, c15, c9, 5" : : "r" (end));
__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
"mcr p15, 1, %1, c15, c9, 5"
: : "r" (start), "r" (end));
raw_local_irq_restore(flags);
}
......@@ -80,11 +81,12 @@ static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
* L2 is PIPT and range operations only do a TLB lookup on
* the start address.
*/
BUG_ON((start ^ end) & ~(PAGE_SIZE - 1));
BUG_ON((start ^ end) >> PAGE_SHIFT);
raw_local_irq_save(flags);
__asm__("mcr p15, 1, %0, c15, c11, 4" : : "r" (start));
__asm__("mcr p15, 1, %0, c15, c11, 5" : : "r" (end));
__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
"mcr p15, 1, %1, c15, c11, 5"
: : "r" (start), "r" (end));
raw_local_irq_restore(flags);
}
......@@ -205,7 +207,7 @@ static void feroceon_l2_flush_range(unsigned long start, unsigned long end)
* time. These are necessary because the L2 cache can only be enabled
* or disabled while the L1 Dcache and Icache are both disabled.
*/
static void __init invalidate_and_disable_dcache(void)
static int __init flush_and_disable_dcache(void)
{
u32 cr;
......@@ -217,7 +219,9 @@ static void __init invalidate_and_disable_dcache(void)
flush_cache_all();
set_cr(cr & ~CR_C);
raw_local_irq_restore(flags);
return 1;
}
return 0;
}
static void __init enable_dcache(void)
......@@ -225,7 +229,6 @@ static void __init enable_dcache(void)
u32 cr;
cr = get_cr();
if (!(cr & CR_C))
set_cr(cr | CR_C);
}
......@@ -233,10 +236,10 @@ static void __init __invalidate_icache(void)
{
int dummy;
__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0\n" : "=r" (dummy));
__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy));
}
static void __init invalidate_and_disable_icache(void)
static int __init invalidate_and_disable_icache(void)
{
u32 cr;
......@@ -244,7 +247,9 @@ static void __init invalidate_and_disable_icache(void)
if (cr & CR_I) {
set_cr(cr & ~CR_I);
__invalidate_icache();
return 1;
}
return 0;
}
static void __init enable_icache(void)
......@@ -252,7 +257,6 @@ static void __init enable_icache(void)
u32 cr;
cr = get_cr();
if (!(cr & CR_I))
set_cr(cr | CR_I);
}
......@@ -291,12 +295,16 @@ static void __init enable_l2(void)
u = read_extra_features();
if (!(u & 0x00400000)) {
int i, d;
printk(KERN_INFO "Feroceon L2: Enabling L2\n");
invalidate_and_disable_dcache();
invalidate_and_disable_icache();
d = flush_and_disable_dcache();
i = invalidate_and_disable_icache();
write_extra_features(u | 0x00400000);
if (i)
enable_icache();
if (d)
enable_dcache();
}
}
......
......@@ -80,7 +80,8 @@ ENTRY(cpu_feroceon_proc_fin)
msr cpsr_c, ip
bl feroceon_flush_kern_cache_all
#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH)
#if defined(CONFIG_CACHE_FEROCEON_L2) && \
!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
mov r0, #0
mcr p15, 1, r0, c15, c9, 0 @ clean L2
mcr p15, 0, r0, c7, c10, 4 @ drain WB
......@@ -389,7 +390,8 @@ ENTRY(feroceon_range_cache_fns)
.align 5
ENTRY(cpu_feroceon_dcache_clean_area)
#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH)
#if defined(CONFIG_CACHE_FEROCEON_L2) && \
!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
mov r2, r0
mov r3, r1
#endif
......@@ -397,7 +399,8 @@ ENTRY(cpu_feroceon_dcache_clean_area)
add r0, r0, #CACHE_DLINESIZE
subs r1, r1, #CACHE_DLINESIZE
bhi 1b
#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH)
#if defined(CONFIG_CACHE_FEROCEON_L2) && \
!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
1: mcr p15, 1, r2, c15, c9, 1 @ clean L2 entry
add r2, r2, #CACHE_DLINESIZE
subs r3, r3, #CACHE_DLINESIZE
......@@ -449,7 +452,8 @@ ENTRY(cpu_feroceon_set_pte_ext)
armv3_set_pte_ext wc_disable=0
mov r0, r0
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH)
#if defined(CONFIG_CACHE_FEROCEON_L2) && \
!defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
mcr p15, 1, r0, c15, c9, 1 @ clean L2 entry
#endif
mcr p15, 0, r0, c7, c10, 4 @ drain WB
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment