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 ...@@ -441,7 +441,7 @@ config ARCH_ORION5X
help help
Support for the following Marvell Orion 5x series SoCs: Support for the following Marvell Orion 5x series SoCs:
Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182), Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
Orion-2 (5281). Orion-2 (5281), Orion-1-90 (6183).
config ARCH_PNX4008 config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile" bool "Philips Nexperia PNX4008 Mobile"
......
...@@ -176,14 +176,17 @@ CONFIG_MACH_KUROBOX_PRO=y ...@@ -176,14 +176,17 @@ CONFIG_MACH_KUROBOX_PRO=y
CONFIG_MACH_DNS323=y CONFIG_MACH_DNS323=y
CONFIG_MACH_TS209=y CONFIG_MACH_TS209=y
CONFIG_MACH_LINKSTATION_PRO=y CONFIG_MACH_LINKSTATION_PRO=y
CONFIG_MACH_LINKSTATION_MINI=y
CONFIG_MACH_TS409=y CONFIG_MACH_TS409=y
CONFIG_MACH_WRT350N_V2=y CONFIG_MACH_WRT350N_V2=y
CONFIG_MACH_TS78XX=y CONFIG_MACH_TS78XX=y
CONFIG_MACH_MV2120=y CONFIG_MACH_MV2120=y
CONFIG_MACH_EDMINI_V2=y
CONFIG_MACH_MSS2=y CONFIG_MACH_MSS2=y
CONFIG_MACH_WNR854T=y CONFIG_MACH_WNR854T=y
CONFIG_MACH_RD88F5181L_GE=y CONFIG_MACH_RD88F5181L_GE=y
CONFIG_MACH_RD88F5181L_FXO=y CONFIG_MACH_RD88F5181L_FXO=y
CONFIG_MACH_RD88F6183AP_GE=y
# #
# Boot options # Boot options
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
struct mbus_dram_target_info kirkwood_mbus_dram_info; struct mbus_dram_target_info kirkwood_mbus_dram_info;
static int __initdata win_alloc_count;
static int __init cpu_win_can_remap(int win) static int __init cpu_win_can_remap(int win)
{ {
...@@ -111,6 +112,8 @@ void __init kirkwood_setup_cpu_mbus(void) ...@@ -111,6 +112,8 @@ void __init kirkwood_setup_cpu_mbus(void)
setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
TARGET_DEV_BUS, ATTR_DEV_NAND, -1); TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
win_alloc_count = 3;
/* /*
* Setup MBUS dram target info. * Setup MBUS dram target info.
*/ */
...@@ -137,3 +140,8 @@ void __init kirkwood_setup_cpu_mbus(void) ...@@ -137,3 +140,8 @@ void __init kirkwood_setup_cpu_mbus(void)
} }
kirkwood_mbus_dram_info.num_cs = cs; 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) ...@@ -98,7 +98,6 @@ void __init kirkwood_ehci_init(void)
* GE00 * GE00
****************************************************************************/ ****************************************************************************/
struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = { struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = {
.t_clk = KIRKWOOD_TCLK,
.dram = &kirkwood_mbus_dram_info, .dram = &kirkwood_mbus_dram_info,
}; };
...@@ -108,6 +107,11 @@ static struct resource kirkwood_ge00_shared_resources[] = { ...@@ -108,6 +107,11 @@ static struct resource kirkwood_ge00_shared_resources[] = {
.start = GE00_PHYS_BASE + 0x2000, .start = GE00_PHYS_BASE + 0x2000,
.end = GE00_PHYS_BASE + 0x3fff, .end = GE00_PHYS_BASE + 0x3fff,
.flags = IORESOURCE_MEM, .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 = { ...@@ -117,7 +121,7 @@ static struct platform_device kirkwood_ge00_shared = {
.dev = { .dev = {
.platform_data = &kirkwood_ge00_shared_data, .platform_data = &kirkwood_ge00_shared_data,
}, },
.num_resources = 1, .num_resources = ARRAY_SIZE(kirkwood_ge00_shared_resources),
.resource = 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) ...@@ -201,7 +205,6 @@ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
* SPI * SPI
****************************************************************************/ ****************************************************************************/
static struct orion_spi_info kirkwood_spi_plat_data = { static struct orion_spi_info kirkwood_spi_plat_data = {
.tclk = KIRKWOOD_TCLK,
}; };
static struct resource kirkwood_spi_resources[] = { static struct resource kirkwood_spi_resources[] = {
...@@ -239,7 +242,7 @@ static struct plat_serial8250_port kirkwood_uart0_data[] = { ...@@ -239,7 +242,7 @@ static struct plat_serial8250_port kirkwood_uart0_data[] = {
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM, .iotype = UPIO_MEM,
.regshift = 2, .regshift = 2,
.uartclk = KIRKWOOD_TCLK, .uartclk = 0,
}, { }, {
}, },
}; };
...@@ -283,7 +286,7 @@ static struct plat_serial8250_port kirkwood_uart1_data[] = { ...@@ -283,7 +286,7 @@ static struct plat_serial8250_port kirkwood_uart1_data[] = {
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM, .iotype = UPIO_MEM,
.regshift = 2, .regshift = 2,
.uartclk = KIRKWOOD_TCLK, .uartclk = 0,
}, { }, {
}, },
}; };
...@@ -525,9 +528,23 @@ void __init kirkwood_xor1_init(void) ...@@ -525,9 +528,23 @@ void __init kirkwood_xor1_init(void)
/***************************************************************************** /*****************************************************************************
* Time handling * 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) 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 = { struct sys_timer kirkwood_timer = {
...@@ -538,33 +555,62 @@ struct sys_timer kirkwood_timer = { ...@@ -538,33 +555,62 @@ struct sys_timer kirkwood_timer = {
/***************************************************************************** /*****************************************************************************
* General * General
****************************************************************************/ ****************************************************************************/
/*
* Identify device ID and revision.
*/
static char * __init kirkwood_id(void) static char * __init kirkwood_id(void)
{ {
switch (readl(DEVICE_ID) & 0x3) { u32 dev, rev;
case 0:
return "88F6180"; kirkwood_pcie_id(&dev, &rev);
case 1:
return "88F6192"; if (dev == MV88F6281_DEV_ID) {
case 2: if (rev == MV88F6281_REV_Z0)
return "88F6281"; 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) void __init kirkwood_init(void)
{ {
printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n", 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(); kirkwood_setup_cpu_mbus();
#ifdef CONFIG_CACHE_FEROCEON_L2 #ifdef CONFIG_CACHE_FEROCEON_L2
feroceon_l2_init(is_l2_writethrough()); kirkwood_l2_init();
#endif #endif
} }
...@@ -23,10 +23,9 @@ void kirkwood_init_irq(void); ...@@ -23,10 +23,9 @@ void kirkwood_init_irq(void);
extern struct mbus_dram_target_info kirkwood_mbus_dram_info; extern struct mbus_dram_target_info kirkwood_mbus_dram_info;
void kirkwood_setup_cpu_mbus(void); void kirkwood_setup_cpu_mbus(void);
void kirkwood_setup_pcie_io_win(int window, u32 base, u32 size, void kirkwood_setup_sram_win(u32 base, u32 size);
int maj, int min);
void kirkwood_setup_pcie_mem_win(int window, u32 base, u32 size, void kirkwood_pcie_id(u32 *dev, u32 *rev);
int maj, int min);
void kirkwood_ehci_init(void); void kirkwood_ehci_init(void);
void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data); void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
......
...@@ -44,7 +44,6 @@ static void __init db88f6281_init(void) ...@@ -44,7 +44,6 @@ static void __init db88f6281_init(void)
kirkwood_rtc_init(); kirkwood_rtc_init();
kirkwood_sata_init(&db88f6281_sata_data); kirkwood_sata_init(&db88f6281_sata_data);
kirkwood_uart0_init(); kirkwood_uart0_init();
kirkwood_uart1_init();
} }
static int __init db88f6281_pci_init(void) static int __init db88f6281_pci_init(void)
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#define IRQ_KIRKWOOD_GPIO_HIGH_0_7 39 #define IRQ_KIRKWOOD_GPIO_HIGH_0_7 39
#define IRQ_KIRKWOOD_GPIO_HIGH_8_15 40 #define IRQ_KIRKWOOD_GPIO_HIGH_8_15 40
#define IRQ_KIRKWOOD_GPIO_HIGH_16_23 41 #define IRQ_KIRKWOOD_GPIO_HIGH_16_23 41
#define IRQ_KIRKWOOD_GE00_ERR 46
/* /*
* KIRKWOOD General Purpose Pins * KIRKWOOD General Purpose Pins
......
...@@ -67,6 +67,20 @@ ...@@ -67,6 +67,20 @@
#define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128) #define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128)
#define L2_WRITETHROUGH 0x00000010 #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 * Register Map
*/ */
......
...@@ -8,4 +8,3 @@ ...@@ -8,4 +8,3 @@
#define CLOCK_TICK_RATE (100 * HZ) #define CLOCK_TICK_RATE (100 * HZ)
#define KIRKWOOD_TCLK 166666667
...@@ -18,6 +18,12 @@ ...@@ -18,6 +18,12 @@
#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE) #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) static int pcie_valid_config(int bus, int dev)
{ {
/* /*
......
...@@ -90,7 +90,6 @@ static void __init rd88f6281_init(void) ...@@ -90,7 +90,6 @@ static void __init rd88f6281_init(void)
kirkwood_rtc_init(); kirkwood_rtc_init();
kirkwood_sata_init(&rd88f6281_sata_data); kirkwood_sata_init(&rd88f6281_sata_data);
kirkwood_uart0_init(); kirkwood_uart0_init();
kirkwood_uart1_init();
platform_device_register(&rd88f6281_nand_flash); platform_device_register(&rd88f6281_nand_flash);
} }
......
...@@ -285,6 +285,11 @@ static struct resource mv78xx0_ge00_shared_resources[] = { ...@@ -285,6 +285,11 @@ static struct resource mv78xx0_ge00_shared_resources[] = {
.start = GE00_PHYS_BASE + 0x2000, .start = GE00_PHYS_BASE + 0x2000,
.end = GE00_PHYS_BASE + 0x3fff, .end = GE00_PHYS_BASE + 0x3fff,
.flags = IORESOURCE_MEM, .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 = { ...@@ -294,7 +299,7 @@ static struct platform_device mv78xx0_ge00_shared = {
.dev = { .dev = {
.platform_data = &mv78xx0_ge00_shared_data, .platform_data = &mv78xx0_ge00_shared_data,
}, },
.num_resources = 1, .num_resources = ARRAY_SIZE(mv78xx0_ge00_shared_resources),
.resource = mv78xx0_ge00_shared_resources, .resource = mv78xx0_ge00_shared_resources,
}; };
......
...@@ -26,14 +26,22 @@ ...@@ -26,14 +26,22 @@
ldr \tmp, [\base, #IRQ_MASK_LOW_OFF] ldr \tmp, [\base, #IRQ_MASK_LOW_OFF]
mov \irqnr, #31 mov \irqnr, #31
ands \irqstat, \irqstat, \tmp ands \irqstat, \irqstat, \tmp
bne 1001f
@ if no low interrupts set, check high interrupts @ if no low interrupts set, check high interrupts
ldreq \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF] ldr \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
ldreq \tmp, [\base, #IRQ_MASK_HIGH_OFF] ldr \tmp, [\base, #IRQ_MASK_HIGH_OFF]
moveq \irqnr, #63 mov \irqnr, #63
andeqs \irqstat, \irqstat, \tmp 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 @ find first active interrupt source
clzne \irqstat, \irqstat 1001: clzne \irqstat, \irqstat
subne \irqnr, \irqnr, \irqstat subne \irqnr, \irqnr, \irqstat
.endm .endm
...@@ -79,10 +79,15 @@ ...@@ -79,10 +79,15 @@
#define IRQ_MV78XX0_DB_IN 60 #define IRQ_MV78XX0_DB_IN 60
#define IRQ_MV78XX0_DB_OUT 61 #define IRQ_MV78XX0_DB_OUT 61
/*
* MV78xx0 Error Interrupt Controller
*/
#define IRQ_MV78XX0_GE_ERR 70
/* /*
* MV78XX0 General Purpose Pins * MV78XX0 General Purpose Pins
*/ */
#define IRQ_MV78XX0_GPIO_START 64 #define IRQ_MV78XX0_GPIO_START 96
#define NR_GPIO_IRQS GPIO_MAX #define NR_GPIO_IRQS GPIO_MAX
#define NR_IRQS (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS) #define NR_IRQS (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
......
...@@ -71,8 +71,10 @@ ...@@ -71,8 +71,10 @@
#define BRIDGE_INT_TIMER1 0x0004 #define BRIDGE_INT_TIMER1 0x0004
#define BRIDGE_INT_TIMER1_CLR (~0x0004) #define BRIDGE_INT_TIMER1_CLR (~0x0004)
#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200) #define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
#define IRQ_CAUSE_ERR_OFF 0x0000
#define IRQ_CAUSE_LOW_OFF 0x0004 #define IRQ_CAUSE_LOW_OFF 0x0004
#define IRQ_CAUSE_HIGH_OFF 0x0008 #define IRQ_CAUSE_HIGH_OFF 0x0008
#define IRQ_MASK_ERR_OFF 0x000c
#define IRQ_MASK_LOW_OFF 0x0010 #define IRQ_MASK_LOW_OFF 0x0010
#define IRQ_MASK_HIGH_OFF 0x0014 #define IRQ_MASK_HIGH_OFF 0x0014
#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
......
...@@ -19,4 +19,5 @@ void __init mv78xx0_init_irq(void) ...@@ -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(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(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 ...@@ -36,6 +36,12 @@ config MACH_TS209
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
QNAP TS-109/TS-209 platform. 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 config MACH_LINKSTATION_PRO
bool "Buffalo Linkstation Pro/Live" bool "Buffalo Linkstation Pro/Live"
select I2C_BOARDINFO select I2C_BOARDINFO
...@@ -44,6 +50,13 @@ config MACH_LINKSTATION_PRO ...@@ -44,6 +50,13 @@ config MACH_LINKSTATION_PRO
Buffalo Linkstation Pro/Live platform. Both v1 and Buffalo Linkstation Pro/Live platform. Both v1 and
v2 devices are supported. 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 config MACH_TS409
bool "QNAP TS-409" bool "QNAP TS-409"
help help
...@@ -68,6 +81,13 @@ config MACH_MV2120 ...@@ -68,6 +81,13 @@ config MACH_MV2120
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
HP Media Vault mv2120 or mv5100. 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 config MACH_MSS2
bool "Maxtor Shared Storage II" bool "Maxtor Shared Storage II"
help help
...@@ -92,6 +112,12 @@ config MACH_RD88F5181L_FXO ...@@ -92,6 +112,12 @@ config MACH_RD88F5181L_FXO
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
Marvell Orion-VoIP FXO (88F5181L) RD. 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 endmenu
endif endif
...@@ -2,14 +2,18 @@ obj-y += common.o addr-map.o pci.o gpio.o irq.o mpp.o ...@@ -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_DB88F5281) += db88f5281-setup.o
obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-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_PRO) += kurobox_pro-setup.o
obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
obj-$(CONFIG_MACH_DNS323) += dns323-setup.o obj-$(CONFIG_MACH_DNS323) += dns323-setup.o
obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o
obj-$(CONFIG_MACH_TS409) += ts409-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_WRT350N_V2) += wrt350n-v2-setup.o
obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o
obj-$(CONFIG_MACH_MV2120) += mv2120-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_MSS2) += mss2-setup.o
obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o
obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o
obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o
obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/mv643xx_i2c.h> #include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h> #include <linux/ata_platform.h>
#include <linux/spi/orion_spi.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/timex.h> #include <asm/timex.h>
...@@ -146,7 +147,6 @@ void __init orion5x_ehci1_init(void) ...@@ -146,7 +147,6 @@ void __init orion5x_ehci1_init(void)
****************************************************************************/ ****************************************************************************/
struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = { struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
.dram = &orion5x_mbus_dram_info, .dram = &orion5x_mbus_dram_info,
.t_clk = ORION5X_TCLK,
}; };
static struct resource orion5x_eth_shared_resources[] = { static struct resource orion5x_eth_shared_resources[] = {
...@@ -154,6 +154,10 @@ static struct resource orion5x_eth_shared_resources[] = { ...@@ -154,6 +154,10 @@ static struct resource orion5x_eth_shared_resources[] = {
.start = ORION5X_ETH_PHYS_BASE + 0x2000, .start = ORION5X_ETH_PHYS_BASE + 0x2000,
.end = ORION5X_ETH_PHYS_BASE + 0x3fff, .end = ORION5X_ETH_PHYS_BASE + 0x3fff,
.flags = IORESOURCE_MEM, .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 = { ...@@ -163,7 +167,7 @@ static struct platform_device orion5x_eth_shared = {
.dev = { .dev = {
.platform_data = &orion5x_eth_shared_data, .platform_data = &orion5x_eth_shared_data,
}, },
.num_resources = 1, .num_resources = ARRAY_SIZE(orion5x_eth_shared_resources),
.resource = 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) ...@@ -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 * UART0
****************************************************************************/ ****************************************************************************/
...@@ -278,7 +314,7 @@ static struct plat_serial8250_port orion5x_uart0_data[] = { ...@@ -278,7 +314,7 @@ static struct plat_serial8250_port orion5x_uart0_data[] = {
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM, .iotype = UPIO_MEM,
.regshift = 2, .regshift = 2,
.uartclk = ORION5X_TCLK, .uartclk = 0,
}, { }, {
}, },
}; };
...@@ -322,7 +358,7 @@ static struct plat_serial8250_port orion5x_uart1_data[] = { ...@@ -322,7 +358,7 @@ static struct plat_serial8250_port orion5x_uart1_data[] = {
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM, .iotype = UPIO_MEM,
.regshift = 2, .regshift = 2,
.uartclk = ORION5X_TCLK, .uartclk = 0,
}, { }, {
}, },
}; };
...@@ -455,9 +491,24 @@ void __init orion5x_xor_init(void) ...@@ -455,9 +491,24 @@ void __init orion5x_xor_init(void)
/***************************************************************************** /*****************************************************************************
* Time handling * 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) 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 = { struct sys_timer orion5x_timer = {
...@@ -499,6 +550,12 @@ static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name) ...@@ -499,6 +550,12 @@ static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
} else { } else {
*dev_name = "MV88F5181(L)-Rev-Unsupported"; *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 { } else {
*dev_name = "Device-Unknown"; *dev_name = "Device-Unknown";
} }
...@@ -510,7 +567,12 @@ void __init orion5x_init(void) ...@@ -510,7 +567,12 @@ void __init orion5x_init(void)
u32 dev, rev; u32 dev, rev;
orion5x_id(&dev, &rev, &dev_name); 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 * Setup Orion address map
......
...@@ -10,6 +10,7 @@ struct mv_sata_platform_data; ...@@ -10,6 +10,7 @@ struct mv_sata_platform_data;
void orion5x_map_io(void); void orion5x_map_io(void);
void orion5x_init_irq(void); void orion5x_init_irq(void);
void orion5x_init(void); void orion5x_init(void);
extern int orion5x_tclk;
extern struct sys_timer orion5x_timer; extern struct sys_timer orion5x_timer;
/* /*
...@@ -30,6 +31,7 @@ void orion5x_ehci1_init(void); ...@@ -30,6 +31,7 @@ void orion5x_ehci1_init(void);
void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data); void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
void orion5x_i2c_init(void); void orion5x_i2c_init(void);
void orion5x_sata_init(struct mv_sata_platform_data *sata_data); void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
void orion5x_spi_init(void);
void orion5x_uart0_init(void); void orion5x_uart0_init(void);
void orion5x_uart1_init(void); void orion5x_uart1_init(void);
void orion5x_xor_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 @@ ...@@ -2,7 +2,7 @@
* arch/arm/mach-orion5x/include/mach/orion5x.h * arch/arm/mach-orion5x/include/mach/orion5x.h
* *
* Generic definitions of Orion SoC flavors: * 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> * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
* *
...@@ -76,6 +76,9 @@ ...@@ -76,6 +76,9 @@
#define MV88F5281_REV_D0 4 #define MV88F5281_REV_D0 4
#define MV88F5281_REV_D1 5 #define MV88F5281_REV_D1 5
#define MV88F5281_REV_D2 6 #define MV88F5281_REV_D2 6
/* Orion-1-90 (88F6183) */
#define MV88F6183_DEV_ID 0x6183
#define MV88F6183_REV_B0 3
/******************************************************************************* /*******************************************************************************
* Orion Registers Map * Orion Registers Map
...@@ -86,6 +89,7 @@ ...@@ -86,6 +89,7 @@
#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000) #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_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000)
#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x)) #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 I2C_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x1000)
#define UART0_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2000) #define UART0_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2000)
#define UART0_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2000) #define UART0_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2000)
......
...@@ -9,5 +9,3 @@ ...@@ -9,5 +9,3 @@
*/ */
#define CLOCK_TICK_RATE (100 * HZ) #define CLOCK_TICK_RATE (100 * HZ)
#define ORION5X_TCLK 166666667
...@@ -293,7 +293,7 @@ static void kurobox_pro_power_off(void) ...@@ -293,7 +293,7 @@ static void kurobox_pro_power_off(void)
const unsigned char shutdownwait[] = {0x00, 0x0c}; const unsigned char shutdownwait[] = {0x00, 0x0c};
const unsigned char poweroff[] = {0x00, 0x06}; const unsigned char poweroff[] = {0x00, 0x06};
/* 38400 baud divisor */ /* 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__); 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 @@ ...@@ -16,6 +16,7 @@
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include "tsx09-common.h" #include "tsx09-common.h"
#include "common.h"
/***************************************************************************** /*****************************************************************************
* QNAP TS-x09 specific power off method via UART1-attached PIC * QNAP TS-x09 specific power off method via UART1-attached PIC
...@@ -26,7 +27,7 @@ ...@@ -26,7 +27,7 @@
void qnap_tsx09_power_off(void) void qnap_tsx09_power_off(void)
{ {
/* 19200 baud divisor */ /* 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__); pr_info("%s: triggering power-off...\n", __func__);
......
...@@ -735,6 +735,14 @@ config CACHE_FEROCEON_L2 ...@@ -735,6 +735,14 @@ config CACHE_FEROCEON_L2
help help
This option enables the Feroceon L2 cache controller. 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 config CACHE_L2X0
bool "Enable the L2x0 outer cache controller" bool "Enable the L2x0 outer cache controller"
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 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) ...@@ -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 * L2 is PIPT and range operations only do a TLB lookup on
* the start address. * the start address.
*/ */
BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); BUG_ON((start ^ end) >> PAGE_SHIFT);
raw_local_irq_save(flags); raw_local_irq_save(flags);
__asm__("mcr p15, 1, %0, c15, c9, 4" : : "r" (start)); __asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
__asm__("mcr p15, 1, %0, c15, c9, 5" : : "r" (end)); "mcr p15, 1, %1, c15, c9, 5"
: : "r" (start), "r" (end));
raw_local_irq_restore(flags); raw_local_irq_restore(flags);
} }
...@@ -80,11 +81,12 @@ static inline void l2_inv_mva_range(unsigned long start, unsigned long end) ...@@ -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 * L2 is PIPT and range operations only do a TLB lookup on
* the start address. * the start address.
*/ */
BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); BUG_ON((start ^ end) >> PAGE_SHIFT);
raw_local_irq_save(flags); raw_local_irq_save(flags);
__asm__("mcr p15, 1, %0, c15, c11, 4" : : "r" (start)); __asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
__asm__("mcr p15, 1, %0, c15, c11, 5" : : "r" (end)); "mcr p15, 1, %1, c15, c11, 5"
: : "r" (start), "r" (end));
raw_local_irq_restore(flags); raw_local_irq_restore(flags);
} }
...@@ -205,7 +207,7 @@ static void feroceon_l2_flush_range(unsigned long start, unsigned long end) ...@@ -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 * time. These are necessary because the L2 cache can only be enabled
* or disabled while the L1 Dcache and Icache are both disabled. * 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; u32 cr;
...@@ -217,7 +219,9 @@ static void __init invalidate_and_disable_dcache(void) ...@@ -217,7 +219,9 @@ static void __init invalidate_and_disable_dcache(void)
flush_cache_all(); flush_cache_all();
set_cr(cr & ~CR_C); set_cr(cr & ~CR_C);
raw_local_irq_restore(flags); raw_local_irq_restore(flags);
return 1;
} }
return 0;
} }
static void __init enable_dcache(void) static void __init enable_dcache(void)
...@@ -225,18 +229,17 @@ static void __init enable_dcache(void) ...@@ -225,18 +229,17 @@ static void __init enable_dcache(void)
u32 cr; u32 cr;
cr = get_cr(); cr = get_cr();
if (!(cr & CR_C)) set_cr(cr | CR_C);
set_cr(cr | CR_C);
} }
static void __init __invalidate_icache(void) static void __init __invalidate_icache(void)
{ {
int dummy; 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; u32 cr;
...@@ -244,7 +247,9 @@ static void __init invalidate_and_disable_icache(void) ...@@ -244,7 +247,9 @@ static void __init invalidate_and_disable_icache(void)
if (cr & CR_I) { if (cr & CR_I) {
set_cr(cr & ~CR_I); set_cr(cr & ~CR_I);
__invalidate_icache(); __invalidate_icache();
return 1;
} }
return 0;
} }
static void __init enable_icache(void) static void __init enable_icache(void)
...@@ -252,8 +257,7 @@ static void __init enable_icache(void) ...@@ -252,8 +257,7 @@ static void __init enable_icache(void)
u32 cr; u32 cr;
cr = get_cr(); cr = get_cr();
if (!(cr & CR_I)) set_cr(cr | CR_I);
set_cr(cr | CR_I);
} }
static inline u32 read_extra_features(void) static inline u32 read_extra_features(void)
...@@ -291,13 +295,17 @@ static void __init enable_l2(void) ...@@ -291,13 +295,17 @@ static void __init enable_l2(void)
u = read_extra_features(); u = read_extra_features();
if (!(u & 0x00400000)) { if (!(u & 0x00400000)) {
int i, d;
printk(KERN_INFO "Feroceon L2: Enabling L2\n"); printk(KERN_INFO "Feroceon L2: Enabling L2\n");
invalidate_and_disable_dcache(); d = flush_and_disable_dcache();
invalidate_and_disable_icache(); i = invalidate_and_disable_icache();
write_extra_features(u | 0x00400000); write_extra_features(u | 0x00400000);
enable_icache(); if (i)
enable_dcache(); enable_icache();
if (d)
enable_dcache();
} }
} }
......
...@@ -80,7 +80,8 @@ ENTRY(cpu_feroceon_proc_fin) ...@@ -80,7 +80,8 @@ ENTRY(cpu_feroceon_proc_fin)
msr cpsr_c, ip msr cpsr_c, ip
bl feroceon_flush_kern_cache_all 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 mov r0, #0
mcr p15, 1, r0, c15, c9, 0 @ clean L2 mcr p15, 1, r0, c15, c9, 0 @ clean L2
mcr p15, 0, r0, c7, c10, 4 @ drain WB mcr p15, 0, r0, c7, c10, 4 @ drain WB
...@@ -389,7 +390,8 @@ ENTRY(feroceon_range_cache_fns) ...@@ -389,7 +390,8 @@ ENTRY(feroceon_range_cache_fns)
.align 5 .align 5
ENTRY(cpu_feroceon_dcache_clean_area) 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 r2, r0
mov r3, r1 mov r3, r1
#endif #endif
...@@ -397,7 +399,8 @@ ENTRY(cpu_feroceon_dcache_clean_area) ...@@ -397,7 +399,8 @@ ENTRY(cpu_feroceon_dcache_clean_area)
add r0, r0, #CACHE_DLINESIZE add r0, r0, #CACHE_DLINESIZE
subs r1, r1, #CACHE_DLINESIZE subs r1, r1, #CACHE_DLINESIZE
bhi 1b 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 1: mcr p15, 1, r2, c15, c9, 1 @ clean L2 entry
add r2, r2, #CACHE_DLINESIZE add r2, r2, #CACHE_DLINESIZE
subs r3, r3, #CACHE_DLINESIZE subs r3, r3, #CACHE_DLINESIZE
...@@ -449,7 +452,8 @@ ENTRY(cpu_feroceon_set_pte_ext) ...@@ -449,7 +452,8 @@ ENTRY(cpu_feroceon_set_pte_ext)
armv3_set_pte_ext wc_disable=0 armv3_set_pte_ext wc_disable=0
mov r0, r0 mov r0, r0
mcr p15, 0, r0, c7, c10, 1 @ clean D entry 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 mcr p15, 1, r0, c15, c9, 1 @ clean L2 entry
#endif #endif
mcr p15, 0, r0, c7, c10, 4 @ drain WB 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