mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 17:18:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
165
arch/arm/mach-orion5x/Kconfig
Normal file
165
arch/arm/mach-orion5x/Kconfig
Normal file
|
@ -0,0 +1,165 @@
|
|||
if ARCH_ORION5X
|
||||
|
||||
menu "Orion Implementations"
|
||||
|
||||
config ARCH_ORION5X_DT
|
||||
bool "Marvell Orion5x Flattened Device Tree"
|
||||
select USE_OF
|
||||
select ORION_CLK
|
||||
select ORION_IRQCHIP
|
||||
select ORION_TIMER
|
||||
select PINCTRL
|
||||
select PINCTRL_ORION
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Marvell Orion5x using flattened device tree.
|
||||
|
||||
config MACH_DB88F5281
|
||||
bool "Marvell Orion-2 Development Board"
|
||||
select I2C_BOARDINFO
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Marvell Orion-2 (88F5281) Development Board
|
||||
|
||||
config MACH_RD88F5182
|
||||
bool "Marvell Orion-NAS Reference Design"
|
||||
select I2C_BOARDINFO
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Marvell Orion-NAS (88F5182) RD2
|
||||
|
||||
config MACH_RD88F5182_DT
|
||||
bool "Marvell Orion-NAS Reference Design (Flattened Device Tree)"
|
||||
select ARCH_ORION5X_DT
|
||||
select I2C_BOARDINFO
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the Marvell
|
||||
Orion-NAS (88F5182) RD2, Flattened Device Tree.
|
||||
|
||||
config MACH_KUROBOX_PRO
|
||||
bool "KuroBox Pro"
|
||||
select I2C_BOARDINFO
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
KuroBox Pro platform.
|
||||
|
||||
config MACH_DNS323
|
||||
bool "D-Link DNS-323"
|
||||
select I2C_BOARDINFO
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
D-Link DNS-323 platform.
|
||||
|
||||
config MACH_TS209
|
||||
bool "QNAP TS-109/TS-209"
|
||||
help
|
||||
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
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Buffalo Linkstation Pro/Live platform. Both v1 and
|
||||
v2 devices are supported.
|
||||
|
||||
config MACH_LINKSTATION_LSCHL
|
||||
bool "Buffalo Linkstation Live v3 (LS-CHL)"
|
||||
select I2C_BOARDINFO
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Buffalo Linkstation Live v3 (LS-CHL) platform.
|
||||
|
||||
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_LINKSTATION_LS_HGL
|
||||
bool "Buffalo Linkstation LS-HGL"
|
||||
select I2C_BOARDINFO
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Buffalo Linkstation LS-HGL platform.
|
||||
|
||||
config MACH_TS409
|
||||
bool "QNAP TS-409"
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
QNAP TS-409 platform.
|
||||
|
||||
config MACH_WRT350N_V2
|
||||
bool "Linksys WRT350N v2"
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Linksys WRT350N v2 platform.
|
||||
|
||||
config MACH_TS78XX
|
||||
bool "Technologic Systems TS-78xx"
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Technologic Systems TS-78xx platform.
|
||||
|
||||
config MACH_MV2120
|
||||
bool "HP Media Vault mv2120"
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
HP Media Vault mv2120 or mv5100.
|
||||
|
||||
config MACH_D2NET_DT
|
||||
bool "LaCie d2 Network / Big Disk Network (Flattened Device Tree)"
|
||||
select ARCH_ORION5X_DT
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
LaCie d2 Network NAS.
|
||||
|
||||
config MACH_NET2BIG
|
||||
bool "LaCie 2Big Network"
|
||||
select I2C_BOARDINFO
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
LaCie 2Big Network NAS.
|
||||
|
||||
config MACH_MSS2_DT
|
||||
bool "Maxtor Shared Storage II (Flattened Device Tree)"
|
||||
select ARCH_ORION5X_DT
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Maxtor Shared Storage II platform.
|
||||
|
||||
config MACH_WNR854T
|
||||
bool "Netgear WNR854T"
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Netgear WNR854T platform.
|
||||
|
||||
config MACH_RD88F5181L_GE
|
||||
bool "Marvell Orion-VoIP GE Reference Design"
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Marvell Orion-VoIP GE (88F5181L) RD.
|
||||
|
||||
config MACH_RD88F5181L_FXO
|
||||
bool "Marvell Orion-VoIP FXO Reference Design"
|
||||
help
|
||||
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
|
25
arch/arm/mach-orion5x/Makefile
Normal file
25
arch/arm/mach-orion5x/Makefile
Normal file
|
@ -0,0 +1,25 @@
|
|||
obj-y += common.o pci.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_LINKSTATION_LS_HGL) += ls_hgl-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_NET2BIG) += net2big-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
|
||||
obj-$(CONFIG_MACH_LINKSTATION_LSCHL) += ls-chl-setup.o
|
||||
|
||||
obj-$(CONFIG_ARCH_ORION5X_DT) += board-dt.o
|
||||
obj-$(CONFIG_MACH_D2NET_DT) += board-d2net.o
|
||||
obj-$(CONFIG_MACH_MSS2_DT) += board-mss2.o
|
||||
obj-$(CONFIG_MACH_RD88F5182_DT) += board-rd88f5182.o
|
3
arch/arm/mach-orion5x/Makefile.boot
Normal file
3
arch/arm/mach-orion5x/Makefile.boot
Normal file
|
@ -0,0 +1,3 @@
|
|||
zreladdr-y += 0x00008000
|
||||
params_phys-y := 0x00000100
|
||||
initrd_phys-y := 0x00800000
|
109
arch/arm/mach-orion5x/board-d2net.c
Normal file
109
arch/arm/mach-orion5x/board-d2net.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/board-d2net.c
|
||||
*
|
||||
* LaCie d2Network and Big Disk Network NAS setup
|
||||
*
|
||||
* Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
|
||||
*
|
||||
* 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/leds.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 <plat/orion-gpio.h>
|
||||
#include "common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* LaCie d2 Network Info
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* GPIO LED's
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* The blue front LED is wired to the CPLD and can blink in relation with the
|
||||
* SATA activity.
|
||||
*
|
||||
* The following array detail the different LED registers and the combination
|
||||
* of their possible values:
|
||||
*
|
||||
* led_off | blink_ctrl | SATA active | LED state
|
||||
* | | |
|
||||
* 1 | x | x | off
|
||||
* 0 | 0 | 0 | off
|
||||
* 0 | 1 | 0 | blink (rate 300ms)
|
||||
* 0 | x | 1 | on
|
||||
*
|
||||
* Notes: The blue and the red front LED's can't be on at the same time.
|
||||
* Red LED have priority.
|
||||
*/
|
||||
|
||||
#define D2NET_GPIO_RED_LED 6
|
||||
#define D2NET_GPIO_BLUE_LED_BLINK_CTRL 16
|
||||
#define D2NET_GPIO_BLUE_LED_OFF 23
|
||||
|
||||
static struct gpio_led d2net_leds[] = {
|
||||
{
|
||||
.name = "d2net:blue:sata",
|
||||
.default_trigger = "default-on",
|
||||
.gpio = D2NET_GPIO_BLUE_LED_OFF,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "d2net:red:fail",
|
||||
.gpio = D2NET_GPIO_RED_LED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data d2net_led_data = {
|
||||
.num_leds = ARRAY_SIZE(d2net_leds),
|
||||
.leds = d2net_leds,
|
||||
};
|
||||
|
||||
static struct platform_device d2net_gpio_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &d2net_led_data,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init d2net_gpio_leds_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Configure register blink_ctrl to allow SATA activity LED blinking. */
|
||||
err = gpio_request(D2NET_GPIO_BLUE_LED_BLINK_CTRL, "blue LED blink");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(D2NET_GPIO_BLUE_LED_BLINK_CTRL, 1);
|
||||
if (err)
|
||||
gpio_free(D2NET_GPIO_BLUE_LED_BLINK_CTRL);
|
||||
}
|
||||
if (err)
|
||||
pr_err("d2net: failed to configure blue LED blink GPIO\n");
|
||||
|
||||
platform_device_register(&d2net_gpio_leds);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
|
||||
void __init d2net_init(void)
|
||||
{
|
||||
d2net_gpio_leds_init();
|
||||
|
||||
pr_notice("d2net: Flash write are not yet supported.\n");
|
||||
}
|
82
arch/arm/mach-orion5x/board-dt.c
Normal file
82
arch/arm/mach-orion5x/board-dt.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2012 (C), Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* arch/arm/mach-orion5x/board-dt.c
|
||||
*
|
||||
* Flattened Device Tree board initialization
|
||||
*
|
||||
* 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/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/mbus.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <asm/system_misc.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include <mach/bridge-regs.h>
|
||||
#include <plat/irq.h>
|
||||
#include <plat/time.h>
|
||||
#include "common.h"
|
||||
|
||||
static struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
|
||||
OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
|
||||
OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
|
||||
NULL),
|
||||
OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
|
||||
OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
|
||||
OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1090000, "mv_crypto", NULL),
|
||||
{},
|
||||
};
|
||||
|
||||
static void __init orion5x_dt_init(void)
|
||||
{
|
||||
char *dev_name;
|
||||
u32 dev, rev;
|
||||
|
||||
orion5x_id(&dev, &rev, &dev_name);
|
||||
printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
|
||||
|
||||
BUG_ON(mvebu_mbus_dt_init(false));
|
||||
|
||||
/*
|
||||
* Setup Orion address map
|
||||
*/
|
||||
orion5x_setup_wins();
|
||||
|
||||
/*
|
||||
* Don't issue "Wait for Interrupt" instruction if we are
|
||||
* running on D0 5281 silicon.
|
||||
*/
|
||||
if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
|
||||
printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
|
||||
cpu_idle_poll_ctrl(true);
|
||||
}
|
||||
|
||||
if (of_machine_is_compatible("maxtor,shared-storage-2"))
|
||||
mss2_init();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
orion5x_auxdata_lookup, NULL);
|
||||
}
|
||||
|
||||
static const char *orion5x_dt_compat[] = {
|
||||
"marvell,orion5x",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(ORION5X_DT, "Marvell Orion5x (Flattened Device Tree)")
|
||||
/* Maintainer: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> */
|
||||
.map_io = orion5x_map_io,
|
||||
.init_machine = orion5x_dt_init,
|
||||
.restart = orion5x_restart,
|
||||
.dt_compat = orion5x_dt_compat,
|
||||
MACHINE_END
|
90
arch/arm/mach-orion5x/board-mss2.c
Normal file
90
arch/arm/mach-orion5x/board-mss2.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Maxtor Shared Storage II 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 <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include <mach/bridge-regs.h>
|
||||
#include "common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Maxtor Shared Storage II Info
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* PCI setup
|
||||
****************************************************************************/
|
||||
static int __init mss2_pci_map_irq(const 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;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct hw_pci mss2_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = mss2_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init mss2_pci_init(void)
|
||||
{
|
||||
if (machine_is_mss2())
|
||||
pci_common_init(&mss2_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(mss2_pci_init);
|
||||
|
||||
/*****************************************************************************
|
||||
* MSS2 power off method
|
||||
****************************************************************************/
|
||||
/*
|
||||
* On the Maxtor Shared Storage II, the shutdown process is the following :
|
||||
* - Userland modifies U-boot env to tell U-boot to go idle at next boot
|
||||
* - The board reboots
|
||||
* - U-boot starts and go into an idle mode until the user press "power"
|
||||
*/
|
||||
static void mss2_power_off(void)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Enable and issue soft reset
|
||||
*/
|
||||
reg = readl(RSTOUTn_MASK);
|
||||
reg |= 1 << 2;
|
||||
writel(reg, RSTOUTn_MASK);
|
||||
|
||||
reg = readl(CPU_SOFT_RESET);
|
||||
reg |= 1;
|
||||
writel(reg, CPU_SOFT_RESET);
|
||||
}
|
||||
|
||||
void __init mss2_init(void)
|
||||
{
|
||||
/* register mss2 specific power-off method */
|
||||
pm_power_off = mss2_power_off;
|
||||
}
|
116
arch/arm/mach-orion5x/board-rd88f5182.c
Normal file
116
arch/arm/mach-orion5x/board-rd88f5182.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/rd88f5182-setup.c
|
||||
*
|
||||
* Marvell Orion-NAS Reference Design Setup
|
||||
*
|
||||
* Maintainer: Ronen Shitrit <rshitrit@marvell.com>
|
||||
*
|
||||
* 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/gpio.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include "common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* RD-88F5182 Info
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* PCI
|
||||
*/
|
||||
|
||||
#define RD88F5182_PCI_SLOT0_OFFS 7
|
||||
#define RD88F5182_PCI_SLOT0_IRQ_A_PIN 7
|
||||
#define RD88F5182_PCI_SLOT0_IRQ_B_PIN 6
|
||||
|
||||
/*****************************************************************************
|
||||
* PCI
|
||||
****************************************************************************/
|
||||
|
||||
static void __init rd88f5182_pci_preinit(void)
|
||||
{
|
||||
int pin;
|
||||
|
||||
/*
|
||||
* Configure PCI GPIO IRQ pins
|
||||
*/
|
||||
pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
|
||||
if (gpio_request(pin, "PCI IntA") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit failed to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
gpio_free(pin);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit failed to request gpio %d\n", pin);
|
||||
}
|
||||
|
||||
pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
|
||||
if (gpio_request(pin, "PCI IntB") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit failed to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
gpio_free(pin);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit failed to gpio_request %d\n", pin);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init rd88f5182_pci_map_irq(const 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
|
||||
*/
|
||||
switch (slot - RD88F5182_PCI_SLOT0_OFFS) {
|
||||
case 0:
|
||||
if (pin == 1)
|
||||
return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_A_PIN);
|
||||
else
|
||||
return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_B_PIN);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct hw_pci rd88f5182_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.preinit = rd88f5182_pci_preinit,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = rd88f5182_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init rd88f5182_pci_init(void)
|
||||
{
|
||||
if (of_machine_is_compatible("marvell,rd-88f5182-nas"))
|
||||
pci_common_init(&rd88f5182_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(rd88f5182_pci_init);
|
379
arch/arm/mach-orion5x/common.c
Normal file
379
arch/arm/mach-orion5x/common.c
Normal file
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/common.c
|
||||
*
|
||||
* Core functions for Marvell Orion 5x SoCs
|
||||
*
|
||||
* Maintainer: Tzachi Perelstein <tzachi@marvell.com>
|
||||
*
|
||||
* 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/dma-mapping.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/mv643xx_i2c.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <net/dsa.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/system_misc.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/bridge-regs.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include <linux/platform_data/mtd-orion_nand.h>
|
||||
#include <linux/platform_data/usb-ehci-orion.h>
|
||||
#include <plat/time.h>
|
||||
#include <plat/common.h>
|
||||
#include "common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* I/O Address Mapping
|
||||
****************************************************************************/
|
||||
static struct map_desc orion5x_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = (unsigned long) ORION5X_REGS_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
|
||||
.length = ORION5X_REGS_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = (unsigned long) ORION5X_PCIE_WA_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
|
||||
.length = ORION5X_PCIE_WA_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
},
|
||||
};
|
||||
|
||||
void __init orion5x_map_io(void)
|
||||
{
|
||||
iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc));
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* CLK tree
|
||||
****************************************************************************/
|
||||
static struct clk *tclk;
|
||||
|
||||
void __init clk_init(void)
|
||||
{
|
||||
tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
|
||||
orion5x_tclk);
|
||||
|
||||
orion_clkdev_init(tclk);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* EHCI0
|
||||
****************************************************************************/
|
||||
void __init orion5x_ehci0_init(void)
|
||||
{
|
||||
orion_ehci_init(ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL,
|
||||
EHCI_PHY_ORION);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* EHCI1
|
||||
****************************************************************************/
|
||||
void __init orion5x_ehci1_init(void)
|
||||
{
|
||||
orion_ehci_1_init(ORION5X_USB1_PHYS_BASE, IRQ_ORION5X_USB1_CTRL);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* GE00
|
||||
****************************************************************************/
|
||||
void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
|
||||
{
|
||||
orion_ge00_init(eth_data,
|
||||
ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
|
||||
IRQ_ORION5X_ETH_ERR,
|
||||
MV643XX_TX_CSUM_DEFAULT_LIMIT);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet switch
|
||||
****************************************************************************/
|
||||
void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
|
||||
{
|
||||
orion_ge00_switch_init(d, irq);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* I2C
|
||||
****************************************************************************/
|
||||
void __init orion5x_i2c_init(void)
|
||||
{
|
||||
orion_i2c_init(I2C_PHYS_BASE, IRQ_ORION5X_I2C, 8);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
|
||||
{
|
||||
orion_sata_init(sata_data, ORION5X_SATA_PHYS_BASE, IRQ_ORION5X_SATA);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* SPI
|
||||
****************************************************************************/
|
||||
void __init orion5x_spi_init(void)
|
||||
{
|
||||
orion_spi_init(SPI_PHYS_BASE);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* UART0
|
||||
****************************************************************************/
|
||||
void __init orion5x_uart0_init(void)
|
||||
{
|
||||
orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
|
||||
IRQ_ORION5X_UART0, tclk);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* UART1
|
||||
****************************************************************************/
|
||||
void __init orion5x_uart1_init(void)
|
||||
{
|
||||
orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
|
||||
IRQ_ORION5X_UART1, tclk);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* XOR engine
|
||||
****************************************************************************/
|
||||
void __init orion5x_xor_init(void)
|
||||
{
|
||||
orion_xor0_init(ORION5X_XOR_PHYS_BASE,
|
||||
ORION5X_XOR_PHYS_BASE + 0x200,
|
||||
IRQ_ORION5X_XOR0, IRQ_ORION5X_XOR1);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Cryptographic Engines and Security Accelerator (CESA)
|
||||
****************************************************************************/
|
||||
static void __init orion5x_crypto_init(void)
|
||||
{
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_SRAM_TARGET,
|
||||
ORION_MBUS_SRAM_ATTR,
|
||||
ORION5X_SRAM_PHYS_BASE,
|
||||
ORION5X_SRAM_SIZE);
|
||||
orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
|
||||
SZ_8K, IRQ_ORION5X_CESA);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Watchdog
|
||||
****************************************************************************/
|
||||
static void __init orion5x_wdt_init(void)
|
||||
{
|
||||
orion_wdt_init();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Time handling
|
||||
****************************************************************************/
|
||||
void __init orion5x_init_early(void)
|
||||
{
|
||||
u32 rev, dev;
|
||||
const char *mbus_soc_name;
|
||||
|
||||
orion_time_set_base(TIMER_VIRT_BASE);
|
||||
|
||||
/* Initialize the MBUS driver */
|
||||
orion5x_pcie_id(&dev, &rev);
|
||||
if (dev == MV88F5281_DEV_ID)
|
||||
mbus_soc_name = "marvell,orion5x-88f5281-mbus";
|
||||
else if (dev == MV88F5182_DEV_ID)
|
||||
mbus_soc_name = "marvell,orion5x-88f5182-mbus";
|
||||
else if (dev == MV88F5181_DEV_ID)
|
||||
mbus_soc_name = "marvell,orion5x-88f5181-mbus";
|
||||
else if (dev == MV88F6183_DEV_ID)
|
||||
mbus_soc_name = "marvell,orion5x-88f6183-mbus";
|
||||
else
|
||||
mbus_soc_name = NULL;
|
||||
mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE,
|
||||
ORION5X_BRIDGE_WINS_SZ,
|
||||
ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ);
|
||||
}
|
||||
|
||||
void orion5x_setup_wins(void)
|
||||
{
|
||||
/*
|
||||
* The PCIe windows will no longer be statically allocated
|
||||
* here once Orion5x is migrated to the pci-mvebu driver.
|
||||
*/
|
||||
mvebu_mbus_add_window_remap_by_id(ORION_MBUS_PCIE_IO_TARGET,
|
||||
ORION_MBUS_PCIE_IO_ATTR,
|
||||
ORION5X_PCIE_IO_PHYS_BASE,
|
||||
ORION5X_PCIE_IO_SIZE,
|
||||
ORION5X_PCIE_IO_BUS_BASE);
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_PCIE_MEM_TARGET,
|
||||
ORION_MBUS_PCIE_MEM_ATTR,
|
||||
ORION5X_PCIE_MEM_PHYS_BASE,
|
||||
ORION5X_PCIE_MEM_SIZE);
|
||||
mvebu_mbus_add_window_remap_by_id(ORION_MBUS_PCI_IO_TARGET,
|
||||
ORION_MBUS_PCI_IO_ATTR,
|
||||
ORION5X_PCI_IO_PHYS_BASE,
|
||||
ORION5X_PCI_IO_SIZE,
|
||||
ORION5X_PCI_IO_BUS_BASE);
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_PCI_MEM_TARGET,
|
||||
ORION_MBUS_PCI_MEM_ATTR,
|
||||
ORION5X_PCI_MEM_PHYS_BASE,
|
||||
ORION5X_PCI_MEM_SIZE);
|
||||
}
|
||||
|
||||
int orion5x_tclk;
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
void __init orion5x_timer_init(void)
|
||||
{
|
||||
orion5x_tclk = orion5x_find_tclk();
|
||||
|
||||
orion_time_init(ORION5X_BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
|
||||
IRQ_ORION5X_BRIDGE, orion5x_tclk);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* General
|
||||
****************************************************************************/
|
||||
/*
|
||||
* Identify device ID and rev from PCIe configuration header space '0'.
|
||||
*/
|
||||
void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
|
||||
{
|
||||
orion5x_pcie_id(dev, rev);
|
||||
|
||||
if (*dev == MV88F5281_DEV_ID) {
|
||||
if (*rev == MV88F5281_REV_D2) {
|
||||
*dev_name = "MV88F5281-D2";
|
||||
} else if (*rev == MV88F5281_REV_D1) {
|
||||
*dev_name = "MV88F5281-D1";
|
||||
} else if (*rev == MV88F5281_REV_D0) {
|
||||
*dev_name = "MV88F5281-D0";
|
||||
} else {
|
||||
*dev_name = "MV88F5281-Rev-Unsupported";
|
||||
}
|
||||
} else if (*dev == MV88F5182_DEV_ID) {
|
||||
if (*rev == MV88F5182_REV_A2) {
|
||||
*dev_name = "MV88F5182-A2";
|
||||
} else {
|
||||
*dev_name = "MV88F5182-Rev-Unsupported";
|
||||
}
|
||||
} else if (*dev == MV88F5181_DEV_ID) {
|
||||
if (*rev == MV88F5181_REV_B1) {
|
||||
*dev_name = "MV88F5181-Rev-B1";
|
||||
} else if (*rev == MV88F5181L_REV_A1) {
|
||||
*dev_name = "MV88F5181L-Rev-A1";
|
||||
} 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";
|
||||
}
|
||||
}
|
||||
|
||||
void __init orion5x_init(void)
|
||||
{
|
||||
char *dev_name;
|
||||
u32 dev, rev;
|
||||
|
||||
orion5x_id(&dev, &rev, &dev_name);
|
||||
printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
|
||||
|
||||
/*
|
||||
* Setup Orion address map
|
||||
*/
|
||||
orion5x_setup_wins();
|
||||
|
||||
/* Setup root of clk tree */
|
||||
clk_init();
|
||||
|
||||
/*
|
||||
* Don't issue "Wait for Interrupt" instruction if we are
|
||||
* running on D0 5281 silicon.
|
||||
*/
|
||||
if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
|
||||
printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
|
||||
cpu_idle_poll_ctrl(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* The 5082/5181l/5182/6082/6082l/6183 have crypto
|
||||
* while 5180n/5181/5281 don't have crypto.
|
||||
*/
|
||||
if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) ||
|
||||
dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID)
|
||||
orion5x_crypto_init();
|
||||
|
||||
/*
|
||||
* Register watchdog driver
|
||||
*/
|
||||
orion5x_wdt_init();
|
||||
}
|
||||
|
||||
void orion5x_restart(enum reboot_mode mode, const char *cmd)
|
||||
{
|
||||
/*
|
||||
* Enable and issue soft reset
|
||||
*/
|
||||
orion5x_setbits(RSTOUTn_MASK, (1 << 2));
|
||||
orion5x_setbits(CPU_SOFT_RESET, 1);
|
||||
mdelay(200);
|
||||
orion5x_clrbits(CPU_SOFT_RESET, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Many orion-based systems have buggy bootloader implementations.
|
||||
* This is a common fixup for bogus memory tags.
|
||||
*/
|
||||
void __init tag_fixup_mem32(struct tag *t, char **from)
|
||||
{
|
||||
for (; t->hdr.size; t = tag_next(t))
|
||||
if (t->hdr.tag == ATAG_MEM &&
|
||||
(!t->u.mem.size || t->u.mem.size & ~PAGE_MASK ||
|
||||
t->u.mem.start & ~PAGE_MASK)) {
|
||||
printk(KERN_WARNING
|
||||
"Clearing invalid memory bank %dKB@0x%08x\n",
|
||||
t->u.mem.size / 1024, t->u.mem.start);
|
||||
t->hdr.tag = 0;
|
||||
}
|
||||
}
|
86
arch/arm/mach-orion5x/common.h
Normal file
86
arch/arm/mach-orion5x/common.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
#ifndef __ARCH_ORION5X_COMMON_H
|
||||
#define __ARCH_ORION5X_COMMON_H
|
||||
|
||||
#include <linux/reboot.h>
|
||||
|
||||
struct dsa_platform_data;
|
||||
struct mv643xx_eth_platform_data;
|
||||
struct mv_sata_platform_data;
|
||||
|
||||
#define ORION_MBUS_PCIE_MEM_TARGET 0x04
|
||||
#define ORION_MBUS_PCIE_MEM_ATTR 0x59
|
||||
#define ORION_MBUS_PCIE_IO_TARGET 0x04
|
||||
#define ORION_MBUS_PCIE_IO_ATTR 0x51
|
||||
#define ORION_MBUS_PCIE_WA_TARGET 0x04
|
||||
#define ORION_MBUS_PCIE_WA_ATTR 0x79
|
||||
#define ORION_MBUS_PCI_MEM_TARGET 0x03
|
||||
#define ORION_MBUS_PCI_MEM_ATTR 0x59
|
||||
#define ORION_MBUS_PCI_IO_TARGET 0x03
|
||||
#define ORION_MBUS_PCI_IO_ATTR 0x51
|
||||
#define ORION_MBUS_DEVBUS_BOOT_TARGET 0x01
|
||||
#define ORION_MBUS_DEVBUS_BOOT_ATTR 0x0f
|
||||
#define ORION_MBUS_DEVBUS_TARGET(cs) 0x01
|
||||
#define ORION_MBUS_DEVBUS_ATTR(cs) (~(1 << cs))
|
||||
#define ORION_MBUS_SRAM_TARGET 0x09
|
||||
#define ORION_MBUS_SRAM_ATTR 0x00
|
||||
|
||||
/*
|
||||
* Basic Orion init functions used early by machine-setup.
|
||||
*/
|
||||
void orion5x_map_io(void);
|
||||
void orion5x_init_early(void);
|
||||
void orion5x_init_irq(void);
|
||||
void orion5x_init(void);
|
||||
void orion5x_id(u32 *dev, u32 *rev, char **dev_name);
|
||||
void clk_init(void);
|
||||
extern int orion5x_tclk;
|
||||
extern void orion5x_timer_init(void);
|
||||
|
||||
void orion5x_setup_wins(void);
|
||||
|
||||
void orion5x_ehci0_init(void);
|
||||
void orion5x_ehci1_init(void);
|
||||
void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
|
||||
void orion5x_eth_switch_init(struct dsa_platform_data *d, int irq);
|
||||
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);
|
||||
void orion5x_restart(enum reboot_mode, const char *);
|
||||
|
||||
/*
|
||||
* PCIe/PCI functions.
|
||||
*/
|
||||
struct pci_bus;
|
||||
struct pci_sys_data;
|
||||
struct pci_dev;
|
||||
|
||||
void orion5x_pcie_id(u32 *dev, u32 *rev);
|
||||
void orion5x_pci_disable(void);
|
||||
void orion5x_pci_set_cardbus_mode(void);
|
||||
int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys);
|
||||
struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
|
||||
int orion5x_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
|
||||
|
||||
struct tag;
|
||||
extern void __init tag_fixup_mem32(struct tag *, char **);
|
||||
|
||||
#ifdef CONFIG_MACH_MSS2_DT
|
||||
extern void mss2_init(void);
|
||||
#else
|
||||
static inline void mss2_init(void) {}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Helpers to access Orion registers
|
||||
****************************************************************************/
|
||||
/*
|
||||
* These are not preempt-safe. Locks, if needed, must be taken
|
||||
* care of by the caller.
|
||||
*/
|
||||
#define orion5x_setbits(r, mask) writel(readl(r) | (mask), (r))
|
||||
#define orion5x_clrbits(r, mask) writel(readl(r) & ~(mask), (r))
|
||||
|
||||
#endif
|
378
arch/arm/mach-orion5x/db88f5281-setup.c
Normal file
378
arch/arm/mach-orion5x/db88f5281-setup.c
Normal file
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/db88f5281-setup.c
|
||||
*
|
||||
* Marvell Orion-2 Development Board Setup
|
||||
*
|
||||
* Maintainer: Tzachi Perelstein <tzachi@marvell.com>
|
||||
*
|
||||
* 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/gpio.h>
|
||||
#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/mtd/nand.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include <linux/platform_data/mtd-orion_nand.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* DB-88F5281 on board devices
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* 512K NOR flash Device bus boot chip select
|
||||
*/
|
||||
|
||||
#define DB88F5281_NOR_BOOT_BASE 0xf4000000
|
||||
#define DB88F5281_NOR_BOOT_SIZE SZ_512K
|
||||
|
||||
/*
|
||||
* 7-Segment on Device bus chip select 0
|
||||
*/
|
||||
|
||||
#define DB88F5281_7SEG_BASE 0xfa000000
|
||||
#define DB88F5281_7SEG_SIZE SZ_1K
|
||||
|
||||
/*
|
||||
* 32M NOR flash on Device bus chip select 1
|
||||
*/
|
||||
|
||||
#define DB88F5281_NOR_BASE 0xfc000000
|
||||
#define DB88F5281_NOR_SIZE SZ_32M
|
||||
|
||||
/*
|
||||
* 32M NAND flash on Device bus chip select 2
|
||||
*/
|
||||
|
||||
#define DB88F5281_NAND_BASE 0xfa800000
|
||||
#define DB88F5281_NAND_SIZE SZ_1K
|
||||
|
||||
/*
|
||||
* PCI
|
||||
*/
|
||||
|
||||
#define DB88F5281_PCI_SLOT0_OFFS 7
|
||||
#define DB88F5281_PCI_SLOT0_IRQ_PIN 12
|
||||
#define DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN 13
|
||||
|
||||
/*****************************************************************************
|
||||
* 512M NOR Flash on Device bus Boot CS
|
||||
****************************************************************************/
|
||||
|
||||
static struct physmap_flash_data db88f5281_boot_flash_data = {
|
||||
.width = 1, /* 8 bit bus width */
|
||||
};
|
||||
|
||||
static struct resource db88f5281_boot_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = DB88F5281_NOR_BOOT_BASE,
|
||||
.end = DB88F5281_NOR_BOOT_BASE + DB88F5281_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device db88f5281_boot_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &db88f5281_boot_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &db88f5281_boot_flash_resource,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* 32M NOR Flash on Device bus CS1
|
||||
****************************************************************************/
|
||||
|
||||
static struct physmap_flash_data db88f5281_nor_flash_data = {
|
||||
.width = 4, /* 32 bit bus width */
|
||||
};
|
||||
|
||||
static struct resource db88f5281_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = DB88F5281_NOR_BASE,
|
||||
.end = DB88F5281_NOR_BASE + DB88F5281_NOR_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device db88f5281_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &db88f5281_nor_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &db88f5281_nor_flash_resource,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* 32M NAND Flash on Device bus CS2
|
||||
****************************************************************************/
|
||||
|
||||
static struct mtd_partition db88f5281_nand_parts[] = {
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = 0,
|
||||
.size = SZ_2M,
|
||||
}, {
|
||||
.name = "root",
|
||||
.offset = SZ_2M,
|
||||
.size = (SZ_16M - SZ_2M),
|
||||
}, {
|
||||
.name = "user",
|
||||
.offset = SZ_16M,
|
||||
.size = SZ_8M,
|
||||
}, {
|
||||
.name = "recovery",
|
||||
.offset = (SZ_16M + SZ_8M),
|
||||
.size = SZ_8M,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource db88f5281_nand_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = DB88F5281_NAND_BASE,
|
||||
.end = DB88F5281_NAND_BASE + DB88F5281_NAND_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct orion_nand_data db88f5281_nand_data = {
|
||||
.parts = db88f5281_nand_parts,
|
||||
.nr_parts = ARRAY_SIZE(db88f5281_nand_parts),
|
||||
.cle = 0,
|
||||
.ale = 1,
|
||||
.width = 8,
|
||||
};
|
||||
|
||||
static struct platform_device db88f5281_nand_flash = {
|
||||
.name = "orion_nand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &db88f5281_nand_data,
|
||||
},
|
||||
.resource = &db88f5281_nand_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* 7-Segment on Device bus CS0
|
||||
* Dummy counter every 2 sec
|
||||
****************************************************************************/
|
||||
|
||||
static void __iomem *db88f5281_7seg;
|
||||
static struct timer_list db88f5281_timer;
|
||||
|
||||
static void db88f5281_7seg_event(unsigned long data)
|
||||
{
|
||||
static int count = 0;
|
||||
writel(0, db88f5281_7seg + (count << 4));
|
||||
count = (count + 1) & 7;
|
||||
mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
|
||||
}
|
||||
|
||||
static int __init db88f5281_7seg_init(void)
|
||||
{
|
||||
if (machine_is_db88f5281()) {
|
||||
db88f5281_7seg = ioremap(DB88F5281_7SEG_BASE,
|
||||
DB88F5281_7SEG_SIZE);
|
||||
if (!db88f5281_7seg) {
|
||||
printk(KERN_ERR "Failed to ioremap db88f5281_7seg\n");
|
||||
return -EIO;
|
||||
}
|
||||
setup_timer(&db88f5281_timer, db88f5281_7seg_event, 0);
|
||||
mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(db88f5281_7seg_init);
|
||||
|
||||
/*****************************************************************************
|
||||
* PCI
|
||||
****************************************************************************/
|
||||
|
||||
static void __init db88f5281_pci_preinit(void)
|
||||
{
|
||||
int pin;
|
||||
|
||||
/*
|
||||
* Configure PCI GPIO IRQ pins
|
||||
*/
|
||||
pin = DB88F5281_PCI_SLOT0_IRQ_PIN;
|
||||
if (gpio_request(pin, "PCI Int1") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "db88f5281_pci_preinit failed to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
gpio_free(pin);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
|
||||
}
|
||||
|
||||
pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN;
|
||||
if (gpio_request(pin, "PCI Int2") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "db88f5281_pci_preinit failed "
|
||||
"to set_irq_type pin %d\n", pin);
|
||||
gpio_free(pin);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init db88f5281_pci_map_irq(const 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.
|
||||
*/
|
||||
switch (slot - DB88F5281_PCI_SLOT0_OFFS) {
|
||||
case 0:
|
||||
return gpio_to_irq(DB88F5281_PCI_SLOT0_IRQ_PIN);
|
||||
case 1:
|
||||
case 2:
|
||||
return gpio_to_irq(DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct hw_pci db88f5281_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.preinit = db88f5281_pci_preinit,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = db88f5281_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init db88f5281_pci_init(void)
|
||||
{
|
||||
if (machine_is_db88f5281())
|
||||
pci_common_init(&db88f5281_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(db88f5281_pci_init);
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
static struct mv643xx_eth_platform_data db88f5281_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* RTC DS1339 on I2C bus
|
||||
****************************************************************************/
|
||||
static struct i2c_board_info __initdata db88f5281_i2c_rtc = {
|
||||
I2C_BOARD_INFO("ds1339", 0x68),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int db88f5281_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* USB Over Current */
|
||||
MPP1_GPIO, /* USB Vbat input */
|
||||
MPP2_PCI_ARB, /* PCI_REQn[2] */
|
||||
MPP3_PCI_ARB, /* PCI_GNTn[2] */
|
||||
MPP4_PCI_ARB, /* PCI_REQn[3] */
|
||||
MPP5_PCI_ARB, /* PCI_GNTn[3] */
|
||||
MPP6_GPIO, /* JP0, CON17.2 */
|
||||
MPP7_GPIO, /* JP1, CON17.1 */
|
||||
MPP8_GPIO, /* JP2, CON11.2 */
|
||||
MPP9_GPIO, /* JP3, CON11.3 */
|
||||
MPP10_GPIO, /* RTC int */
|
||||
MPP11_GPIO, /* Baud Rate Generator */
|
||||
MPP12_GPIO, /* PCI int 1 */
|
||||
MPP13_GPIO, /* PCI int 2 */
|
||||
MPP14_NAND, /* NAND_REn[2] */
|
||||
MPP15_NAND, /* NAND_WEn[2] */
|
||||
MPP16_UART, /* UART1_RX */
|
||||
MPP17_UART, /* UART1_TX */
|
||||
MPP18_UART, /* UART1_CTSn */
|
||||
MPP19_UART, /* UART1_RTSn */
|
||||
0,
|
||||
};
|
||||
|
||||
static void __init db88f5281_init(void)
|
||||
{
|
||||
/*
|
||||
* Basic Orion setup. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(db88f5281_mpp_modes);
|
||||
writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_eth_init(&db88f5281_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_uart0_init();
|
||||
orion5x_uart1_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
DB88F5281_NOR_BOOT_BASE,
|
||||
DB88F5281_NOR_BOOT_SIZE);
|
||||
platform_device_register(&db88f5281_boot_flash);
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(0),
|
||||
ORION_MBUS_DEVBUS_ATTR(0),
|
||||
DB88F5281_7SEG_BASE,
|
||||
DB88F5281_7SEG_SIZE);
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(1),
|
||||
ORION_MBUS_DEVBUS_ATTR(1),
|
||||
DB88F5281_NOR_BASE,
|
||||
DB88F5281_NOR_SIZE);
|
||||
platform_device_register(&db88f5281_nor_flash);
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(2),
|
||||
ORION_MBUS_DEVBUS_ATTR(2),
|
||||
DB88F5281_NAND_BASE,
|
||||
DB88F5281_NAND_SIZE);
|
||||
platform_device_register(&db88f5281_nand_flash);
|
||||
|
||||
i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
|
||||
}
|
||||
|
||||
MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
|
||||
/* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = db88f5281_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
725
arch/arm/mach-orion5x/dns323-setup.c
Normal file
725
arch/arm/mach-orion5x/dns323-setup.c
Normal file
|
@ -0,0 +1,725 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/dns323-setup.c
|
||||
*
|
||||
* Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
*
|
||||
* Support for HW Rev C1:
|
||||
*
|
||||
* Copyright (C) 2010 Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser 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/gpio.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.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/phy.h>
|
||||
#include <linux/marvell_phy.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/system_info.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include <plat/orion-gpio.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
/* Rev A1 and B1 */
|
||||
#define DNS323_GPIO_LED_RIGHT_AMBER 1
|
||||
#define DNS323_GPIO_LED_LEFT_AMBER 2
|
||||
#define DNS323_GPIO_SYSTEM_UP 3
|
||||
#define DNS323_GPIO_LED_POWER1 4
|
||||
#define DNS323_GPIO_LED_POWER2 5
|
||||
#define DNS323_GPIO_OVERTEMP 6
|
||||
#define DNS323_GPIO_RTC 7
|
||||
#define DNS323_GPIO_POWER_OFF 8
|
||||
#define DNS323_GPIO_KEY_POWER 9
|
||||
#define DNS323_GPIO_KEY_RESET 10
|
||||
|
||||
/* Rev C1 */
|
||||
#define DNS323C_GPIO_KEY_POWER 1
|
||||
#define DNS323C_GPIO_POWER_OFF 2
|
||||
#define DNS323C_GPIO_LED_RIGHT_AMBER 8
|
||||
#define DNS323C_GPIO_LED_LEFT_AMBER 9
|
||||
#define DNS323C_GPIO_LED_POWER 17
|
||||
#define DNS323C_GPIO_FAN_BIT1 18
|
||||
#define DNS323C_GPIO_FAN_BIT0 19
|
||||
|
||||
/* Exposed to userspace, do not change */
|
||||
enum {
|
||||
DNS323_REV_A1, /* 0 */
|
||||
DNS323_REV_B1, /* 1 */
|
||||
DNS323_REV_C1, /* 2 */
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PCI setup
|
||||
*/
|
||||
|
||||
static int __init dns323_pci_map_irq(const 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;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct hw_pci dns323_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = dns323_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init dns323_pci_init(void)
|
||||
{
|
||||
/* Rev B1 and C1 doesn't really use its PCI bus, and initialising PCI
|
||||
* gets in the way of initialising the SATA controller.
|
||||
*/
|
||||
if (machine_is_dns323() && system_rev == DNS323_REV_A1)
|
||||
pci_common_init(&dns323_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(dns323_pci_init);
|
||||
|
||||
/****************************************************************************
|
||||
* 8MiB NOR flash (Spansion S29GL064M90TFIR4)
|
||||
*
|
||||
* Layout as used by D-Link:
|
||||
* 0x00000000-0x00010000 : "MTD1"
|
||||
* 0x00010000-0x00020000 : "MTD2"
|
||||
* 0x00020000-0x001a0000 : "Linux Kernel"
|
||||
* 0x001a0000-0x007d0000 : "File System"
|
||||
* 0x007d0000-0x00800000 : "u-boot"
|
||||
*/
|
||||
|
||||
#define DNS323_NOR_BOOT_BASE 0xf4000000
|
||||
#define DNS323_NOR_BOOT_SIZE SZ_8M
|
||||
|
||||
static struct mtd_partition dns323_partitions[] = {
|
||||
{
|
||||
.name = "MTD1",
|
||||
.size = 0x00010000,
|
||||
.offset = 0,
|
||||
}, {
|
||||
.name = "MTD2",
|
||||
.size = 0x00010000,
|
||||
.offset = 0x00010000,
|
||||
}, {
|
||||
.name = "Linux Kernel",
|
||||
.size = 0x00180000,
|
||||
.offset = 0x00020000,
|
||||
}, {
|
||||
.name = "File System",
|
||||
.size = 0x00630000,
|
||||
.offset = 0x001A0000,
|
||||
}, {
|
||||
.name = "u-boot",
|
||||
.size = 0x00030000,
|
||||
.offset = 0x007d0000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data dns323_nor_flash_data = {
|
||||
.width = 1,
|
||||
.parts = dns323_partitions,
|
||||
.nr_parts = ARRAY_SIZE(dns323_partitions)
|
||||
};
|
||||
|
||||
static struct resource dns323_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = DNS323_NOR_BOOT_BASE,
|
||||
.end = DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device dns323_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &dns323_nor_flash_data,
|
||||
},
|
||||
.resource = &dns323_nor_flash_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Ethernet
|
||||
*/
|
||||
|
||||
static struct mv643xx_eth_platform_data dns323_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these
|
||||
* functions be kept somewhere?
|
||||
*/
|
||||
static int __init dns323_parse_hex_nibble(char n)
|
||||
{
|
||||
if (n >= '0' && n <= '9')
|
||||
return n - '0';
|
||||
|
||||
if (n >= 'A' && n <= 'F')
|
||||
return n - 'A' + 10;
|
||||
|
||||
if (n >= 'a' && n <= 'f')
|
||||
return n - 'a' + 10;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __init dns323_parse_hex_byte(const char *b)
|
||||
{
|
||||
int hi;
|
||||
int lo;
|
||||
|
||||
hi = dns323_parse_hex_nibble(b[0]);
|
||||
lo = dns323_parse_hex_nibble(b[1]);
|
||||
|
||||
if (hi < 0 || lo < 0)
|
||||
return -1;
|
||||
|
||||
return (hi << 4) | lo;
|
||||
}
|
||||
|
||||
static int __init dns323_read_mac_addr(void)
|
||||
{
|
||||
u_int8_t addr[6];
|
||||
int i;
|
||||
char *mac_page;
|
||||
|
||||
/* MAC address is stored as a regular ol' string in /dev/mtdblock4
|
||||
* (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80).
|
||||
*/
|
||||
mac_page = ioremap(DNS323_NOR_BOOT_BASE + 0x7d0000 + 196480, 1024);
|
||||
if (!mac_page)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Sanity check the string we're looking at */
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (*(mac_page + (i * 3) + 2) != ':') {
|
||||
goto error_fail;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
int byte;
|
||||
|
||||
byte = dns323_parse_hex_byte(mac_page + (i * 3));
|
||||
if (byte < 0) {
|
||||
goto error_fail;
|
||||
}
|
||||
|
||||
addr[i] = byte;
|
||||
}
|
||||
|
||||
iounmap(mac_page);
|
||||
printk("DNS-323: Found ethernet MAC address: ");
|
||||
for (i = 0; i < 6; i++)
|
||||
printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
|
||||
|
||||
memcpy(dns323_eth_data.mac_addr, addr, 6);
|
||||
|
||||
return 0;
|
||||
|
||||
error_fail:
|
||||
iounmap(mac_page);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO LEDs (simple - doesn't use hardware blinking support)
|
||||
*/
|
||||
|
||||
static struct gpio_led dns323ab_leds[] = {
|
||||
{
|
||||
.name = "power:blue",
|
||||
.gpio = DNS323_GPIO_LED_POWER2,
|
||||
.default_trigger = "default-on",
|
||||
}, {
|
||||
.name = "right:amber",
|
||||
.gpio = DNS323_GPIO_LED_RIGHT_AMBER,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "left:amber",
|
||||
.gpio = DNS323_GPIO_LED_LEFT_AMBER,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct gpio_led dns323c_leds[] = {
|
||||
{
|
||||
.name = "power:blue",
|
||||
.gpio = DNS323C_GPIO_LED_POWER,
|
||||
.default_trigger = "timer",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "right:amber",
|
||||
.gpio = DNS323C_GPIO_LED_RIGHT_AMBER,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "left:amber",
|
||||
.gpio = DNS323C_GPIO_LED_LEFT_AMBER,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct gpio_led_platform_data dns323ab_led_data = {
|
||||
.num_leds = ARRAY_SIZE(dns323ab_leds),
|
||||
.leds = dns323ab_leds,
|
||||
.gpio_blink_set = orion_gpio_led_blink_set,
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data dns323c_led_data = {
|
||||
.num_leds = ARRAY_SIZE(dns323c_leds),
|
||||
.leds = dns323c_leds,
|
||||
.gpio_blink_set = orion_gpio_led_blink_set,
|
||||
};
|
||||
|
||||
static struct platform_device dns323_gpio_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &dns323ab_led_data,
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO Attached Keys
|
||||
*/
|
||||
|
||||
static struct gpio_keys_button dns323ab_buttons[] = {
|
||||
{
|
||||
.code = KEY_RESTART,
|
||||
.gpio = DNS323_GPIO_KEY_RESET,
|
||||
.desc = "Reset Button",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.code = KEY_POWER,
|
||||
.gpio = DNS323_GPIO_KEY_POWER,
|
||||
.desc = "Power Button",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data dns323ab_button_data = {
|
||||
.buttons = dns323ab_buttons,
|
||||
.nbuttons = ARRAY_SIZE(dns323ab_buttons),
|
||||
};
|
||||
|
||||
static struct gpio_keys_button dns323c_buttons[] = {
|
||||
{
|
||||
.code = KEY_POWER,
|
||||
.gpio = DNS323C_GPIO_KEY_POWER,
|
||||
.desc = "Power Button",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data dns323c_button_data = {
|
||||
.buttons = dns323c_buttons,
|
||||
.nbuttons = ARRAY_SIZE(dns323c_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device dns323_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &dns323ab_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
*/
|
||||
static struct mv_sata_platform_data dns323_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* General Setup
|
||||
*/
|
||||
static unsigned int dns323a_mpp_modes[] __initdata = {
|
||||
MPP0_PCIE_RST_OUTn,
|
||||
MPP1_GPIO, /* right amber LED (sata ch0) */
|
||||
MPP2_GPIO, /* left amber LED (sata ch1) */
|
||||
MPP3_UNUSED,
|
||||
MPP4_GPIO, /* power button LED */
|
||||
MPP5_GPIO, /* power button LED */
|
||||
MPP6_GPIO, /* GMT G751-2f overtemp */
|
||||
MPP7_GPIO, /* M41T80 nIRQ/OUT/SQW */
|
||||
MPP8_GPIO, /* triggers power off */
|
||||
MPP9_GPIO, /* power button switch */
|
||||
MPP10_GPIO, /* reset button switch */
|
||||
MPP11_UNUSED,
|
||||
MPP12_UNUSED,
|
||||
MPP13_UNUSED,
|
||||
MPP14_UNUSED,
|
||||
MPP15_UNUSED,
|
||||
MPP16_UNUSED,
|
||||
MPP17_UNUSED,
|
||||
MPP18_UNUSED,
|
||||
MPP19_UNUSED,
|
||||
0,
|
||||
};
|
||||
|
||||
static unsigned int dns323b_mpp_modes[] __initdata = {
|
||||
MPP0_UNUSED,
|
||||
MPP1_GPIO, /* right amber LED (sata ch0) */
|
||||
MPP2_GPIO, /* left amber LED (sata ch1) */
|
||||
MPP3_GPIO, /* system up flag */
|
||||
MPP4_GPIO, /* power button LED */
|
||||
MPP5_GPIO, /* power button LED */
|
||||
MPP6_GPIO, /* GMT G751-2f overtemp */
|
||||
MPP7_GPIO, /* M41T80 nIRQ/OUT/SQW */
|
||||
MPP8_GPIO, /* triggers power off */
|
||||
MPP9_GPIO, /* power button switch */
|
||||
MPP10_GPIO, /* reset button switch */
|
||||
MPP11_UNUSED,
|
||||
MPP12_SATA_LED,
|
||||
MPP13_SATA_LED,
|
||||
MPP14_SATA_LED,
|
||||
MPP15_SATA_LED,
|
||||
MPP16_UNUSED,
|
||||
MPP17_UNUSED,
|
||||
MPP18_UNUSED,
|
||||
MPP19_UNUSED,
|
||||
0,
|
||||
};
|
||||
|
||||
static unsigned int dns323c_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* ? input */
|
||||
MPP1_GPIO, /* input power switch (0 = pressed) */
|
||||
MPP2_GPIO, /* output power off */
|
||||
MPP3_UNUSED, /* ? output */
|
||||
MPP4_UNUSED, /* ? output */
|
||||
MPP5_UNUSED, /* ? output */
|
||||
MPP6_UNUSED, /* ? output */
|
||||
MPP7_UNUSED, /* ? output */
|
||||
MPP8_GPIO, /* i/o right amber LED */
|
||||
MPP9_GPIO, /* i/o left amber LED */
|
||||
MPP10_GPIO, /* input */
|
||||
MPP11_UNUSED,
|
||||
MPP12_SATA_LED,
|
||||
MPP13_SATA_LED,
|
||||
MPP14_SATA_LED,
|
||||
MPP15_SATA_LED,
|
||||
MPP16_UNUSED,
|
||||
MPP17_GPIO, /* power button LED */
|
||||
MPP18_GPIO, /* fan speed bit 0 */
|
||||
MPP19_GPIO, /* fan speed bit 1 */
|
||||
0,
|
||||
};
|
||||
|
||||
/* Rev C1 Fan speed notes:
|
||||
*
|
||||
* The fan is controlled by 2 GPIOs on this board. The settings
|
||||
* of the bits is as follow:
|
||||
*
|
||||
* GPIO 18 GPIO 19 Fan
|
||||
*
|
||||
* 0 0 stopped
|
||||
* 0 1 low speed
|
||||
* 1 0 high speed
|
||||
* 1 1 don't do that (*)
|
||||
*
|
||||
* (*) I think the two bits control two feed-in resistors into a fixed
|
||||
* PWN circuit, setting both bits will basically go a 'bit' faster
|
||||
* than high speed, but d-link doesn't do it and you may get out of
|
||||
* HW spec so don't do it.
|
||||
*/
|
||||
|
||||
/*
|
||||
* On the DNS-323 A1 and B1 the following devices are attached via I2C:
|
||||
*
|
||||
* i2c addr | chip | description
|
||||
* 0x3e | GMT G760Af | fan speed PWM controller
|
||||
* 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible)
|
||||
* 0x68 | ST M41T80 | RTC w/ alarm
|
||||
*/
|
||||
static struct i2c_board_info __initdata dns323ab_i2c_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("g760a", 0x3e),
|
||||
}, {
|
||||
I2C_BOARD_INFO("lm75", 0x48),
|
||||
}, {
|
||||
I2C_BOARD_INFO("m41t80", 0x68),
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* On the DNS-323 C1 the following devices are attached via I2C:
|
||||
*
|
||||
* i2c addr | chip | description
|
||||
* 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible)
|
||||
* 0x68 | ST M41T80 | RTC w/ alarm
|
||||
*/
|
||||
static struct i2c_board_info __initdata dns323c_i2c_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("lm75", 0x48),
|
||||
}, {
|
||||
I2C_BOARD_INFO("m41t80", 0x68),
|
||||
},
|
||||
};
|
||||
|
||||
/* DNS-323 rev. A specific power off method */
|
||||
static void dns323a_power_off(void)
|
||||
{
|
||||
pr_info("DNS-323: Triggering power-off...\n");
|
||||
gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
|
||||
}
|
||||
|
||||
/* DNS-323 rev B specific power off method */
|
||||
static void dns323b_power_off(void)
|
||||
{
|
||||
pr_info("DNS-323: Triggering power-off...\n");
|
||||
/* Pin has to be changed to 1 and back to 0 to do actual power off. */
|
||||
gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
|
||||
mdelay(100);
|
||||
gpio_set_value(DNS323_GPIO_POWER_OFF, 0);
|
||||
}
|
||||
|
||||
/* DNS-323 rev. C specific power off method */
|
||||
static void dns323c_power_off(void)
|
||||
{
|
||||
pr_info("DNS-323: Triggering power-off...\n");
|
||||
gpio_set_value(DNS323C_GPIO_POWER_OFF, 1);
|
||||
}
|
||||
|
||||
static int dns323c_phy_fixup(struct phy_device *phy)
|
||||
{
|
||||
phy->dev_flags |= MARVELL_PHY_M1118_DNS323_LEDS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init dns323_identify_rev(void)
|
||||
{
|
||||
u32 dev, rev, i, reg;
|
||||
|
||||
pr_debug("DNS-323: Identifying board ... \n");
|
||||
|
||||
/* Rev A1 has a 5181 */
|
||||
orion5x_pcie_id(&dev, &rev);
|
||||
if (dev == MV88F5181_DEV_ID) {
|
||||
pr_debug("DNS-323: 5181 found, board is A1\n");
|
||||
return DNS323_REV_A1;
|
||||
}
|
||||
pr_debug("DNS-323: 5182 found, board is B1 or C1, checking PHY...\n");
|
||||
|
||||
/* Rev B1 and C1 both have 5182, let's poke at the eth PHY. This is
|
||||
* a bit gross but we want to do that without links into the eth
|
||||
* driver so let's poke at it directly. We default to rev B1 in
|
||||
* case the accesses fail
|
||||
*/
|
||||
|
||||
#define ETH_SMI_REG (ORION5X_ETH_VIRT_BASE + 0x2000 + 0x004)
|
||||
#define SMI_BUSY 0x10000000
|
||||
#define SMI_READ_VALID 0x08000000
|
||||
#define SMI_OPCODE_READ 0x04000000
|
||||
#define SMI_OPCODE_WRITE 0x00000000
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
reg = readl(ETH_SMI_REG);
|
||||
if (!(reg & SMI_BUSY))
|
||||
break;
|
||||
}
|
||||
if (i >= 1000) {
|
||||
pr_warn("DNS-323: Timeout accessing PHY, assuming rev B1\n");
|
||||
return DNS323_REV_B1;
|
||||
}
|
||||
writel((3 << 21) /* phy ID reg */ |
|
||||
(8 << 16) /* phy addr */ |
|
||||
SMI_OPCODE_READ, ETH_SMI_REG);
|
||||
for (i = 0; i < 1000; i++) {
|
||||
reg = readl(ETH_SMI_REG);
|
||||
if (reg & SMI_READ_VALID)
|
||||
break;
|
||||
}
|
||||
if (i >= 1000) {
|
||||
pr_warn("DNS-323: Timeout reading PHY, assuming rev B1\n");
|
||||
return DNS323_REV_B1;
|
||||
}
|
||||
pr_debug("DNS-323: Ethernet PHY ID 0x%x\n", reg & 0xffff);
|
||||
|
||||
/* Note: the Marvell tools mask the ID with 0x3f0 before comparison
|
||||
* but I don't see that making a difference here, at least with
|
||||
* any known Marvell PHY ID
|
||||
*/
|
||||
switch(reg & 0xfff0) {
|
||||
case 0x0cc0: /* MV88E1111 */
|
||||
return DNS323_REV_B1;
|
||||
case 0x0e10: /* MV88E1118 */
|
||||
return DNS323_REV_C1;
|
||||
default:
|
||||
pr_warn("DNS-323: Unknown PHY ID 0x%04x, assuming rev B1\n",
|
||||
reg & 0xffff);
|
||||
}
|
||||
return DNS323_REV_B1;
|
||||
}
|
||||
|
||||
static void __init dns323_init(void)
|
||||
{
|
||||
/* Setup basic Orion functions. Need to be called early. */
|
||||
orion5x_init();
|
||||
|
||||
/* Identify revision */
|
||||
system_rev = dns323_identify_rev();
|
||||
pr_info("DNS-323: Identified HW revision %c1\n", 'A' + system_rev);
|
||||
|
||||
/* Just to be tricky, the 5182 has a completely different
|
||||
* set of MPP modes to the 5181.
|
||||
*/
|
||||
switch(system_rev) {
|
||||
case DNS323_REV_A1:
|
||||
orion5x_mpp_conf(dns323a_mpp_modes);
|
||||
writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */
|
||||
break;
|
||||
case DNS323_REV_B1:
|
||||
orion5x_mpp_conf(dns323b_mpp_modes);
|
||||
break;
|
||||
case DNS323_REV_C1:
|
||||
orion5x_mpp_conf(dns323c_mpp_modes);
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup flash mapping
|
||||
* CS3 holds a 8 MB Spansion S29GL064M90TFIR4
|
||||
*/
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
DNS323_NOR_BOOT_BASE,
|
||||
DNS323_NOR_BOOT_SIZE);
|
||||
platform_device_register(&dns323_nor_flash);
|
||||
|
||||
/* Sort out LEDs, Buttons and i2c devices */
|
||||
switch(system_rev) {
|
||||
case DNS323_REV_A1:
|
||||
/* The 5181 power LED is active low and requires
|
||||
* DNS323_GPIO_LED_POWER1 to also be low.
|
||||
*/
|
||||
dns323ab_leds[0].active_low = 1;
|
||||
gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
|
||||
gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
|
||||
/* Fall through */
|
||||
case DNS323_REV_B1:
|
||||
i2c_register_board_info(0, dns323ab_i2c_devices,
|
||||
ARRAY_SIZE(dns323ab_i2c_devices));
|
||||
break;
|
||||
case DNS323_REV_C1:
|
||||
/* Hookup LEDs & Buttons */
|
||||
dns323_gpio_leds.dev.platform_data = &dns323c_led_data;
|
||||
dns323_button_device.dev.platform_data = &dns323c_button_data;
|
||||
|
||||
/* Hookup i2c devices and fan driver */
|
||||
i2c_register_board_info(0, dns323c_i2c_devices,
|
||||
ARRAY_SIZE(dns323c_i2c_devices));
|
||||
platform_device_register_simple("dns323c-fan", 0, NULL, 0);
|
||||
|
||||
/* Register fixup for the PHY LEDs */
|
||||
if (!IS_BUILTIN(CONFIG_PHYLIB))
|
||||
break;
|
||||
phy_register_fixup_for_uid(MARVELL_PHY_ID_88E1118,
|
||||
MARVELL_PHY_ID_MASK,
|
||||
dns323c_phy_fixup);
|
||||
}
|
||||
|
||||
platform_device_register(&dns323_gpio_leds);
|
||||
platform_device_register(&dns323_button_device);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
if (dns323_read_mac_addr() < 0)
|
||||
printk("DNS-323: Failed to read MAC address\n");
|
||||
orion5x_ehci0_init();
|
||||
orion5x_eth_init(&dns323_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_uart0_init();
|
||||
|
||||
/* Remaining GPIOs */
|
||||
switch(system_rev) {
|
||||
case DNS323_REV_A1:
|
||||
/* Poweroff GPIO */
|
||||
if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
|
||||
gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
|
||||
pr_err("DNS-323: failed to setup power-off GPIO\n");
|
||||
pm_power_off = dns323a_power_off;
|
||||
break;
|
||||
case DNS323_REV_B1:
|
||||
/* 5182 built-in SATA init */
|
||||
orion5x_sata_init(&dns323_sata_data);
|
||||
|
||||
/* The DNS323 rev B1 has flag to indicate the system is up.
|
||||
* Without this flag set, power LED will flash and cannot be
|
||||
* controlled via leds-gpio.
|
||||
*/
|
||||
if (gpio_request(DNS323_GPIO_SYSTEM_UP, "SYS_READY") == 0)
|
||||
gpio_direction_output(DNS323_GPIO_SYSTEM_UP, 1);
|
||||
|
||||
/* Poweroff GPIO */
|
||||
if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
|
||||
gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
|
||||
pr_err("DNS-323: failed to setup power-off GPIO\n");
|
||||
pm_power_off = dns323b_power_off;
|
||||
break;
|
||||
case DNS323_REV_C1:
|
||||
/* 5182 built-in SATA init */
|
||||
orion5x_sata_init(&dns323_sata_data);
|
||||
|
||||
/* Poweroff GPIO */
|
||||
if (gpio_request(DNS323C_GPIO_POWER_OFF, "POWEROFF") != 0 ||
|
||||
gpio_direction_output(DNS323C_GPIO_POWER_OFF, 0) != 0)
|
||||
pr_err("DNS-323: failed to setup power-off GPIO\n");
|
||||
pm_power_off = dns323c_power_off;
|
||||
|
||||
/* Now, -this- should theorically be done by the sata_mv driver
|
||||
* once I figure out what's going on there. Maybe the behaviour
|
||||
* of the LEDs should be somewhat passed via the platform_data.
|
||||
* for now, just whack the register and make the LEDs happy
|
||||
*
|
||||
* Note: AFAIK, rev B1 needs the same treatement but I'll let
|
||||
* somebody else test it.
|
||||
*/
|
||||
writel(0x5, ORION5X_SATA_VIRT_BASE + 0x2c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
|
||||
MACHINE_START(DNS323, "D-Link DNS-323")
|
||||
/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = dns323_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
37
arch/arm/mach-orion5x/include/mach/bridge-regs.h
Normal file
37
arch/arm/mach-orion5x/include/mach/bridge-regs.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/include/mach/bridge-regs.h
|
||||
*
|
||||
* Orion CPU Bridge Registers
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_BRIDGE_REGS_H
|
||||
#define __ASM_ARCH_BRIDGE_REGS_H
|
||||
|
||||
#include <mach/orion5x.h>
|
||||
|
||||
#define CPU_CONF (ORION5X_BRIDGE_VIRT_BASE + 0x100)
|
||||
|
||||
#define CPU_CTRL (ORION5X_BRIDGE_VIRT_BASE + 0x104)
|
||||
|
||||
#define RSTOUTn_MASK (ORION5X_BRIDGE_VIRT_BASE + 0x108)
|
||||
#define RSTOUTn_MASK_PHYS (ORION5X_BRIDGE_PHYS_BASE + 0x108)
|
||||
|
||||
#define CPU_SOFT_RESET (ORION5X_BRIDGE_VIRT_BASE + 0x10c)
|
||||
|
||||
#define BRIDGE_CAUSE (ORION5X_BRIDGE_VIRT_BASE + 0x110)
|
||||
|
||||
#define POWER_MNG_CTRL_REG (ORION5X_BRIDGE_VIRT_BASE + 0x11C)
|
||||
|
||||
#define BRIDGE_INT_TIMER1_CLR (~0x0004)
|
||||
|
||||
#define MAIN_IRQ_CAUSE (ORION5X_BRIDGE_VIRT_BASE + 0x200)
|
||||
|
||||
#define MAIN_IRQ_MASK (ORION5X_BRIDGE_VIRT_BASE + 0x204)
|
||||
|
||||
#define TIMER_VIRT_BASE (ORION5X_BRIDGE_VIRT_BASE + 0x300)
|
||||
#define TIMER_PHYS_BASE (ORION5X_BRIDGE_PHYS_BASE + 0x300)
|
||||
#endif
|
25
arch/arm/mach-orion5x/include/mach/entry-macro.S
Normal file
25
arch/arm/mach-orion5x/include/mach/entry-macro.S
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/include/mach/entry-macro.S
|
||||
*
|
||||
* Low-level IRQ helper macros for Orion platforms
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <mach/bridge-regs.h>
|
||||
|
||||
.macro get_irqnr_preamble, base, tmp
|
||||
ldr \base, =MAIN_IRQ_CAUSE
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
|
||||
ldr \irqstat, [\base, #0] @ main cause
|
||||
ldr \tmp, [\base, #(MAIN_IRQ_MASK - MAIN_IRQ_CAUSE)] @ main mask
|
||||
mov \irqnr, #0 @ default irqnr
|
||||
@ find cause bits that are unmasked
|
||||
ands \irqstat, \irqstat, \tmp @ clear Z flag if any
|
||||
clzne \irqnr, \irqstat @ calc irqnr
|
||||
rsbne \irqnr, \irqnr, #31
|
||||
.endm
|
14
arch/arm/mach-orion5x/include/mach/hardware.h
Normal file
14
arch/arm/mach-orion5x/include/mach/hardware.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/include/mach/hardware.h
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_HARDWARE_H
|
||||
#define __ASM_ARCH_HARDWARE_H
|
||||
|
||||
#include "orion5x.h"
|
||||
|
||||
#endif
|
60
arch/arm/mach-orion5x/include/mach/irqs.h
Normal file
60
arch/arm/mach-orion5x/include/mach/irqs.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/include/mach/irqs.h
|
||||
*
|
||||
* IRQ definitions for Orion SoC
|
||||
*
|
||||
* Maintainer: Tzachi Perelstein <tzachi@marvell.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_IRQS_H
|
||||
#define __ASM_ARCH_IRQS_H
|
||||
|
||||
/*
|
||||
* Orion Main Interrupt Controller
|
||||
*/
|
||||
#define IRQ_ORION5X_BRIDGE 0
|
||||
#define IRQ_ORION5X_DOORBELL_H2C 1
|
||||
#define IRQ_ORION5X_DOORBELL_C2H 2
|
||||
#define IRQ_ORION5X_UART0 3
|
||||
#define IRQ_ORION5X_UART1 4
|
||||
#define IRQ_ORION5X_I2C 5
|
||||
#define IRQ_ORION5X_GPIO_0_7 6
|
||||
#define IRQ_ORION5X_GPIO_8_15 7
|
||||
#define IRQ_ORION5X_GPIO_16_23 8
|
||||
#define IRQ_ORION5X_GPIO_24_31 9
|
||||
#define IRQ_ORION5X_PCIE0_ERR 10
|
||||
#define IRQ_ORION5X_PCIE0_INT 11
|
||||
#define IRQ_ORION5X_USB1_CTRL 12
|
||||
#define IRQ_ORION5X_DEV_BUS_ERR 14
|
||||
#define IRQ_ORION5X_PCI_ERR 15
|
||||
#define IRQ_ORION5X_USB_BR_ERR 16
|
||||
#define IRQ_ORION5X_USB0_CTRL 17
|
||||
#define IRQ_ORION5X_ETH_RX 18
|
||||
#define IRQ_ORION5X_ETH_TX 19
|
||||
#define IRQ_ORION5X_ETH_MISC 20
|
||||
#define IRQ_ORION5X_ETH_SUM 21
|
||||
#define IRQ_ORION5X_ETH_ERR 22
|
||||
#define IRQ_ORION5X_IDMA_ERR 23
|
||||
#define IRQ_ORION5X_IDMA_0 24
|
||||
#define IRQ_ORION5X_IDMA_1 25
|
||||
#define IRQ_ORION5X_IDMA_2 26
|
||||
#define IRQ_ORION5X_IDMA_3 27
|
||||
#define IRQ_ORION5X_CESA 28
|
||||
#define IRQ_ORION5X_SATA 29
|
||||
#define IRQ_ORION5X_XOR0 30
|
||||
#define IRQ_ORION5X_XOR1 31
|
||||
|
||||
/*
|
||||
* Orion General Purpose Pins
|
||||
*/
|
||||
#define IRQ_ORION5X_GPIO_START 32
|
||||
#define NR_GPIO_IRQS 32
|
||||
|
||||
#define NR_IRQS (IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
|
||||
|
||||
|
||||
#endif
|
146
arch/arm/mach-orion5x/include/mach/orion5x.h
Normal file
146
arch/arm/mach-orion5x/include/mach/orion5x.h
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/include/mach/orion5x.h
|
||||
*
|
||||
* Generic definitions of Orion SoC flavors:
|
||||
* Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90.
|
||||
*
|
||||
* Maintainer: Tzachi Perelstein <tzachi@marvell.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_ORION5X_H
|
||||
#define __ASM_ARCH_ORION5X_H
|
||||
|
||||
/*****************************************************************************
|
||||
* Orion Address Maps
|
||||
*
|
||||
* phys
|
||||
* e0000000 PCIe MEM space
|
||||
* e8000000 PCI MEM space
|
||||
* f0000000 PCIe WA space (Orion-1/Orion-NAS only)
|
||||
* f1000000 on-chip peripheral registers
|
||||
* f2000000 PCIe I/O space
|
||||
* f2100000 PCI I/O space
|
||||
* f2200000 SRAM dedicated for the crypto unit
|
||||
* f4000000 device bus mappings (boot)
|
||||
* fa000000 device bus mappings (cs0)
|
||||
* fa800000 device bus mappings (cs2)
|
||||
* fc000000 device bus mappings (cs0/cs1)
|
||||
*
|
||||
* virt phys size
|
||||
* fe000000 f1000000 1M on-chip peripheral registers
|
||||
* fee00000 f2000000 64K PCIe I/O space
|
||||
* fee10000 f2100000 64K PCI I/O space
|
||||
* fd000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only)
|
||||
****************************************************************************/
|
||||
#define ORION5X_REGS_PHYS_BASE 0xf1000000
|
||||
#define ORION5X_REGS_VIRT_BASE IOMEM(0xfe000000)
|
||||
#define ORION5X_REGS_SIZE SZ_1M
|
||||
|
||||
#define ORION5X_PCIE_IO_PHYS_BASE 0xf2000000
|
||||
#define ORION5X_PCIE_IO_BUS_BASE 0x00000000
|
||||
#define ORION5X_PCIE_IO_SIZE SZ_64K
|
||||
|
||||
#define ORION5X_PCI_IO_PHYS_BASE 0xf2100000
|
||||
#define ORION5X_PCI_IO_BUS_BASE 0x00010000
|
||||
#define ORION5X_PCI_IO_SIZE SZ_64K
|
||||
|
||||
#define ORION5X_SRAM_PHYS_BASE (0xf2200000)
|
||||
#define ORION5X_SRAM_SIZE SZ_8K
|
||||
|
||||
/* Relevant only for Orion-1/Orion-NAS */
|
||||
#define ORION5X_PCIE_WA_PHYS_BASE 0xf0000000
|
||||
#define ORION5X_PCIE_WA_VIRT_BASE IOMEM(0xfd000000)
|
||||
#define ORION5X_PCIE_WA_SIZE SZ_16M
|
||||
|
||||
#define ORION5X_PCIE_MEM_PHYS_BASE 0xe0000000
|
||||
#define ORION5X_PCIE_MEM_SIZE SZ_128M
|
||||
|
||||
#define ORION5X_PCI_MEM_PHYS_BASE 0xe8000000
|
||||
#define ORION5X_PCI_MEM_SIZE SZ_128M
|
||||
|
||||
/*******************************************************************************
|
||||
* Orion Registers Map
|
||||
******************************************************************************/
|
||||
|
||||
#define ORION5X_DDR_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x00000)
|
||||
#define ORION5X_DDR_WINS_BASE (ORION5X_DDR_PHYS_BASE + 0x1500)
|
||||
#define ORION5X_DDR_WINS_SZ (0x10)
|
||||
#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x00000)
|
||||
#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 GPIO_VIRT_BASE ORION5X_DEV_BUS_REG(0x0100)
|
||||
#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)
|
||||
#define UART1_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE + 0x2100)
|
||||
#define UART1_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE + 0x2100)
|
||||
|
||||
#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x20000)
|
||||
#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x20000)
|
||||
#define ORION5X_BRIDGE_WINS_BASE (ORION5X_BRIDGE_PHYS_BASE)
|
||||
#define ORION5X_BRIDGE_WINS_SZ (0x80)
|
||||
|
||||
#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x30000)
|
||||
|
||||
#define ORION5X_PCIE_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x40000)
|
||||
|
||||
#define ORION5X_USB0_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x50000)
|
||||
#define ORION5X_USB0_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x50000)
|
||||
|
||||
#define ORION5X_XOR_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x60900)
|
||||
#define ORION5X_XOR_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x60900)
|
||||
|
||||
#define ORION5X_ETH_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x70000)
|
||||
#define ORION5X_ETH_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x70000)
|
||||
|
||||
#define ORION5X_SATA_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x80000)
|
||||
#define ORION5X_SATA_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x80000)
|
||||
|
||||
#define ORION5X_CRYPTO_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x90000)
|
||||
|
||||
#define ORION5X_USB1_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0xa0000)
|
||||
#define ORION5X_USB1_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0xa0000)
|
||||
|
||||
/*******************************************************************************
|
||||
* Device Bus Registers
|
||||
******************************************************************************/
|
||||
#define MPP_0_7_CTRL ORION5X_DEV_BUS_REG(0x000)
|
||||
#define MPP_8_15_CTRL ORION5X_DEV_BUS_REG(0x004)
|
||||
#define MPP_16_19_CTRL ORION5X_DEV_BUS_REG(0x050)
|
||||
#define MPP_DEV_CTRL ORION5X_DEV_BUS_REG(0x008)
|
||||
#define MPP_RESET_SAMPLE ORION5X_DEV_BUS_REG(0x010)
|
||||
#define DEV_BANK_0_PARAM ORION5X_DEV_BUS_REG(0x45c)
|
||||
#define DEV_BANK_1_PARAM ORION5X_DEV_BUS_REG(0x460)
|
||||
#define DEV_BANK_2_PARAM ORION5X_DEV_BUS_REG(0x464)
|
||||
#define DEV_BANK_BOOT_PARAM ORION5X_DEV_BUS_REG(0x46c)
|
||||
#define DEV_BUS_CTRL ORION5X_DEV_BUS_REG(0x4c0)
|
||||
#define DEV_BUS_INT_CAUSE ORION5X_DEV_BUS_REG(0x4d0)
|
||||
#define DEV_BUS_INT_MASK ORION5X_DEV_BUS_REG(0x4d4)
|
||||
|
||||
/*******************************************************************************
|
||||
* Supported Devices & Revisions
|
||||
******************************************************************************/
|
||||
/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */
|
||||
#define MV88F5181_DEV_ID 0x5181
|
||||
#define MV88F5181_REV_B1 3
|
||||
#define MV88F5181L_REV_A0 8
|
||||
#define MV88F5181L_REV_A1 9
|
||||
/* Orion-NAS (88F5182) */
|
||||
#define MV88F5182_DEV_ID 0x5182
|
||||
#define MV88F5182_REV_A2 2
|
||||
/* Orion-2 (88F5281) */
|
||||
#define MV88F5281_DEV_ID 0x5281
|
||||
#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
|
||||
|
||||
#endif
|
48
arch/arm/mach-orion5x/include/mach/uncompress.h
Normal file
48
arch/arm/mach-orion5x/include/mach/uncompress.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/include/mach/uncompress.h
|
||||
*
|
||||
* Tzachi Perelstein <tzachi@marvell.com>
|
||||
*
|
||||
* 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/serial_reg.h>
|
||||
#include <mach/orion5x.h>
|
||||
|
||||
#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE)
|
||||
|
||||
static void putc(const char c)
|
||||
{
|
||||
unsigned char *base = SERIAL_BASE;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 0x1000; i++) {
|
||||
if (base[UART_LSR << 2] & UART_LSR_THRE)
|
||||
break;
|
||||
barrier();
|
||||
}
|
||||
|
||||
base[UART_TX << 2] = c;
|
||||
}
|
||||
|
||||
static void flush(void)
|
||||
{
|
||||
unsigned char *base = SERIAL_BASE;
|
||||
unsigned char mask;
|
||||
int i;
|
||||
|
||||
mask = UART_LSR_TEMT | UART_LSR_THRE;
|
||||
|
||||
for (i = 0; i < 0x1000; i++) {
|
||||
if ((base[UART_LSR << 2] & mask) == mask)
|
||||
break;
|
||||
barrier();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* nothing to do
|
||||
*/
|
||||
#define arch_decomp_setup()
|
65
arch/arm/mach-orion5x/irq.c
Normal file
65
arch/arm/mach-orion5x/irq.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/irq.c
|
||||
*
|
||||
* Core IRQ functions for Marvell Orion System On Chip
|
||||
*
|
||||
* Maintainer: Tzachi Perelstein <tzachi@marvell.com>
|
||||
*
|
||||
* 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/gpio.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach/bridge-regs.h>
|
||||
#include <plat/orion-gpio.h>
|
||||
#include <plat/irq.h>
|
||||
#include <asm/exception.h>
|
||||
#include "common.h"
|
||||
|
||||
static int __initdata gpio0_irqs[4] = {
|
||||
IRQ_ORION5X_GPIO_0_7,
|
||||
IRQ_ORION5X_GPIO_8_15,
|
||||
IRQ_ORION5X_GPIO_16_23,
|
||||
IRQ_ORION5X_GPIO_24_31,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MULTI_IRQ_HANDLER
|
||||
/*
|
||||
* Compiling with both non-DT and DT support enabled, will
|
||||
* break asm irq handler used by non-DT boards. Therefore,
|
||||
* we provide a C-style irq handler even for non-DT boards,
|
||||
* if MULTI_IRQ_HANDLER is set.
|
||||
*/
|
||||
|
||||
asmlinkage void
|
||||
__exception_irq_entry orion5x_legacy_handle_irq(struct pt_regs *regs)
|
||||
{
|
||||
u32 stat;
|
||||
|
||||
stat = readl_relaxed(MAIN_IRQ_CAUSE);
|
||||
stat &= readl_relaxed(MAIN_IRQ_MASK);
|
||||
if (stat) {
|
||||
unsigned int hwirq = __fls(stat);
|
||||
handle_IRQ(hwirq, regs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init orion5x_init_irq(void)
|
||||
{
|
||||
orion_irq_init(0, MAIN_IRQ_MASK);
|
||||
|
||||
#ifdef CONFIG_MULTI_IRQ_HANDLER
|
||||
set_handle_irq(orion5x_legacy_handle_irq);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize gpiolib for GPIOs 0-31.
|
||||
*/
|
||||
orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE, 0,
|
||||
IRQ_ORION5X_GPIO_START, gpio0_irqs);
|
||||
}
|
408
arch/arm/mach-orion5x/kurobox_pro-setup.c
Normal file
408
arch/arm/mach-orion5x/kurobox_pro-setup.c
Normal file
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/kurobox_pro-setup.c
|
||||
*
|
||||
* Maintainer: Ronen Shitrit <rshitrit@marvell.com>
|
||||
*
|
||||
* 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/gpio.h>
|
||||
#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/mtd/nand.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include <linux/platform_data/mtd-orion_nand.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* KUROBOX-PRO Info
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* 256K NOR flash Device bus boot chip select
|
||||
*/
|
||||
|
||||
#define KUROBOX_PRO_NOR_BOOT_BASE 0xf4000000
|
||||
#define KUROBOX_PRO_NOR_BOOT_SIZE SZ_256K
|
||||
|
||||
/*
|
||||
* 256M NAND flash on Device bus chip select 1
|
||||
*/
|
||||
|
||||
#define KUROBOX_PRO_NAND_BASE 0xfc000000
|
||||
#define KUROBOX_PRO_NAND_SIZE SZ_2M
|
||||
|
||||
/*****************************************************************************
|
||||
* 256MB NAND Flash on Device bus CS0
|
||||
****************************************************************************/
|
||||
|
||||
static struct mtd_partition kurobox_pro_nand_parts[] = {
|
||||
{
|
||||
.name = "uImage",
|
||||
.offset = 0,
|
||||
.size = SZ_4M,
|
||||
}, {
|
||||
.name = "rootfs",
|
||||
.offset = SZ_4M,
|
||||
.size = SZ_64M,
|
||||
}, {
|
||||
.name = "extra",
|
||||
.offset = SZ_4M + SZ_64M,
|
||||
.size = SZ_256M - (SZ_4M + SZ_64M),
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource kurobox_pro_nand_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = KUROBOX_PRO_NAND_BASE,
|
||||
.end = KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct orion_nand_data kurobox_pro_nand_data = {
|
||||
.parts = kurobox_pro_nand_parts,
|
||||
.nr_parts = ARRAY_SIZE(kurobox_pro_nand_parts),
|
||||
.cle = 0,
|
||||
.ale = 1,
|
||||
.width = 8,
|
||||
};
|
||||
|
||||
static struct platform_device kurobox_pro_nand_flash = {
|
||||
.name = "orion_nand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &kurobox_pro_nand_data,
|
||||
},
|
||||
.resource = &kurobox_pro_nand_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* 256KB NOR Flash on BOOT Device
|
||||
****************************************************************************/
|
||||
|
||||
static struct physmap_flash_data kurobox_pro_nor_flash_data = {
|
||||
.width = 1,
|
||||
};
|
||||
|
||||
static struct resource kurobox_pro_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = KUROBOX_PRO_NOR_BOOT_BASE,
|
||||
.end = KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device kurobox_pro_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &kurobox_pro_nor_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &kurobox_pro_nor_flash_resource,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* PCI
|
||||
****************************************************************************/
|
||||
|
||||
static int __init kurobox_pro_pci_map_irq(const 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 isn't used on the Kuro
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct hw_pci kurobox_pro_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = kurobox_pro_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init kurobox_pro_pci_init(void)
|
||||
{
|
||||
if (machine_is_kurobox_pro()) {
|
||||
orion5x_pci_disable();
|
||||
pci_common_init(&kurobox_pro_pci);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(kurobox_pro_pci_init);
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
|
||||
static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* RTC 5C372a on I2C bus
|
||||
****************************************************************************/
|
||||
static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {
|
||||
I2C_BOARD_INFO("rs5c372a", 0x32),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
static struct mv_sata_platform_data kurobox_pro_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Kurobox Pro specific power off method via UART1-attached microcontroller
|
||||
****************************************************************************/
|
||||
|
||||
#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
|
||||
|
||||
static int kurobox_pro_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 kurobox_pro_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 kurobox_pro_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 */
|
||||
kurobox_pro_miconwrite(data, count);
|
||||
|
||||
/* send checksum */
|
||||
kurobox_pro_miconwrite(&checksum, 1);
|
||||
|
||||
if (kurobox_pro_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));
|
||||
kurobox_pro_miconwrite(send_buf, sizeof(send_buf));
|
||||
|
||||
/* make dummy reads */
|
||||
mdelay(100);
|
||||
kurobox_pro_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 kurobox_pro_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 Kurobox Pro */
|
||||
kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ;
|
||||
kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ;
|
||||
kurobox_pro_miconsend(poweroff, sizeof(poweroff));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int kurobox_pro_mpp_modes[] __initdata = {
|
||||
MPP0_UNUSED,
|
||||
MPP1_UNUSED,
|
||||
MPP2_GPIO, /* GPIO Micon */
|
||||
MPP3_GPIO, /* GPIO Rtc */
|
||||
MPP4_UNUSED,
|
||||
MPP5_UNUSED,
|
||||
MPP6_NAND, /* NAND Flash REn */
|
||||
MPP7_NAND, /* NAND Flash WEn */
|
||||
MPP8_UNUSED,
|
||||
MPP9_UNUSED,
|
||||
MPP10_UNUSED,
|
||||
MPP11_UNUSED,
|
||||
MPP12_SATA_LED, /* SATA 0 presence */
|
||||
MPP13_SATA_LED, /* SATA 1 presence */
|
||||
MPP14_SATA_LED, /* SATA 0 active */
|
||||
MPP15_SATA_LED, /* SATA 1 active */
|
||||
MPP16_UART, /* UART1 RXD */
|
||||
MPP17_UART, /* UART1 TXD */
|
||||
MPP18_UART, /* UART1 CTSn */
|
||||
MPP19_UART, /* UART1 RTSn */
|
||||
0,
|
||||
};
|
||||
|
||||
static void __init kurobox_pro_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(kurobox_pro_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_ehci1_init();
|
||||
orion5x_eth_init(&kurobox_pro_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_sata_init(&kurobox_pro_sata_data);
|
||||
orion5x_uart0_init();
|
||||
orion5x_uart1_init();
|
||||
orion5x_xor_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
KUROBOX_PRO_NOR_BOOT_BASE,
|
||||
KUROBOX_PRO_NOR_BOOT_SIZE);
|
||||
platform_device_register(&kurobox_pro_nor_flash);
|
||||
|
||||
if (machine_is_kurobox_pro()) {
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(0),
|
||||
ORION_MBUS_DEVBUS_ATTR(0),
|
||||
KUROBOX_PRO_NAND_BASE,
|
||||
KUROBOX_PRO_NAND_SIZE);
|
||||
platform_device_register(&kurobox_pro_nand_flash);
|
||||
}
|
||||
|
||||
i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
|
||||
|
||||
/* register Kurobox Pro specific power-off method */
|
||||
pm_power_off = kurobox_pro_power_off;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MACH_KUROBOX_PRO
|
||||
MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
|
||||
/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = kurobox_pro_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACH_LINKSTATION_PRO
|
||||
MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")
|
||||
/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = kurobox_pro_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
||||
#endif
|
330
arch/arm/mach-orion5x/ls-chl-setup.c
Normal file
330
arch/arm/mach-orion5x/ls-chl-setup.c
Normal file
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/ls-chl-setup.c
|
||||
*
|
||||
* Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk>
|
||||
*
|
||||
* 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/mtd/physmap.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/gpio-fan.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 <mach/orion5x.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Linkstation LS-CHL Info
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* 256K NOR flash Device bus boot chip select
|
||||
*/
|
||||
|
||||
#define LSCHL_NOR_BOOT_BASE 0xf4000000
|
||||
#define LSCHL_NOR_BOOT_SIZE SZ_256K
|
||||
|
||||
/*****************************************************************************
|
||||
* 256KB NOR Flash on BOOT Device
|
||||
****************************************************************************/
|
||||
|
||||
static struct physmap_flash_data lschl_nor_flash_data = {
|
||||
.width = 1,
|
||||
};
|
||||
|
||||
static struct resource lschl_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = LSCHL_NOR_BOOT_BASE,
|
||||
.end = LSCHL_NOR_BOOT_BASE + LSCHL_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device lschl_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &lschl_nor_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &lschl_nor_flash_resource,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
|
||||
static struct mv643xx_eth_platform_data lschl_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* RTC 5C372a on I2C bus
|
||||
****************************************************************************/
|
||||
|
||||
static struct i2c_board_info __initdata lschl_i2c_rtc = {
|
||||
I2C_BOARD_INFO("rs5c372a", 0x32),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LEDs attached to GPIO
|
||||
****************************************************************************/
|
||||
|
||||
#define LSCHL_GPIO_LED_ALARM 2
|
||||
#define LSCHL_GPIO_LED_INFO 3
|
||||
#define LSCHL_GPIO_LED_FUNC 17
|
||||
#define LSCHL_GPIO_LED_PWR 0
|
||||
|
||||
static struct gpio_led lschl_led_pins[] = {
|
||||
{
|
||||
.name = "alarm:red",
|
||||
.gpio = LSCHL_GPIO_LED_ALARM,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "info:amber",
|
||||
.gpio = LSCHL_GPIO_LED_INFO,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "func:blue:top",
|
||||
.gpio = LSCHL_GPIO_LED_FUNC,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "power:blue:bottom",
|
||||
.gpio = LSCHL_GPIO_LED_PWR,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data lschl_led_data = {
|
||||
.leds = lschl_led_pins,
|
||||
.num_leds = ARRAY_SIZE(lschl_led_pins),
|
||||
};
|
||||
|
||||
static struct platform_device lschl_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &lschl_led_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
static struct mv_sata_platform_data lschl_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LS-CHL specific power off method: reboot
|
||||
****************************************************************************/
|
||||
/*
|
||||
* On the LS-CHL, 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 lschl_power_off(void)
|
||||
{
|
||||
orion5x_restart(REBOOT_HARD, NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
#define LSCHL_GPIO_USB_POWER 9
|
||||
#define LSCHL_GPIO_AUTO_POWER 17
|
||||
#define LSCHL_GPIO_POWER 18
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO Attached Keys
|
||||
****************************************************************************/
|
||||
#define LSCHL_GPIO_KEY_FUNC 15
|
||||
#define LSCHL_GPIO_KEY_POWER 8
|
||||
#define LSCHL_GPIO_KEY_AUTOPOWER 10
|
||||
#define LSCHL_SW_POWER 0x00
|
||||
#define LSCHL_SW_AUTOPOWER 0x01
|
||||
#define LSCHL_SW_FUNC 0x02
|
||||
|
||||
static struct gpio_keys_button lschl_buttons[] = {
|
||||
{
|
||||
.type = EV_SW,
|
||||
.code = LSCHL_SW_POWER,
|
||||
.gpio = LSCHL_GPIO_KEY_POWER,
|
||||
.desc = "Power-on Switch",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.type = EV_SW,
|
||||
.code = LSCHL_SW_AUTOPOWER,
|
||||
.gpio = LSCHL_GPIO_KEY_AUTOPOWER,
|
||||
.desc = "Power-auto Switch",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.type = EV_SW,
|
||||
.code = LSCHL_SW_FUNC,
|
||||
.gpio = LSCHL_GPIO_KEY_FUNC,
|
||||
.desc = "Function Switch",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data lschl_button_data = {
|
||||
.buttons = lschl_buttons,
|
||||
.nbuttons = ARRAY_SIZE(lschl_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device lschl_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &lschl_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
#define LSCHL_GPIO_HDD_POWER 1
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO Fan
|
||||
****************************************************************************/
|
||||
|
||||
#define LSCHL_GPIO_FAN_LOW 16
|
||||
#define LSCHL_GPIO_FAN_HIGH 14
|
||||
#define LSCHL_GPIO_FAN_LOCK 6
|
||||
|
||||
static struct gpio_fan_alarm lschl_alarm = {
|
||||
.gpio = LSCHL_GPIO_FAN_LOCK,
|
||||
};
|
||||
|
||||
static struct gpio_fan_speed lschl_speeds[] = {
|
||||
{
|
||||
.rpm = 0,
|
||||
.ctrl_val = 3,
|
||||
}, {
|
||||
.rpm = 1500,
|
||||
.ctrl_val = 2,
|
||||
}, {
|
||||
.rpm = 3250,
|
||||
.ctrl_val = 1,
|
||||
}, {
|
||||
.rpm = 5000,
|
||||
.ctrl_val = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static int lschl_gpio_list[] = {
|
||||
LSCHL_GPIO_FAN_HIGH, LSCHL_GPIO_FAN_LOW,
|
||||
};
|
||||
|
||||
static struct gpio_fan_platform_data lschl_fan_data = {
|
||||
.num_ctrl = ARRAY_SIZE(lschl_gpio_list),
|
||||
.ctrl = lschl_gpio_list,
|
||||
.alarm = &lschl_alarm,
|
||||
.num_speed = ARRAY_SIZE(lschl_speeds),
|
||||
.speed = lschl_speeds,
|
||||
};
|
||||
|
||||
static struct platform_device lschl_fan_device = {
|
||||
.name = "gpio-fan",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &lschl_fan_data,
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO Data
|
||||
****************************************************************************/
|
||||
|
||||
static unsigned int lschl_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* LED POWER */
|
||||
MPP1_GPIO, /* HDD POWER */
|
||||
MPP2_GPIO, /* LED ALARM */
|
||||
MPP3_GPIO, /* LED INFO */
|
||||
MPP4_UNUSED,
|
||||
MPP5_UNUSED,
|
||||
MPP6_GPIO, /* FAN LOCK */
|
||||
MPP7_GPIO, /* SW INIT */
|
||||
MPP8_GPIO, /* SW POWER */
|
||||
MPP9_GPIO, /* USB POWER */
|
||||
MPP10_GPIO, /* SW AUTO POWER */
|
||||
MPP11_UNUSED,
|
||||
MPP12_UNUSED,
|
||||
MPP13_UNUSED,
|
||||
MPP14_GPIO, /* FAN HIGH */
|
||||
MPP15_GPIO, /* SW FUNC */
|
||||
MPP16_GPIO, /* FAN LOW */
|
||||
MPP17_GPIO, /* LED FUNC */
|
||||
MPP18_UNUSED,
|
||||
MPP19_UNUSED,
|
||||
0,
|
||||
};
|
||||
|
||||
static void __init lschl_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Needs to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(lschl_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_ehci1_init();
|
||||
orion5x_eth_init(&lschl_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_sata_init(&lschl_sata_data);
|
||||
orion5x_uart0_init();
|
||||
orion5x_xor_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
LSCHL_NOR_BOOT_BASE,
|
||||
LSCHL_NOR_BOOT_SIZE);
|
||||
platform_device_register(&lschl_nor_flash);
|
||||
|
||||
platform_device_register(&lschl_leds);
|
||||
|
||||
platform_device_register(&lschl_button_device);
|
||||
|
||||
platform_device_register(&lschl_fan_device);
|
||||
|
||||
i2c_register_board_info(0, &lschl_i2c_rtc, 1);
|
||||
|
||||
/* usb power on */
|
||||
gpio_set_value(LSCHL_GPIO_USB_POWER, 1);
|
||||
|
||||
/* register power-off method */
|
||||
pm_power_off = lschl_power_off;
|
||||
|
||||
pr_info("%s: finished\n", __func__);
|
||||
}
|
||||
|
||||
MACHINE_START(LINKSTATION_LSCHL, "Buffalo Linkstation LiveV3 (LS-CHL)")
|
||||
/* Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = lschl_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
277
arch/arm/mach-orion5x/ls_hgl-setup.c
Normal file
277
arch/arm/mach-orion5x/ls_hgl-setup.c
Normal file
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/ls_hgl-setup.c
|
||||
*
|
||||
* Maintainer: Zhu Qingsen <zhuqs@cn.fujitsu.com>
|
||||
*
|
||||
* 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/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 <mach/orion5x.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Linkstation LS-HGL Info
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* 256K NOR flash Device bus boot chip select
|
||||
*/
|
||||
|
||||
#define LS_HGL_NOR_BOOT_BASE 0xf4000000
|
||||
#define LS_HGL_NOR_BOOT_SIZE SZ_256K
|
||||
|
||||
/*****************************************************************************
|
||||
* 256KB NOR Flash on BOOT Device
|
||||
****************************************************************************/
|
||||
|
||||
static struct physmap_flash_data ls_hgl_nor_flash_data = {
|
||||
.width = 1,
|
||||
};
|
||||
|
||||
static struct resource ls_hgl_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = LS_HGL_NOR_BOOT_BASE,
|
||||
.end = LS_HGL_NOR_BOOT_BASE + LS_HGL_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device ls_hgl_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &ls_hgl_nor_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &ls_hgl_nor_flash_resource,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
|
||||
static struct mv643xx_eth_platform_data ls_hgl_eth_data = {
|
||||
.phy_addr = 8,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* RTC 5C372a on I2C bus
|
||||
****************************************************************************/
|
||||
|
||||
static struct i2c_board_info __initdata ls_hgl_i2c_rtc = {
|
||||
I2C_BOARD_INFO("rs5c372a", 0x32),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LEDs attached to GPIO
|
||||
****************************************************************************/
|
||||
|
||||
#define LS_HGL_GPIO_LED_ALARM 2
|
||||
#define LS_HGL_GPIO_LED_INFO 3
|
||||
#define LS_HGL_GPIO_LED_FUNC 17
|
||||
#define LS_HGL_GPIO_LED_PWR 0
|
||||
|
||||
|
||||
static struct gpio_led ls_hgl_led_pins[] = {
|
||||
{
|
||||
.name = "alarm:red",
|
||||
.gpio = LS_HGL_GPIO_LED_ALARM,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "info:amber",
|
||||
.gpio = LS_HGL_GPIO_LED_INFO,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "func:blue:top",
|
||||
.gpio = LS_HGL_GPIO_LED_FUNC,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "power:blue:bottom",
|
||||
.gpio = LS_HGL_GPIO_LED_PWR,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data ls_hgl_led_data = {
|
||||
.leds = ls_hgl_led_pins,
|
||||
.num_leds = ARRAY_SIZE(ls_hgl_led_pins),
|
||||
};
|
||||
|
||||
static struct platform_device ls_hgl_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &ls_hgl_led_data,
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO Attached Keys
|
||||
****************************************************************************/
|
||||
#define LS_HGL_GPIO_KEY_FUNC 15
|
||||
#define LS_HGL_GPIO_KEY_POWER 8
|
||||
#define LS_HGL_GPIO_KEY_AUTOPOWER 10
|
||||
|
||||
#define LS_HGL_SW_POWER 0x00
|
||||
#define LS_HGL_SW_AUTOPOWER 0x01
|
||||
|
||||
static struct gpio_keys_button ls_hgl_buttons[] = {
|
||||
{
|
||||
.code = KEY_OPTION,
|
||||
.gpio = LS_HGL_GPIO_KEY_FUNC,
|
||||
.desc = "Function Button",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.type = EV_SW,
|
||||
.code = LS_HGL_SW_POWER,
|
||||
.gpio = LS_HGL_GPIO_KEY_POWER,
|
||||
.desc = "Power-on Switch",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.type = EV_SW,
|
||||
.code = LS_HGL_SW_AUTOPOWER,
|
||||
.gpio = LS_HGL_GPIO_KEY_AUTOPOWER,
|
||||
.desc = "Power-auto Switch",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data ls_hgl_button_data = {
|
||||
.buttons = ls_hgl_buttons,
|
||||
.nbuttons = ARRAY_SIZE(ls_hgl_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device ls_hgl_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &ls_hgl_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
static struct mv_sata_platform_data ls_hgl_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Linkstation LS-HGL specific power off method: reboot
|
||||
****************************************************************************/
|
||||
/*
|
||||
* On the Linkstation LS-HGL, 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 ls_hgl_power_off(void)
|
||||
{
|
||||
orion5x_restart(REBOOT_HARD, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
|
||||
#define LS_HGL_GPIO_USB_POWER 9
|
||||
#define LS_HGL_GPIO_AUTO_POWER 10
|
||||
#define LS_HGL_GPIO_POWER 8
|
||||
|
||||
#define LS_HGL_GPIO_HDD_POWER 1
|
||||
|
||||
static unsigned int ls_hgl_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* LED_PWR */
|
||||
MPP1_GPIO, /* HDD_PWR */
|
||||
MPP2_GPIO, /* LED_ALARM */
|
||||
MPP3_GPIO, /* LED_INFO */
|
||||
MPP4_UNUSED,
|
||||
MPP5_UNUSED,
|
||||
MPP6_GPIO, /* FAN_LCK */
|
||||
MPP7_GPIO, /* INIT */
|
||||
MPP8_GPIO, /* POWER */
|
||||
MPP9_GPIO, /* USB_PWR */
|
||||
MPP10_GPIO, /* AUTO_POWER */
|
||||
MPP11_UNUSED, /* LED_ETH (dummy) */
|
||||
MPP12_UNUSED,
|
||||
MPP13_UNUSED,
|
||||
MPP14_UNUSED,
|
||||
MPP15_GPIO, /* FUNC */
|
||||
MPP16_UNUSED,
|
||||
MPP17_GPIO, /* LED_FUNC */
|
||||
MPP18_UNUSED,
|
||||
MPP19_UNUSED,
|
||||
0,
|
||||
};
|
||||
|
||||
static void __init ls_hgl_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(ls_hgl_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_ehci1_init();
|
||||
orion5x_eth_init(&ls_hgl_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_sata_init(&ls_hgl_sata_data);
|
||||
orion5x_uart0_init();
|
||||
orion5x_xor_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
LS_HGL_NOR_BOOT_BASE,
|
||||
LS_HGL_NOR_BOOT_SIZE);
|
||||
platform_device_register(&ls_hgl_nor_flash);
|
||||
|
||||
platform_device_register(&ls_hgl_button_device);
|
||||
|
||||
platform_device_register(&ls_hgl_leds);
|
||||
|
||||
i2c_register_board_info(0, &ls_hgl_i2c_rtc, 1);
|
||||
|
||||
/* enable USB power */
|
||||
gpio_set_value(LS_HGL_GPIO_USB_POWER, 1);
|
||||
|
||||
/* register power-off method */
|
||||
pm_power_off = ls_hgl_power_off;
|
||||
|
||||
pr_info("%s: finished\n", __func__);
|
||||
}
|
||||
|
||||
MACHINE_START(LINKSTATION_LS_HGL, "Buffalo Linkstation LS-HGL")
|
||||
/* Maintainer: Zhu Qingsen <zhuqs@cn.fujistu.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = ls_hgl_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
280
arch/arm/mach-orion5x/lsmini-setup.c
Normal file
280
arch/arm/mach-orion5x/lsmini-setup.c
Normal file
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
* 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/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 <mach/orion5x.h>
|
||||
#include "common.h"
|
||||
#include "mpp.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)
|
||||
{
|
||||
orion5x_restart(REBOOT_HARD, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* 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 unsigned int lsmini_mpp_modes[] __initdata = {
|
||||
MPP0_UNUSED, /* LED_RESERVE1 (unused) */
|
||||
MPP1_GPIO, /* HDD_PWR */
|
||||
MPP2_GPIO, /* LED_ALARM */
|
||||
MPP3_GPIO, /* LED_INFO */
|
||||
MPP4_UNUSED,
|
||||
MPP5_UNUSED,
|
||||
MPP6_UNUSED,
|
||||
MPP7_UNUSED,
|
||||
MPP8_UNUSED,
|
||||
MPP9_GPIO, /* LED_FUNC */
|
||||
MPP10_UNUSED,
|
||||
MPP11_UNUSED, /* LED_ETH (dummy) */
|
||||
MPP12_UNUSED,
|
||||
MPP13_UNUSED,
|
||||
MPP14_GPIO, /* LED_PWR */
|
||||
MPP15_GPIO, /* FUNC */
|
||||
MPP16_GPIO, /* USB_PWR */
|
||||
MPP17_GPIO, /* AUTO_POWER */
|
||||
MPP18_GPIO, /* POWER */
|
||||
MPP19_GPIO, /* HDD_PWR1 */
|
||||
0,
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
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> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = lsmini_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
||||
#endif
|
44
arch/arm/mach-orion5x/mpp.c
Normal file
44
arch/arm/mach-orion5x/mpp.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/mpp.c
|
||||
*
|
||||
* MPP functions for Marvell Orion 5x SoCs
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <plat/mpp.h>
|
||||
#include "mpp.h"
|
||||
#include "common.h"
|
||||
|
||||
static unsigned int __init orion5x_variant(void)
|
||||
{
|
||||
u32 dev;
|
||||
u32 rev;
|
||||
|
||||
orion5x_pcie_id(&dev, &rev);
|
||||
|
||||
if (dev == MV88F5181_DEV_ID)
|
||||
return MPP_F5181_MASK;
|
||||
|
||||
if (dev == MV88F5182_DEV_ID)
|
||||
return MPP_F5182_MASK;
|
||||
|
||||
if (dev == MV88F5281_DEV_ID)
|
||||
return MPP_F5281_MASK;
|
||||
|
||||
printk(KERN_ERR "MPP setup: unknown orion5x variant "
|
||||
"(dev %#x rev %#x)\n", dev, rev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init orion5x_mpp_conf(unsigned int *mpp_list)
|
||||
{
|
||||
orion_mpp_conf(mpp_list, orion5x_variant(),
|
||||
MPP_MAX, ORION5X_DEV_BUS_VIRT_BASE);
|
||||
}
|
129
arch/arm/mach-orion5x/mpp.h
Normal file
129
arch/arm/mach-orion5x/mpp.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
#ifndef __ARCH_ORION5X_MPP_H
|
||||
#define __ARCH_ORION5X_MPP_H
|
||||
|
||||
#define MPP(_num, _sel, _in, _out, _F5181l, _F5182, _F5281) ( \
|
||||
/* MPP number */ ((_num) & 0xff) | \
|
||||
/* MPP select value */ (((_sel) & 0xf) << 8) | \
|
||||
/* may be input signal */ ((!!(_in)) << 12) | \
|
||||
/* may be output signal */ ((!!(_out)) << 13) | \
|
||||
/* available on F5181l */ ((!!(_F5181l)) << 14) | \
|
||||
/* available on F5182 */ ((!!(_F5182)) << 15) | \
|
||||
/* available on F5281 */ ((!!(_F5281)) << 16))
|
||||
|
||||
/* num sel i o 5181 5182 5281 */
|
||||
|
||||
#define MPP_F5181_MASK MPP(0, 0x0, 0, 0, 1, 0, 0)
|
||||
#define MPP_F5182_MASK MPP(0, 0x0, 0, 0, 0, 1, 0)
|
||||
#define MPP_F5281_MASK MPP(0, 0x0, 0, 0, 0, 0, 1)
|
||||
|
||||
#define MPP0_UNUSED MPP(0, 0x3, 0, 0, 1, 1, 1)
|
||||
#define MPP0_GPIO MPP(0, 0x3, 1, 1, 1, 1, 1)
|
||||
#define MPP0_PCIE_RST_OUTn MPP(0, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP0_PCI_ARB MPP(0, 0x2, 0, 0, 1, 1, 1)
|
||||
|
||||
#define MPP1_UNUSED MPP(1, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP1_GPIO MPP(1, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP1_PCI_ARB MPP(1, 0x2, 0, 0, 1, 1, 1)
|
||||
|
||||
#define MPP2_UNUSED MPP(2, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP2_GPIO MPP(2, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP2_PCI_ARB MPP(2, 0x2, 0, 0, 1, 1, 1)
|
||||
#define MPP2_PCI_PMEn MPP(2, 0x3, 0, 0, 1, 1, 1)
|
||||
|
||||
#define MPP3_UNUSED MPP(3, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP3_GPIO MPP(3, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP3_PCI_ARB MPP(3, 0x2, 0, 0, 1, 1, 1)
|
||||
|
||||
#define MPP4_UNUSED MPP(4, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP4_GPIO MPP(4, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP4_PCI_ARB MPP(4, 0x2, 0, 0, 1, 1, 1)
|
||||
#define MPP4_NAND MPP(4, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP4_SATA_LED MPP(4, 0x5, 0, 0, 0, 1, 0)
|
||||
|
||||
#define MPP5_UNUSED MPP(5, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP5_GPIO MPP(5, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP5_PCI_ARB MPP(5, 0x2, 0, 0, 1, 1, 1)
|
||||
#define MPP5_NAND MPP(5, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP5_SATA_LED MPP(5, 0x5, 0, 0, 0, 1, 0)
|
||||
|
||||
#define MPP6_UNUSED MPP(6, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP6_GPIO MPP(6, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP6_PCI_ARB MPP(6, 0x2, 0, 0, 1, 1, 1)
|
||||
#define MPP6_NAND MPP(6, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP6_PCI_CLK MPP(6, 0x5, 0, 0, 1, 0, 0)
|
||||
#define MPP6_SATA_LED MPP(6, 0x5, 0, 0, 0, 1, 0)
|
||||
|
||||
#define MPP7_UNUSED MPP(7, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP7_GPIO MPP(7, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP7_PCI_ARB MPP(7, 0x2, 0, 0, 1, 1, 1)
|
||||
#define MPP7_NAND MPP(7, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP7_PCI_CLK MPP(7, 0x5, 0, 0, 1, 0, 0)
|
||||
#define MPP7_SATA_LED MPP(7, 0x5, 0, 0, 0, 1, 0)
|
||||
|
||||
#define MPP8_UNUSED MPP(8, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP8_GPIO MPP(8, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP8_GIGE MPP(8, 0x1, 0, 0, 1, 1, 1)
|
||||
|
||||
#define MPP9_UNUSED MPP(9, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP9_GPIO MPP(9, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP9_GIGE MPP(9, 0x1, 0, 0, 1, 1, 1)
|
||||
|
||||
#define MPP10_UNUSED MPP(10, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP10_GPIO MPP(10, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP10_GIGE MPP(10, 0x1, 0, 0, 1, 1, 1)
|
||||
|
||||
#define MPP11_UNUSED MPP(11, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP11_GPIO MPP(11, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP11_GIGE MPP(11, 0x1, 0, 0, 1, 1, 1)
|
||||
|
||||
#define MPP12_UNUSED MPP(12, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP12_GPIO MPP(12, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP12_GIGE MPP(12, 0x1, 0, 0, 1, 1, 1)
|
||||
#define MPP12_NAND MPP(12, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP12_SATA_LED MPP(12, 0x5, 0, 0, 0, 1, 0)
|
||||
|
||||
#define MPP13_UNUSED MPP(13, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP13_GPIO MPP(13, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP13_GIGE MPP(13, 0x1, 0, 0, 1, 1, 1)
|
||||
#define MPP13_NAND MPP(13, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP13_SATA_LED MPP(13, 0x5, 0, 0, 0, 1, 0)
|
||||
|
||||
#define MPP14_UNUSED MPP(14, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP14_GPIO MPP(14, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP14_GIGE MPP(14, 0x1, 0, 0, 1, 1, 1)
|
||||
#define MPP14_NAND MPP(14, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP14_SATA_LED MPP(14, 0x5, 0, 0, 0, 1, 0)
|
||||
|
||||
#define MPP15_UNUSED MPP(15, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP15_GPIO MPP(15, 0x0, 1, 1, 1, 1, 1)
|
||||
#define MPP15_GIGE MPP(15, 0x1, 0, 0, 1, 1, 1)
|
||||
#define MPP15_NAND MPP(15, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP15_SATA_LED MPP(15, 0x5, 0, 0, 0, 1, 0)
|
||||
|
||||
#define MPP16_UNUSED MPP(16, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP16_GPIO MPP(16, 0x5, 1, 1, 0, 1, 0)
|
||||
#define MPP16_GIGE MPP(16, 0x1, 0, 0, 1, 1, 1)
|
||||
#define MPP16_NAND MPP(16, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP16_UART MPP(16, 0x0, 0, 0, 0, 1, 1)
|
||||
|
||||
#define MPP17_UNUSED MPP(17, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP17_GPIO MPP(17, 0x5, 1, 1, 0, 1, 0)
|
||||
#define MPP17_GIGE MPP(17, 0x1, 0, 0, 1, 1, 1)
|
||||
#define MPP17_NAND MPP(17, 0x4, 0, 0, 0, 1, 1)
|
||||
#define MPP17_UART MPP(17, 0x0, 0, 0, 0, 1, 1)
|
||||
|
||||
#define MPP18_UNUSED MPP(18, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP18_GPIO MPP(18, 0x5, 1, 1, 0, 1, 0)
|
||||
#define MPP18_GIGE MPP(18, 0x1, 0, 0, 1, 1, 1)
|
||||
#define MPP18_UART MPP(18, 0x0, 0, 0, 0, 1, 1)
|
||||
|
||||
#define MPP19_UNUSED MPP(19, 0x0, 0, 0, 1, 1, 1)
|
||||
#define MPP19_GPIO MPP(19, 0x5, 1, 1, 0, 1, 0)
|
||||
#define MPP19_GIGE MPP(19, 0x1, 0, 0, 1, 1, 1)
|
||||
#define MPP19_UART MPP(19, 0x0, 0, 0, 0, 1, 1)
|
||||
|
||||
#define MPP_MAX 19
|
||||
|
||||
void orion5x_mpp_conf(unsigned int *mpp_list);
|
||||
|
||||
#endif
|
242
arch/arm/mach-orion5x/mv2120-setup.c
Normal file
242
arch/arm/mach-orion5x/mv2120-setup.c
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
* Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser 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/gpio.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.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 <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
#define MV2120_NOR_BOOT_BASE 0xf4000000
|
||||
#define MV2120_NOR_BOOT_SIZE SZ_512K
|
||||
|
||||
#define MV2120_GPIO_RTC_IRQ 3
|
||||
#define MV2120_GPIO_KEY_RESET 17
|
||||
#define MV2120_GPIO_KEY_POWER 18
|
||||
#define MV2120_GPIO_POWER_OFF 19
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
static struct mv643xx_eth_platform_data mv2120_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
static struct mv_sata_platform_data mv2120_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
static struct mtd_partition mv2120_partitions[] = {
|
||||
{
|
||||
.name = "firmware",
|
||||
.size = 0x00080000,
|
||||
.offset = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data mv2120_nor_flash_data = {
|
||||
.width = 1,
|
||||
.parts = mv2120_partitions,
|
||||
.nr_parts = ARRAY_SIZE(mv2120_partitions)
|
||||
};
|
||||
|
||||
static struct resource mv2120_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = MV2120_NOR_BOOT_BASE,
|
||||
.end = MV2120_NOR_BOOT_BASE + MV2120_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device mv2120_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &mv2120_nor_flash_data,
|
||||
},
|
||||
.resource = &mv2120_nor_flash_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
static struct gpio_keys_button mv2120_buttons[] = {
|
||||
{
|
||||
.code = KEY_RESTART,
|
||||
.gpio = MV2120_GPIO_KEY_RESET,
|
||||
.desc = "reset",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.code = KEY_POWER,
|
||||
.gpio = MV2120_GPIO_KEY_POWER,
|
||||
.desc = "power",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data mv2120_button_data = {
|
||||
.buttons = mv2120_buttons,
|
||||
.nbuttons = ARRAY_SIZE(mv2120_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device mv2120_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &mv2120_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int mv2120_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* Sys status LED */
|
||||
MPP1_GPIO, /* Sys error LED */
|
||||
MPP2_GPIO, /* OverTemp interrupt */
|
||||
MPP3_GPIO, /* RTC interrupt */
|
||||
MPP4_GPIO, /* V_LED 5V */
|
||||
MPP5_GPIO, /* V_LED 3.3V */
|
||||
MPP6_UNUSED,
|
||||
MPP7_UNUSED,
|
||||
MPP8_GPIO, /* SATA 0 fail LED */
|
||||
MPP9_GPIO, /* SATA 1 fail LED */
|
||||
MPP10_UNUSED,
|
||||
MPP11_UNUSED,
|
||||
MPP12_SATA_LED, /* SATA 0 presence */
|
||||
MPP13_SATA_LED, /* SATA 1 presence */
|
||||
MPP14_SATA_LED, /* SATA 0 active */
|
||||
MPP15_SATA_LED, /* SATA 1 active */
|
||||
MPP16_UNUSED,
|
||||
MPP17_GPIO, /* Reset button */
|
||||
MPP18_GPIO, /* Power button */
|
||||
MPP19_GPIO, /* Power off */
|
||||
0,
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata mv2120_i2c_rtc = {
|
||||
I2C_BOARD_INFO("pcf8563", 0x51),
|
||||
.irq = 0,
|
||||
};
|
||||
|
||||
static struct gpio_led mv2120_led_pins[] = {
|
||||
{
|
||||
.name = "mv2120:blue:health",
|
||||
.gpio = 0,
|
||||
},
|
||||
{
|
||||
.name = "mv2120:red:health",
|
||||
.gpio = 1,
|
||||
},
|
||||
{
|
||||
.name = "mv2120:led:bright",
|
||||
.gpio = 4,
|
||||
.default_trigger = "default-on",
|
||||
},
|
||||
{
|
||||
.name = "mv2120:led:dimmed",
|
||||
.gpio = 5,
|
||||
},
|
||||
{
|
||||
.name = "mv2120:red:sata0",
|
||||
.gpio = 8,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "mv2120:red:sata1",
|
||||
.gpio = 9,
|
||||
.active_low = 1,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data mv2120_led_data = {
|
||||
.leds = mv2120_led_pins,
|
||||
.num_leds = ARRAY_SIZE(mv2120_led_pins),
|
||||
};
|
||||
|
||||
static struct platform_device mv2120_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &mv2120_led_data,
|
||||
}
|
||||
};
|
||||
|
||||
static void mv2120_power_off(void)
|
||||
{
|
||||
pr_info("%s: triggering power-off...\n", __func__);
|
||||
gpio_set_value(MV2120_GPIO_POWER_OFF, 0);
|
||||
}
|
||||
|
||||
static void __init mv2120_init(void)
|
||||
{
|
||||
/* Setup basic Orion functions. Need to be called early. */
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(mv2120_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_ehci1_init();
|
||||
orion5x_eth_init(&mv2120_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_sata_init(&mv2120_sata_data);
|
||||
orion5x_uart0_init();
|
||||
orion5x_xor_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
MV2120_NOR_BOOT_BASE,
|
||||
MV2120_NOR_BOOT_SIZE);
|
||||
platform_device_register(&mv2120_nor_flash);
|
||||
|
||||
platform_device_register(&mv2120_button_device);
|
||||
|
||||
if (gpio_request(MV2120_GPIO_RTC_IRQ, "rtc") == 0) {
|
||||
if (gpio_direction_input(MV2120_GPIO_RTC_IRQ) == 0)
|
||||
mv2120_i2c_rtc.irq = gpio_to_irq(MV2120_GPIO_RTC_IRQ);
|
||||
else
|
||||
gpio_free(MV2120_GPIO_RTC_IRQ);
|
||||
}
|
||||
i2c_register_board_info(0, &mv2120_i2c_rtc, 1);
|
||||
platform_device_register(&mv2120_leds);
|
||||
|
||||
/* register mv2120 specific power-off method */
|
||||
if (gpio_request(MV2120_GPIO_POWER_OFF, "POWEROFF") != 0 ||
|
||||
gpio_direction_output(MV2120_GPIO_POWER_OFF, 1) != 0)
|
||||
pr_err("mv2120: failed to setup power-off GPIO\n");
|
||||
pm_power_off = mv2120_power_off;
|
||||
}
|
||||
|
||||
/* Warning: HP uses a wrong mach-type (=526) in their bootloader */
|
||||
MACHINE_START(MV2120, "HP Media Vault mv2120")
|
||||
/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = mv2120_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
434
arch/arm/mach-orion5x/net2big-setup.c
Normal file
434
arch/arm/mach-orion5x/net2big-setup.c
Normal file
|
@ -0,0 +1,434 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/net2big-setup.c
|
||||
*
|
||||
* LaCie 2Big Network NAS setup
|
||||
*
|
||||
* Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
|
||||
*
|
||||
* 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/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 <linux/delay.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include <plat/orion-gpio.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* LaCie 2Big Network Info
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* 512KB NOR flash Device bus boot chip select
|
||||
*/
|
||||
|
||||
#define NET2BIG_NOR_BOOT_BASE 0xfff80000
|
||||
#define NET2BIG_NOR_BOOT_SIZE SZ_512K
|
||||
|
||||
/*****************************************************************************
|
||||
* 512KB NOR Flash on Boot Device
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* TODO: Check write support on flash MX29LV400CBTC-70G
|
||||
*/
|
||||
|
||||
static struct mtd_partition net2big_partitions[] = {
|
||||
{
|
||||
.name = "Full512kb",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 0x00000000,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data net2big_nor_flash_data = {
|
||||
.width = 1,
|
||||
.parts = net2big_partitions,
|
||||
.nr_parts = ARRAY_SIZE(net2big_partitions),
|
||||
};
|
||||
|
||||
static struct resource net2big_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = NET2BIG_NOR_BOOT_BASE,
|
||||
.end = NET2BIG_NOR_BOOT_BASE
|
||||
+ NET2BIG_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device net2big_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &net2big_nor_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &net2big_nor_flash_resource,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
|
||||
static struct mv643xx_eth_platform_data net2big_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* I2C devices
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* i2c addr | chip | description
|
||||
* 0x32 | Ricoh 5C372b | RTC
|
||||
* 0x50 | HT24LC08 | eeprom (1kB)
|
||||
*/
|
||||
static struct i2c_board_info __initdata net2big_i2c_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("rs5c372b", 0x32),
|
||||
}, {
|
||||
I2C_BOARD_INFO("24c08", 0x50),
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
|
||||
static struct mv_sata_platform_data net2big_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
#define NET2BIG_GPIO_SATA_POWER_REQ 19
|
||||
#define NET2BIG_GPIO_SATA0_POWER 23
|
||||
#define NET2BIG_GPIO_SATA1_POWER 25
|
||||
|
||||
static void __init net2big_sata_power_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Configure GPIOs over MPP max number. */
|
||||
orion_gpio_set_valid(NET2BIG_GPIO_SATA0_POWER, 1);
|
||||
orion_gpio_set_valid(NET2BIG_GPIO_SATA1_POWER, 1);
|
||||
|
||||
err = gpio_request(NET2BIG_GPIO_SATA0_POWER, "SATA0 power status");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_input(NET2BIG_GPIO_SATA0_POWER);
|
||||
if (err)
|
||||
gpio_free(NET2BIG_GPIO_SATA0_POWER);
|
||||
}
|
||||
if (err) {
|
||||
pr_err("net2big: failed to setup SATA0 power GPIO\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = gpio_request(NET2BIG_GPIO_SATA1_POWER, "SATA1 power status");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_input(NET2BIG_GPIO_SATA1_POWER);
|
||||
if (err)
|
||||
gpio_free(NET2BIG_GPIO_SATA1_POWER);
|
||||
}
|
||||
if (err) {
|
||||
pr_err("net2big: failed to setup SATA1 power GPIO\n");
|
||||
goto err_free_1;
|
||||
}
|
||||
|
||||
err = gpio_request(NET2BIG_GPIO_SATA_POWER_REQ, "SATA power request");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(NET2BIG_GPIO_SATA_POWER_REQ, 0);
|
||||
if (err)
|
||||
gpio_free(NET2BIG_GPIO_SATA_POWER_REQ);
|
||||
}
|
||||
if (err) {
|
||||
pr_err("net2big: failed to setup SATA power request GPIO\n");
|
||||
goto err_free_2;
|
||||
}
|
||||
|
||||
if (gpio_get_value(NET2BIG_GPIO_SATA0_POWER) &&
|
||||
gpio_get_value(NET2BIG_GPIO_SATA1_POWER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* SATA power up on both disk is done by pulling high the CPLD power
|
||||
* request line. The 300ms delay is related to the CPLD clock and is
|
||||
* needed to be sure that the CPLD has take into account the low line
|
||||
* status.
|
||||
*/
|
||||
msleep(300);
|
||||
gpio_set_value(NET2BIG_GPIO_SATA_POWER_REQ, 1);
|
||||
pr_info("net2big: power up SATA hard disks\n");
|
||||
|
||||
return;
|
||||
|
||||
err_free_2:
|
||||
gpio_free(NET2BIG_GPIO_SATA1_POWER);
|
||||
err_free_1:
|
||||
gpio_free(NET2BIG_GPIO_SATA0_POWER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GPIO LEDs
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* The power front LEDs (blue and red) and SATA red LEDs are controlled via a
|
||||
* single GPIO line and are compatible with the leds-gpio driver.
|
||||
*
|
||||
* The SATA blue LEDs have some hardware blink capabilities which are detailed
|
||||
* in the following array:
|
||||
*
|
||||
* SATAx blue LED | SATAx activity | LED state
|
||||
* | |
|
||||
* 0 | 0 | blink (rate 300ms)
|
||||
* 1 | 0 | off
|
||||
* ? | 1 | on
|
||||
*
|
||||
* Notes: The blue and the red front LED's can't be on at the same time.
|
||||
* Blue LED have priority.
|
||||
*/
|
||||
|
||||
#define NET2BIG_GPIO_PWR_RED_LED 6
|
||||
#define NET2BIG_GPIO_PWR_BLUE_LED 16
|
||||
#define NET2BIG_GPIO_PWR_LED_BLINK_STOP 7
|
||||
|
||||
#define NET2BIG_GPIO_SATA0_RED_LED 11
|
||||
#define NET2BIG_GPIO_SATA1_RED_LED 10
|
||||
|
||||
#define NET2BIG_GPIO_SATA0_BLUE_LED 17
|
||||
#define NET2BIG_GPIO_SATA1_BLUE_LED 13
|
||||
|
||||
static struct gpio_led net2big_leds[] = {
|
||||
{
|
||||
.name = "net2big:red:power",
|
||||
.gpio = NET2BIG_GPIO_PWR_RED_LED,
|
||||
},
|
||||
{
|
||||
.name = "net2big:blue:power",
|
||||
.gpio = NET2BIG_GPIO_PWR_BLUE_LED,
|
||||
},
|
||||
{
|
||||
.name = "net2big:red:sata0",
|
||||
.gpio = NET2BIG_GPIO_SATA0_RED_LED,
|
||||
},
|
||||
{
|
||||
.name = "net2big:red:sata1",
|
||||
.gpio = NET2BIG_GPIO_SATA1_RED_LED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data net2big_led_data = {
|
||||
.num_leds = ARRAY_SIZE(net2big_leds),
|
||||
.leds = net2big_leds,
|
||||
};
|
||||
|
||||
static struct platform_device net2big_gpio_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &net2big_led_data,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init net2big_gpio_leds_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Stop initial CPLD slow red/blue blinking on power LED. */
|
||||
err = gpio_request(NET2BIG_GPIO_PWR_LED_BLINK_STOP,
|
||||
"Power LED blink stop");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(NET2BIG_GPIO_PWR_LED_BLINK_STOP, 1);
|
||||
if (err)
|
||||
gpio_free(NET2BIG_GPIO_PWR_LED_BLINK_STOP);
|
||||
}
|
||||
if (err)
|
||||
pr_err("net2big: failed to setup power LED blink GPIO\n");
|
||||
|
||||
/*
|
||||
* Configure SATA0 and SATA1 blue LEDs to blink in relation with the
|
||||
* hard disk activity.
|
||||
*/
|
||||
err = gpio_request(NET2BIG_GPIO_SATA0_BLUE_LED,
|
||||
"SATA0 blue LED control");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(NET2BIG_GPIO_SATA0_BLUE_LED, 1);
|
||||
if (err)
|
||||
gpio_free(NET2BIG_GPIO_SATA0_BLUE_LED);
|
||||
}
|
||||
if (err)
|
||||
pr_err("net2big: failed to setup SATA0 blue LED GPIO\n");
|
||||
|
||||
err = gpio_request(NET2BIG_GPIO_SATA1_BLUE_LED,
|
||||
"SATA1 blue LED control");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(NET2BIG_GPIO_SATA1_BLUE_LED, 1);
|
||||
if (err)
|
||||
gpio_free(NET2BIG_GPIO_SATA1_BLUE_LED);
|
||||
}
|
||||
if (err)
|
||||
pr_err("net2big: failed to setup SATA1 blue LED GPIO\n");
|
||||
|
||||
platform_device_register(&net2big_gpio_leds);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO keys
|
||||
****************************************************************************/
|
||||
|
||||
#define NET2BIG_GPIO_PUSH_BUTTON 18
|
||||
#define NET2BIG_GPIO_POWER_SWITCH_ON 8
|
||||
#define NET2BIG_GPIO_POWER_SWITCH_OFF 9
|
||||
|
||||
#define NET2BIG_SWITCH_POWER_ON 0x1
|
||||
#define NET2BIG_SWITCH_POWER_OFF 0x2
|
||||
|
||||
static struct gpio_keys_button net2big_buttons[] = {
|
||||
{
|
||||
.type = EV_SW,
|
||||
.code = NET2BIG_SWITCH_POWER_OFF,
|
||||
.gpio = NET2BIG_GPIO_POWER_SWITCH_OFF,
|
||||
.desc = "Power rocker switch (auto|off)",
|
||||
.active_low = 0,
|
||||
},
|
||||
{
|
||||
.type = EV_SW,
|
||||
.code = NET2BIG_SWITCH_POWER_ON,
|
||||
.gpio = NET2BIG_GPIO_POWER_SWITCH_ON,
|
||||
.desc = "Power rocker switch (on|auto)",
|
||||
.active_low = 0,
|
||||
},
|
||||
{
|
||||
.type = EV_KEY,
|
||||
.code = KEY_POWER,
|
||||
.gpio = NET2BIG_GPIO_PUSH_BUTTON,
|
||||
.desc = "Front Push Button",
|
||||
.active_low = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data net2big_button_data = {
|
||||
.buttons = net2big_buttons,
|
||||
.nbuttons = ARRAY_SIZE(net2big_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device net2big_gpio_buttons = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &net2big_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
|
||||
static unsigned int net2big_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* Raid mode (bit 0) */
|
||||
MPP1_GPIO, /* USB port 2 fuse (0 = Fail, 1 = Ok) */
|
||||
MPP2_GPIO, /* Raid mode (bit 1) */
|
||||
MPP3_GPIO, /* Board ID (bit 0) */
|
||||
MPP4_GPIO, /* Fan activity (0 = Off, 1 = On) */
|
||||
MPP5_GPIO, /* Fan fail detection */
|
||||
MPP6_GPIO, /* Red front LED (0 = Off, 1 = On) */
|
||||
MPP7_GPIO, /* Disable initial blinking on front LED */
|
||||
MPP8_GPIO, /* Rear power switch (on|auto) */
|
||||
MPP9_GPIO, /* Rear power switch (auto|off) */
|
||||
MPP10_GPIO, /* SATA 1 red LED (0 = Off, 1 = On) */
|
||||
MPP11_GPIO, /* SATA 0 red LED (0 = Off, 1 = On) */
|
||||
MPP12_GPIO, /* Board ID (bit 1) */
|
||||
MPP13_GPIO, /* SATA 1 blue LED blink control */
|
||||
MPP14_SATA_LED,
|
||||
MPP15_SATA_LED,
|
||||
MPP16_GPIO, /* Blue front LED control */
|
||||
MPP17_GPIO, /* SATA 0 blue LED blink control */
|
||||
MPP18_GPIO, /* Front button (0 = Released, 1 = Pushed ) */
|
||||
MPP19_GPIO, /* SATA{0,1} power On/Off request */
|
||||
0,
|
||||
/* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
|
||||
/* 23: SATA 0 power status */
|
||||
/* 24: Board power off */
|
||||
/* 25: SATA 1 power status */
|
||||
};
|
||||
|
||||
#define NET2BIG_GPIO_POWER_OFF 24
|
||||
|
||||
static void net2big_power_off(void)
|
||||
{
|
||||
gpio_set_value(NET2BIG_GPIO_POWER_OFF, 1);
|
||||
}
|
||||
|
||||
static void __init net2big_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(net2big_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_ehci1_init();
|
||||
orion5x_eth_init(&net2big_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_uart0_init();
|
||||
orion5x_xor_init();
|
||||
|
||||
net2big_sata_power_init();
|
||||
orion5x_sata_init(&net2big_sata_data);
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
NET2BIG_NOR_BOOT_BASE,
|
||||
NET2BIG_NOR_BOOT_SIZE);
|
||||
platform_device_register(&net2big_nor_flash);
|
||||
|
||||
platform_device_register(&net2big_gpio_buttons);
|
||||
net2big_gpio_leds_init();
|
||||
|
||||
i2c_register_board_info(0, net2big_i2c_devices,
|
||||
ARRAY_SIZE(net2big_i2c_devices));
|
||||
|
||||
orion_gpio_set_valid(NET2BIG_GPIO_POWER_OFF, 1);
|
||||
|
||||
if (gpio_request(NET2BIG_GPIO_POWER_OFF, "power-off") == 0 &&
|
||||
gpio_direction_output(NET2BIG_GPIO_POWER_OFF, 0) == 0)
|
||||
pm_power_off = net2big_power_off;
|
||||
else
|
||||
pr_err("net2big: failed to configure power-off GPIO\n");
|
||||
|
||||
pr_notice("net2big: Flash writing is not yet supported.\n");
|
||||
}
|
||||
|
||||
/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
|
||||
MACHINE_START(NET2BIG, "LaCie 2Big Network")
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = net2big_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
||||
|
587
arch/arm/mach-orion5x/pci.c
Normal file
587
arch/arm/mach-orion5x/pci.c
Normal file
|
@ -0,0 +1,587 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/pci.c
|
||||
*
|
||||
* PCI and PCIe functions for Marvell Orion System On Chip
|
||||
*
|
||||
* Maintainer: Tzachi Perelstein <tzachi@marvell.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mbus.h>
|
||||
#include <video/vga.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <plat/pcie.h>
|
||||
#include <plat/addr-map.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include "common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Orion has one PCIe controller and one PCI controller.
|
||||
*
|
||||
* Note1: The local PCIe bus number is '0'. The local PCI bus number
|
||||
* follows the scanned PCIe bridged busses, if any.
|
||||
*
|
||||
* Note2: It is possible for PCI/PCIe agents to access many subsystem's
|
||||
* space, by configuring BARs and Address Decode Windows, e.g. flashes on
|
||||
* device bus, Orion registers, etc. However this code only enable the
|
||||
* access to DDR banks.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* PCIe controller
|
||||
****************************************************************************/
|
||||
#define PCIE_BASE (ORION5X_PCIE_VIRT_BASE)
|
||||
|
||||
void __init orion5x_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)
|
||||
{
|
||||
/*
|
||||
* Don't go out when trying to access --
|
||||
* 1. nonexisting device on local bus
|
||||
* 2. where there's no device connected (no link)
|
||||
*/
|
||||
if (bus == 0 && dev == 0)
|
||||
return 1;
|
||||
|
||||
if (!orion_pcie_link_up(PCIE_BASE))
|
||||
return 0;
|
||||
|
||||
if (bus == 0 && dev != 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PCIe config cycles are done by programming the PCIE_CONF_ADDR register
|
||||
* and then reading the PCIE_CONF_DATA register. Need to make sure these
|
||||
* transactions are atomic.
|
||||
*/
|
||||
static DEFINE_SPINLOCK(orion5x_pcie_lock);
|
||||
|
||||
static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
|
||||
int size, u32 *val)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
|
||||
*val = 0xffffffff;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&orion5x_pcie_lock, flags);
|
||||
ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
|
||||
spin_unlock_irqrestore(&orion5x_pcie_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pcie_rd_conf_wa(struct pci_bus *bus, u32 devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
|
||||
*val = 0xffffffff;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*
|
||||
* We only support access to the non-extended configuration
|
||||
* space when using the WA access method (or we would have to
|
||||
* sacrifice 256M of CPU virtual address space.)
|
||||
*/
|
||||
if (where >= 0x100) {
|
||||
*val = 0xffffffff;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
ret = orion_pcie_rd_conf_wa(ORION5X_PCIE_WA_VIRT_BASE,
|
||||
bus, devfn, where, size, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
spin_lock_irqsave(&orion5x_pcie_lock, flags);
|
||||
ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
|
||||
spin_unlock_irqrestore(&orion5x_pcie_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct pci_ops pcie_ops = {
|
||||
.read = pcie_rd_conf,
|
||||
.write = pcie_wr_conf,
|
||||
};
|
||||
|
||||
|
||||
static int __init pcie_setup(struct pci_sys_data *sys)
|
||||
{
|
||||
struct resource *res;
|
||||
int dev;
|
||||
|
||||
/*
|
||||
* Generic PCIe unit setup.
|
||||
*/
|
||||
orion_pcie_setup(PCIE_BASE);
|
||||
|
||||
/*
|
||||
* Check whether to apply Orion-1/Orion-NAS PCIe config
|
||||
* read transaction workaround.
|
||||
*/
|
||||
dev = orion_pcie_dev_id(PCIE_BASE);
|
||||
if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
|
||||
printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config "
|
||||
"read transaction workaround\n");
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_PCIE_WA_TARGET,
|
||||
ORION_MBUS_PCIE_WA_ATTR,
|
||||
ORION5X_PCIE_WA_PHYS_BASE,
|
||||
ORION5X_PCIE_WA_SIZE);
|
||||
pcie_ops.read = pcie_rd_conf_wa;
|
||||
}
|
||||
|
||||
pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCIE_IO_PHYS_BASE);
|
||||
|
||||
/*
|
||||
* Request resources.
|
||||
*/
|
||||
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
|
||||
if (!res)
|
||||
panic("pcie_setup unable to alloc resources");
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
*/
|
||||
res->name = "PCIe Memory Space";
|
||||
res->flags = IORESOURCE_MEM;
|
||||
res->start = ORION5X_PCIE_MEM_PHYS_BASE;
|
||||
res->end = res->start + ORION5X_PCIE_MEM_SIZE - 1;
|
||||
if (request_resource(&iomem_resource, res))
|
||||
panic("Request PCIe Memory resource failed\n");
|
||||
pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* PCI controller
|
||||
****************************************************************************/
|
||||
#define ORION5X_PCI_REG(x) (ORION5X_PCI_VIRT_BASE + (x))
|
||||
#define PCI_MODE ORION5X_PCI_REG(0xd00)
|
||||
#define PCI_CMD ORION5X_PCI_REG(0xc00)
|
||||
#define PCI_P2P_CONF ORION5X_PCI_REG(0x1d14)
|
||||
#define PCI_CONF_ADDR ORION5X_PCI_REG(0xc78)
|
||||
#define PCI_CONF_DATA ORION5X_PCI_REG(0xc7c)
|
||||
|
||||
/*
|
||||
* PCI_MODE bits
|
||||
*/
|
||||
#define PCI_MODE_64BIT (1 << 2)
|
||||
#define PCI_MODE_PCIX ((1 << 4) | (1 << 5))
|
||||
|
||||
/*
|
||||
* PCI_CMD bits
|
||||
*/
|
||||
#define PCI_CMD_HOST_REORDER (1 << 29)
|
||||
|
||||
/*
|
||||
* PCI_P2P_CONF bits
|
||||
*/
|
||||
#define PCI_P2P_BUS_OFFS 16
|
||||
#define PCI_P2P_BUS_MASK (0xff << PCI_P2P_BUS_OFFS)
|
||||
#define PCI_P2P_DEV_OFFS 24
|
||||
#define PCI_P2P_DEV_MASK (0x1f << PCI_P2P_DEV_OFFS)
|
||||
|
||||
/*
|
||||
* PCI_CONF_ADDR bits
|
||||
*/
|
||||
#define PCI_CONF_REG(reg) ((reg) & 0xfc)
|
||||
#define PCI_CONF_FUNC(func) (((func) & 0x3) << 8)
|
||||
#define PCI_CONF_DEV(dev) (((dev) & 0x1f) << 11)
|
||||
#define PCI_CONF_BUS(bus) (((bus) & 0xff) << 16)
|
||||
#define PCI_CONF_ADDR_EN (1 << 31)
|
||||
|
||||
/*
|
||||
* Internal configuration space
|
||||
*/
|
||||
#define PCI_CONF_FUNC_STAT_CMD 0
|
||||
#define PCI_CONF_REG_STAT_CMD 4
|
||||
#define PCIX_STAT 0x64
|
||||
#define PCIX_STAT_BUS_OFFS 8
|
||||
#define PCIX_STAT_BUS_MASK (0xff << PCIX_STAT_BUS_OFFS)
|
||||
|
||||
/*
|
||||
* PCI Address Decode Windows registers
|
||||
*/
|
||||
#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \
|
||||
((n) == 1) ? ORION5X_PCI_REG(0xd08) : \
|
||||
((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \
|
||||
((n) == 3) ? ORION5X_PCI_REG(0xd0c) : NULL)
|
||||
#define PCI_BAR_REMAP_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \
|
||||
((n) == 1) ? ORION5X_PCI_REG(0xd48) : \
|
||||
((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \
|
||||
((n) == 3) ? ORION5X_PCI_REG(0xd4c) : NULL)
|
||||
#define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c)
|
||||
#define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c)
|
||||
|
||||
/*
|
||||
* PCI configuration helpers for BAR settings
|
||||
*/
|
||||
#define PCI_CONF_FUNC_BAR_CS(n) ((n) >> 1)
|
||||
#define PCI_CONF_REG_BAR_LO_CS(n) (((n) & 1) ? 0x18 : 0x10)
|
||||
#define PCI_CONF_REG_BAR_HI_CS(n) (((n) & 1) ? 0x1c : 0x14)
|
||||
|
||||
/*
|
||||
* PCI config cycles are done by programming the PCI_CONF_ADDR register
|
||||
* and then reading the PCI_CONF_DATA register. Need to make sure these
|
||||
* transactions are atomic.
|
||||
*/
|
||||
static DEFINE_SPINLOCK(orion5x_pci_lock);
|
||||
|
||||
static int orion5x_pci_cardbus_mode;
|
||||
|
||||
static int orion5x_pci_local_bus_nr(void)
|
||||
{
|
||||
u32 conf = readl(PCI_P2P_CONF);
|
||||
return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
|
||||
}
|
||||
|
||||
static int orion5x_pci_hw_rd_conf(int bus, int dev, u32 func,
|
||||
u32 where, u32 size, u32 *val)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&orion5x_pci_lock, flags);
|
||||
|
||||
writel(PCI_CONF_BUS(bus) |
|
||||
PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
|
||||
PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR);
|
||||
|
||||
*val = readl(PCI_CONF_DATA);
|
||||
|
||||
if (size == 1)
|
||||
*val = (*val >> (8*(where & 0x3))) & 0xff;
|
||||
else if (size == 2)
|
||||
*val = (*val >> (8*(where & 0x3))) & 0xffff;
|
||||
|
||||
spin_unlock_irqrestore(&orion5x_pci_lock, flags);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func,
|
||||
u32 where, u32 size, u32 val)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = PCIBIOS_SUCCESSFUL;
|
||||
|
||||
spin_lock_irqsave(&orion5x_pci_lock, flags);
|
||||
|
||||
writel(PCI_CONF_BUS(bus) |
|
||||
PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
|
||||
PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR);
|
||||
|
||||
if (size == 4) {
|
||||
__raw_writel(val, PCI_CONF_DATA);
|
||||
} else if (size == 2) {
|
||||
__raw_writew(val, PCI_CONF_DATA + (where & 0x3));
|
||||
} else if (size == 1) {
|
||||
__raw_writeb(val, PCI_CONF_DATA + (where & 0x3));
|
||||
} else {
|
||||
ret = PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&orion5x_pci_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int orion5x_pci_valid_config(int bus, u32 devfn)
|
||||
{
|
||||
if (bus == orion5x_pci_local_bus_nr()) {
|
||||
/*
|
||||
* Don't go out for local device
|
||||
*/
|
||||
if (PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* When the PCI signals are directly connected to a
|
||||
* Cardbus slot, ignore all but device IDs 0 and 1.
|
||||
*/
|
||||
if (orion5x_pci_cardbus_mode && PCI_SLOT(devfn) > 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn,
|
||||
int where, int size, u32 *val)
|
||||
{
|
||||
if (!orion5x_pci_valid_config(bus->number, devfn)) {
|
||||
*val = 0xffffffff;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return orion5x_pci_hw_rd_conf(bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), where, size, val);
|
||||
}
|
||||
|
||||
static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn,
|
||||
int where, int size, u32 val)
|
||||
{
|
||||
if (!orion5x_pci_valid_config(bus->number, devfn))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
|
||||
PCI_FUNC(devfn), where, size, val);
|
||||
}
|
||||
|
||||
static struct pci_ops pci_ops = {
|
||||
.read = orion5x_pci_rd_conf,
|
||||
.write = orion5x_pci_wr_conf,
|
||||
};
|
||||
|
||||
static void __init orion5x_pci_set_bus_nr(int nr)
|
||||
{
|
||||
u32 p2p = readl(PCI_P2P_CONF);
|
||||
|
||||
if (readl(PCI_MODE) & PCI_MODE_PCIX) {
|
||||
/*
|
||||
* PCI-X mode
|
||||
*/
|
||||
u32 pcix_status, bus, dev;
|
||||
bus = (p2p & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS;
|
||||
dev = (p2p & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS;
|
||||
orion5x_pci_hw_rd_conf(bus, dev, 0, PCIX_STAT, 4, &pcix_status);
|
||||
pcix_status &= ~PCIX_STAT_BUS_MASK;
|
||||
pcix_status |= (nr << PCIX_STAT_BUS_OFFS);
|
||||
orion5x_pci_hw_wr_conf(bus, dev, 0, PCIX_STAT, 4, pcix_status);
|
||||
} else {
|
||||
/*
|
||||
* PCI Conventional mode
|
||||
*/
|
||||
p2p &= ~PCI_P2P_BUS_MASK;
|
||||
p2p |= (nr << PCI_P2P_BUS_OFFS);
|
||||
writel(p2p, PCI_P2P_CONF);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init orion5x_pci_master_slave_enable(void)
|
||||
{
|
||||
int bus_nr, func, reg;
|
||||
u32 val;
|
||||
|
||||
bus_nr = orion5x_pci_local_bus_nr();
|
||||
func = PCI_CONF_FUNC_STAT_CMD;
|
||||
reg = PCI_CONF_REG_STAT_CMD;
|
||||
orion5x_pci_hw_rd_conf(bus_nr, 0, func, reg, 4, &val);
|
||||
val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
||||
orion5x_pci_hw_wr_conf(bus_nr, 0, func, reg, 4, val | 0x7);
|
||||
}
|
||||
|
||||
static void __init orion5x_setup_pci_wins(void)
|
||||
{
|
||||
const struct mbus_dram_target_info *dram = mv_mbus_dram_info();
|
||||
u32 win_enable;
|
||||
int bus;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* First, disable windows.
|
||||
*/
|
||||
win_enable = 0xffffffff;
|
||||
writel(win_enable, PCI_BAR_ENABLE);
|
||||
|
||||
/*
|
||||
* Setup windows for DDR banks.
|
||||
*/
|
||||
bus = orion5x_pci_local_bus_nr();
|
||||
|
||||
for (i = 0; i < dram->num_cs; i++) {
|
||||
const struct mbus_dram_window *cs = dram->cs + i;
|
||||
u32 func = PCI_CONF_FUNC_BAR_CS(cs->cs_index);
|
||||
u32 reg;
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* Write DRAM bank base address register.
|
||||
*/
|
||||
reg = PCI_CONF_REG_BAR_LO_CS(cs->cs_index);
|
||||
orion5x_pci_hw_rd_conf(bus, 0, func, reg, 4, &val);
|
||||
val = (cs->base & 0xfffff000) | (val & 0xfff);
|
||||
orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, val);
|
||||
|
||||
/*
|
||||
* Write DRAM bank size register.
|
||||
*/
|
||||
reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index);
|
||||
orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0);
|
||||
writel((cs->size - 1) & 0xfffff000,
|
||||
PCI_BAR_SIZE_DDR_CS(cs->cs_index));
|
||||
writel(cs->base & 0xfffff000,
|
||||
PCI_BAR_REMAP_DDR_CS(cs->cs_index));
|
||||
|
||||
/*
|
||||
* Enable decode window for this chip select.
|
||||
*/
|
||||
win_enable &= ~(1 << cs->cs_index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-enable decode windows.
|
||||
*/
|
||||
writel(win_enable, PCI_BAR_ENABLE);
|
||||
|
||||
/*
|
||||
* Disable automatic update of address remapping when writing to BARs.
|
||||
*/
|
||||
orion5x_setbits(PCI_ADDR_DECODE_CTRL, 1);
|
||||
}
|
||||
|
||||
static int __init pci_setup(struct pci_sys_data *sys)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
/*
|
||||
* Point PCI unit MBUS decode windows to DRAM space.
|
||||
*/
|
||||
orion5x_setup_pci_wins();
|
||||
|
||||
/*
|
||||
* Master + Slave enable
|
||||
*/
|
||||
orion5x_pci_master_slave_enable();
|
||||
|
||||
/*
|
||||
* Force ordering
|
||||
*/
|
||||
orion5x_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
|
||||
|
||||
pci_ioremap_io(sys->busnr * SZ_64K, ORION5X_PCI_IO_PHYS_BASE);
|
||||
|
||||
/*
|
||||
* Request resources
|
||||
*/
|
||||
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
|
||||
if (!res)
|
||||
panic("pci_setup unable to alloc resources");
|
||||
|
||||
/*
|
||||
* IORESOURCE_MEM
|
||||
*/
|
||||
res->name = "PCI Memory Space";
|
||||
res->flags = IORESOURCE_MEM;
|
||||
res->start = ORION5X_PCI_MEM_PHYS_BASE;
|
||||
res->end = res->start + ORION5X_PCI_MEM_SIZE - 1;
|
||||
if (request_resource(&iomem_resource, res))
|
||||
panic("Request PCI Memory resource failed\n");
|
||||
pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* General PCIe + PCI
|
||||
****************************************************************************/
|
||||
static void rc_pci_fixup(struct pci_dev *dev)
|
||||
{
|
||||
/*
|
||||
* Prevent enumeration of root complex.
|
||||
*/
|
||||
if (dev->bus->parent == NULL && dev->devfn == 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
dev->resource[i].start = 0;
|
||||
dev->resource[i].end = 0;
|
||||
dev->resource[i].flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
|
||||
|
||||
static int orion5x_pci_disabled __initdata;
|
||||
|
||||
void __init orion5x_pci_disable(void)
|
||||
{
|
||||
orion5x_pci_disabled = 1;
|
||||
}
|
||||
|
||||
void __init orion5x_pci_set_cardbus_mode(void)
|
||||
{
|
||||
orion5x_pci_cardbus_mode = 1;
|
||||
}
|
||||
|
||||
int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
vga_base = ORION5X_PCIE_MEM_PHYS_BASE;
|
||||
|
||||
if (nr == 0) {
|
||||
orion_pcie_set_local_bus_nr(PCIE_BASE, sys->busnr);
|
||||
ret = pcie_setup(sys);
|
||||
} else if (nr == 1 && !orion5x_pci_disabled) {
|
||||
orion5x_pci_set_bus_nr(sys->busnr);
|
||||
ret = pci_setup(sys);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
struct pci_bus *bus;
|
||||
|
||||
if (nr == 0) {
|
||||
bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
|
||||
&sys->resources);
|
||||
} else if (nr == 1 && !orion5x_pci_disabled) {
|
||||
bus = pci_scan_root_bus(NULL, sys->busnr, &pci_ops, sys,
|
||||
&sys->resources);
|
||||
} else {
|
||||
bus = NULL;
|
||||
BUG();
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
||||
int __init orion5x_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
int bus = dev->bus->number;
|
||||
|
||||
/*
|
||||
* PCIe endpoint?
|
||||
*/
|
||||
if (orion5x_pci_disabled || bus < orion5x_pci_local_bus_nr())
|
||||
return IRQ_ORION5X_PCIE0_INT;
|
||||
|
||||
return -1;
|
||||
}
|
179
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
Normal file
179
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
|
||||
*
|
||||
* Marvell Orion-VoIP FXO 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/gpio.h>
|
||||
#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/ethtool.h>
|
||||
#include <net/dsa.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"
|
||||
|
||||
/*****************************************************************************
|
||||
* RD-88F5181L FXO Info
|
||||
****************************************************************************/
|
||||
/*
|
||||
* 8M NOR flash Device bus boot chip select
|
||||
*/
|
||||
#define RD88F5181L_FXO_NOR_BOOT_BASE 0xff800000
|
||||
#define RD88F5181L_FXO_NOR_BOOT_SIZE SZ_8M
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* 8M NOR Flash on Device bus Boot chip select
|
||||
****************************************************************************/
|
||||
static struct physmap_flash_data rd88f5181l_fxo_nor_boot_flash_data = {
|
||||
.width = 1,
|
||||
};
|
||||
|
||||
static struct resource rd88f5181l_fxo_nor_boot_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = RD88F5181L_FXO_NOR_BOOT_BASE,
|
||||
.end = RD88F5181L_FXO_NOR_BOOT_BASE +
|
||||
RD88F5181L_FXO_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device rd88f5181l_fxo_nor_boot_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &rd88f5181l_fxo_nor_boot_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &rd88f5181l_fxo_nor_boot_flash_resource,
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int rd88f5181l_fxo_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* LED1 CardBus LED (front panel) */
|
||||
MPP1_GPIO, /* PCI_intA */
|
||||
MPP2_GPIO, /* Hard Reset / Factory Init*/
|
||||
MPP3_GPIO, /* FXS or DAA select */
|
||||
MPP4_GPIO, /* LED6 - phone LED (front panel) */
|
||||
MPP5_GPIO, /* LED5 - phone LED (front panel) */
|
||||
MPP6_PCI_CLK, /* CPU PCI refclk */
|
||||
MPP7_PCI_CLK, /* PCI/PCIe refclk */
|
||||
MPP8_GPIO, /* CardBus reset */
|
||||
MPP9_GPIO, /* GE_RXERR */
|
||||
MPP10_GPIO, /* LED2 MiniPCI LED (front panel) */
|
||||
MPP11_GPIO, /* Lifeline control */
|
||||
MPP12_GIGE, /* GE_TXD[4] */
|
||||
MPP13_GIGE, /* GE_TXD[5] */
|
||||
MPP14_GIGE, /* GE_TXD[6] */
|
||||
MPP15_GIGE, /* GE_TXD[7] */
|
||||
MPP16_GIGE, /* GE_RXD[4] */
|
||||
MPP17_GIGE, /* GE_RXD[5] */
|
||||
MPP18_GIGE, /* GE_RXD[6] */
|
||||
MPP19_GIGE, /* GE_RXD[7] */
|
||||
0,
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_NONE,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static struct dsa_chip_data rd88f5181l_fxo_switch_chip_data = {
|
||||
.port_names[0] = "lan2",
|
||||
.port_names[1] = "lan1",
|
||||
.port_names[2] = "wan",
|
||||
.port_names[3] = "cpu",
|
||||
.port_names[5] = "lan4",
|
||||
.port_names[7] = "lan3",
|
||||
};
|
||||
|
||||
static struct dsa_platform_data rd88f5181l_fxo_switch_plat_data = {
|
||||
.nr_chips = 1,
|
||||
.chip = &rd88f5181l_fxo_switch_chip_data,
|
||||
};
|
||||
|
||||
static void __init rd88f5181l_fxo_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(rd88f5181l_fxo_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_eth_init(&rd88f5181l_fxo_eth_data);
|
||||
orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
|
||||
orion5x_uart0_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
RD88F5181L_FXO_NOR_BOOT_BASE,
|
||||
RD88F5181L_FXO_NOR_BOOT_SIZE);
|
||||
platform_device_register(&rd88f5181l_fxo_nor_boot_flash);
|
||||
}
|
||||
|
||||
static int __init
|
||||
rd88f5181l_fxo_pci_map_irq(const 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;
|
||||
|
||||
/*
|
||||
* Mini-PCI / Cardbus slot.
|
||||
*/
|
||||
return gpio_to_irq(1);
|
||||
}
|
||||
|
||||
static struct hw_pci rd88f5181l_fxo_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = rd88f5181l_fxo_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init rd88f5181l_fxo_pci_init(void)
|
||||
{
|
||||
if (machine_is_rd88f5181l_fxo()) {
|
||||
orion5x_pci_set_cardbus_mode();
|
||||
pci_common_init(&rd88f5181l_fxo_pci);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(rd88f5181l_fxo_pci_init);
|
||||
|
||||
MACHINE_START(RD88F5181L_FXO, "Marvell Orion-VoIP FXO Reference Design")
|
||||
/* Maintainer: Nicolas Pitre <nico@marvell.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = rd88f5181l_fxo_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
191
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
Normal file
191
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
|
||||
*
|
||||
* Marvell Orion-VoIP 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/gpio.h>
|
||||
#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/ethtool.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <net/dsa.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"
|
||||
|
||||
/*****************************************************************************
|
||||
* RD-88F5181L GE Info
|
||||
****************************************************************************/
|
||||
/*
|
||||
* 16M NOR flash Device bus boot chip select
|
||||
*/
|
||||
#define RD88F5181L_GE_NOR_BOOT_BASE 0xff000000
|
||||
#define RD88F5181L_GE_NOR_BOOT_SIZE SZ_16M
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* 16M NOR Flash on Device bus Boot chip select
|
||||
****************************************************************************/
|
||||
static struct physmap_flash_data rd88f5181l_ge_nor_boot_flash_data = {
|
||||
.width = 1,
|
||||
};
|
||||
|
||||
static struct resource rd88f5181l_ge_nor_boot_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = RD88F5181L_GE_NOR_BOOT_BASE,
|
||||
.end = RD88F5181L_GE_NOR_BOOT_BASE +
|
||||
RD88F5181L_GE_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device rd88f5181l_ge_nor_boot_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &rd88f5181l_ge_nor_boot_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &rd88f5181l_ge_nor_boot_flash_resource,
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int rd88f5181l_ge_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* LED1 */
|
||||
MPP1_GPIO, /* LED5 */
|
||||
MPP2_GPIO, /* LED4 */
|
||||
MPP3_GPIO, /* LED3 */
|
||||
MPP4_GPIO, /* PCI_intA */
|
||||
MPP5_GPIO, /* RTC interrupt */
|
||||
MPP6_PCI_CLK, /* CPU PCI refclk */
|
||||
MPP7_PCI_CLK, /* PCI/PCIe refclk */
|
||||
MPP8_GPIO, /* 88e6131 interrupt */
|
||||
MPP9_GPIO, /* GE_RXERR */
|
||||
MPP10_GPIO, /* PCI_intB */
|
||||
MPP11_GPIO, /* LED2 */
|
||||
MPP12_GIGE, /* GE_TXD[4] */
|
||||
MPP13_GIGE, /* GE_TXD[5] */
|
||||
MPP14_GIGE, /* GE_TXD[6] */
|
||||
MPP15_GIGE, /* GE_TXD[7] */
|
||||
MPP16_GIGE, /* GE_RXD[4] */
|
||||
MPP17_GIGE, /* GE_RXD[5] */
|
||||
MPP18_GIGE, /* GE_RXD[6] */
|
||||
MPP19_GIGE, /* GE_RXD[7] */
|
||||
0,
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_NONE,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static struct dsa_chip_data rd88f5181l_ge_switch_chip_data = {
|
||||
.port_names[0] = "lan2",
|
||||
.port_names[1] = "lan1",
|
||||
.port_names[2] = "wan",
|
||||
.port_names[3] = "cpu",
|
||||
.port_names[5] = "lan4",
|
||||
.port_names[7] = "lan3",
|
||||
};
|
||||
|
||||
static struct dsa_platform_data rd88f5181l_ge_switch_plat_data = {
|
||||
.nr_chips = 1,
|
||||
.chip = &rd88f5181l_ge_switch_chip_data,
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
|
||||
I2C_BOARD_INFO("ds1338", 0x68),
|
||||
};
|
||||
|
||||
static void __init rd88f5181l_ge_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(rd88f5181l_ge_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_eth_init(&rd88f5181l_ge_eth_data);
|
||||
orion5x_eth_switch_init(&rd88f5181l_ge_switch_plat_data,
|
||||
gpio_to_irq(8));
|
||||
orion5x_i2c_init();
|
||||
orion5x_uart0_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
RD88F5181L_GE_NOR_BOOT_BASE,
|
||||
RD88F5181L_GE_NOR_BOOT_SIZE);
|
||||
platform_device_register(&rd88f5181l_ge_nor_boot_flash);
|
||||
|
||||
i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1);
|
||||
}
|
||||
|
||||
static int __init
|
||||
rd88f5181l_ge_pci_map_irq(const 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;
|
||||
|
||||
/*
|
||||
* Cardbus slot.
|
||||
*/
|
||||
if (pin == 1)
|
||||
return gpio_to_irq(4);
|
||||
else
|
||||
return gpio_to_irq(10);
|
||||
}
|
||||
|
||||
static struct hw_pci rd88f5181l_ge_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = rd88f5181l_ge_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init rd88f5181l_ge_pci_init(void)
|
||||
{
|
||||
if (machine_is_rd88f5181l_ge()) {
|
||||
orion5x_pci_set_cardbus_mode();
|
||||
pci_common_init(&rd88f5181l_ge_pci);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(rd88f5181l_ge_pci_init);
|
||||
|
||||
MACHINE_START(RD88F5181L_GE, "Marvell Orion-VoIP GE Reference Design")
|
||||
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = rd88f5181l_ge_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
290
arch/arm/mach-orion5x/rd88f5182-setup.c
Normal file
290
arch/arm/mach-orion5x/rd88f5182-setup.c
Normal file
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/rd88f5182-setup.c
|
||||
*
|
||||
* Marvell Orion-NAS Reference Design Setup
|
||||
*
|
||||
* Maintainer: Ronen Shitrit <rshitrit@marvell.com>
|
||||
*
|
||||
* 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/gpio.h>
|
||||
#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/ata_platform.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/leds.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"
|
||||
|
||||
/*****************************************************************************
|
||||
* RD-88F5182 Info
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* 512K NOR flash Device bus boot chip select
|
||||
*/
|
||||
|
||||
#define RD88F5182_NOR_BOOT_BASE 0xf4000000
|
||||
#define RD88F5182_NOR_BOOT_SIZE SZ_512K
|
||||
|
||||
/*
|
||||
* 16M NOR flash on Device bus chip select 1
|
||||
*/
|
||||
|
||||
#define RD88F5182_NOR_BASE 0xfc000000
|
||||
#define RD88F5182_NOR_SIZE SZ_16M
|
||||
|
||||
/*
|
||||
* PCI
|
||||
*/
|
||||
|
||||
#define RD88F5182_PCI_SLOT0_OFFS 7
|
||||
#define RD88F5182_PCI_SLOT0_IRQ_A_PIN 7
|
||||
#define RD88F5182_PCI_SLOT0_IRQ_B_PIN 6
|
||||
|
||||
/*****************************************************************************
|
||||
* 16M NOR Flash on Device bus CS1
|
||||
****************************************************************************/
|
||||
|
||||
static struct physmap_flash_data rd88f5182_nor_flash_data = {
|
||||
.width = 1,
|
||||
};
|
||||
|
||||
static struct resource rd88f5182_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = RD88F5182_NOR_BASE,
|
||||
.end = RD88F5182_NOR_BASE + RD88F5182_NOR_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device rd88f5182_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &rd88f5182_nor_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &rd88f5182_nor_flash_resource,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Use GPIO LED as CPU active indication
|
||||
****************************************************************************/
|
||||
|
||||
#define RD88F5182_GPIO_LED 0
|
||||
|
||||
static struct gpio_led rd88f5182_gpio_led_pins[] = {
|
||||
{
|
||||
.name = "rd88f5182:cpu",
|
||||
.default_trigger = "cpu0",
|
||||
.gpio = RD88F5182_GPIO_LED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data rd88f5182_gpio_led_data = {
|
||||
.leds = rd88f5182_gpio_led_pins,
|
||||
.num_leds = ARRAY_SIZE(rd88f5182_gpio_led_pins),
|
||||
};
|
||||
|
||||
static struct platform_device rd88f5182_gpio_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &rd88f5182_gpio_led_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* PCI
|
||||
****************************************************************************/
|
||||
|
||||
static void __init rd88f5182_pci_preinit(void)
|
||||
{
|
||||
int pin;
|
||||
|
||||
/*
|
||||
* Configure PCI GPIO IRQ pins
|
||||
*/
|
||||
pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
|
||||
if (gpio_request(pin, "PCI IntA") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit failed to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
gpio_free(pin);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit failed to request gpio %d\n", pin);
|
||||
}
|
||||
|
||||
pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
|
||||
if (gpio_request(pin, "PCI IntB") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit failed to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
gpio_free(pin);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "rd88f5182_pci_preinit failed to gpio_request %d\n", pin);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init rd88f5182_pci_map_irq(const 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
|
||||
*/
|
||||
switch (slot - RD88F5182_PCI_SLOT0_OFFS) {
|
||||
case 0:
|
||||
if (pin == 1)
|
||||
return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_A_PIN);
|
||||
else
|
||||
return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_B_PIN);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct hw_pci rd88f5182_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.preinit = rd88f5182_pci_preinit,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = rd88f5182_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init rd88f5182_pci_init(void)
|
||||
{
|
||||
if (machine_is_rd88f5182())
|
||||
pci_common_init(&rd88f5182_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(rd88f5182_pci_init);
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
|
||||
static struct mv643xx_eth_platform_data rd88f5182_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* RTC DS1338 on I2C bus
|
||||
****************************************************************************/
|
||||
static struct i2c_board_info __initdata rd88f5182_i2c_rtc = {
|
||||
I2C_BOARD_INFO("ds1338", 0x68),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Sata
|
||||
****************************************************************************/
|
||||
static struct mv_sata_platform_data rd88f5182_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int rd88f5182_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* Debug Led */
|
||||
MPP1_GPIO, /* Reset Switch */
|
||||
MPP2_UNUSED,
|
||||
MPP3_GPIO, /* RTC Int */
|
||||
MPP4_GPIO,
|
||||
MPP5_GPIO,
|
||||
MPP6_GPIO, /* PCI_intA */
|
||||
MPP7_GPIO, /* PCI_intB */
|
||||
MPP8_UNUSED,
|
||||
MPP9_UNUSED,
|
||||
MPP10_UNUSED,
|
||||
MPP11_UNUSED,
|
||||
MPP12_SATA_LED, /* SATA 0 presence */
|
||||
MPP13_SATA_LED, /* SATA 1 presence */
|
||||
MPP14_SATA_LED, /* SATA 0 active */
|
||||
MPP15_SATA_LED, /* SATA 1 active */
|
||||
MPP16_UNUSED,
|
||||
MPP17_UNUSED,
|
||||
MPP18_UNUSED,
|
||||
MPP19_UNUSED,
|
||||
0,
|
||||
};
|
||||
|
||||
static void __init rd88f5182_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(rd88f5182_mpp_modes);
|
||||
|
||||
/*
|
||||
* MPP[20] PCI Clock to MV88F5182
|
||||
* MPP[21] PCI Clock to mini PCI CON11
|
||||
* MPP[22] USB 0 over current indication
|
||||
* MPP[23] USB 1 over current indication
|
||||
* MPP[24] USB 1 over current enable
|
||||
* MPP[25] USB 0 over current enable
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_ehci1_init();
|
||||
orion5x_eth_init(&rd88f5182_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_sata_init(&rd88f5182_sata_data);
|
||||
orion5x_uart0_init();
|
||||
orion5x_xor_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
RD88F5182_NOR_BOOT_BASE,
|
||||
RD88F5182_NOR_BOOT_SIZE);
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(1),
|
||||
ORION_MBUS_DEVBUS_ATTR(1),
|
||||
RD88F5182_NOR_BASE,
|
||||
RD88F5182_NOR_SIZE);
|
||||
platform_device_register(&rd88f5182_nor_flash);
|
||||
platform_device_register(&rd88f5182_gpio_leds);
|
||||
|
||||
i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
|
||||
}
|
||||
|
||||
MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
|
||||
/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = rd88f5182_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
129
arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
Normal file
129
arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* 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/gpio.h>
|
||||
#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/flash.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <net/dsa.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include "common.h"
|
||||
|
||||
static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
|
||||
.phy_addr = -1,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static struct dsa_chip_data rd88f6183ap_ge_switch_chip_data = {
|
||||
.port_names[0] = "lan1",
|
||||
.port_names[1] = "lan2",
|
||||
.port_names[2] = "lan3",
|
||||
.port_names[3] = "lan4",
|
||||
.port_names[4] = "wan",
|
||||
.port_names[5] = "cpu",
|
||||
};
|
||||
|
||||
static struct dsa_platform_data rd88f6183ap_ge_switch_plat_data = {
|
||||
.nr_chips = 1,
|
||||
.chip = &rd88f6183ap_ge_switch_chip_data,
|
||||
};
|
||||
|
||||
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);
|
||||
orion5x_eth_switch_init(&rd88f6183ap_ge_switch_plat_data,
|
||||
gpio_to_irq(3));
|
||||
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,
|
||||
.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> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = rd88f6183ap_ge_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
369
arch/arm/mach-orion5x/terastation_pro2-setup.c
Normal file
369
arch/arm/mach-orion5x/terastation_pro2-setup.c
Normal file
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* 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/gpio.h>
|
||||
#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/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
|
||||
|
||||
static 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) {
|
||||
irq_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(const 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,
|
||||
.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 unsigned int tsp2_mpp_modes[] __initdata = {
|
||||
MPP0_PCIE_RST_OUTn,
|
||||
MPP1_UNUSED,
|
||||
MPP2_UNUSED,
|
||||
MPP3_UNUSED,
|
||||
MPP4_NAND, /* BOOT NAND Flash REn */
|
||||
MPP5_NAND, /* BOOT NAND Flash WEn */
|
||||
MPP6_NAND, /* BOOT NAND Flash HREn[0] */
|
||||
MPP7_NAND, /* BOOT NAND Flash WEn[0] */
|
||||
MPP8_GPIO, /* MICON int */
|
||||
MPP9_GPIO, /* RTC int */
|
||||
MPP10_UNUSED,
|
||||
MPP11_GPIO, /* PCI Int A */
|
||||
MPP12_UNUSED,
|
||||
MPP13_GPIO, /* UPS on UART0 enable */
|
||||
MPP14_GPIO, /* UPS low battery detection */
|
||||
MPP15_UNUSED,
|
||||
MPP16_UART, /* UART1 RXD */
|
||||
MPP17_UART, /* UART1 TXD */
|
||||
MPP18_UART, /* UART1 CTSn */
|
||||
MPP19_UART, /* UART1 RTSn */
|
||||
0,
|
||||
};
|
||||
|
||||
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.
|
||||
*/
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
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_warn("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> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = tsp2_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
334
arch/arm/mach-orion5x/ts209-setup.c
Normal file
334
arch/arm/mach-orion5x/ts209-setup.c
Normal file
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
* QNAP TS-109/TS-209 Board Setup
|
||||
*
|
||||
* Maintainer: Byron Bradley <byron.bbradley@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
#include <linux/gpio.h>
|
||||
#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/mtd/nand.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/ata_platform.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"
|
||||
#include "tsx09-common.h"
|
||||
|
||||
#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
|
||||
#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M
|
||||
|
||||
/****************************************************************************
|
||||
* 8MiB NOR flash. The struct mtd_partition is not in the same order as the
|
||||
* partitions on the device because we want to keep compatibility with
|
||||
* existing QNAP firmware.
|
||||
*
|
||||
* Layout as used by QNAP:
|
||||
* [2] 0x00000000-0x00200000 : "Kernel"
|
||||
* [3] 0x00200000-0x00600000 : "RootFS1"
|
||||
* [4] 0x00600000-0x00700000 : "RootFS2"
|
||||
* [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
|
||||
* [5] 0x00760000-0x00780000 : "U-Boot Config"
|
||||
* [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
|
||||
***************************************************************************/
|
||||
static struct mtd_partition qnap_ts209_partitions[] = {
|
||||
{
|
||||
.name = "U-Boot",
|
||||
.size = 0x00080000,
|
||||
.offset = 0x00780000,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
}, {
|
||||
.name = "Kernel",
|
||||
.size = 0x00200000,
|
||||
.offset = 0,
|
||||
}, {
|
||||
.name = "RootFS1",
|
||||
.size = 0x00400000,
|
||||
.offset = 0x00200000,
|
||||
}, {
|
||||
.name = "RootFS2",
|
||||
.size = 0x00100000,
|
||||
.offset = 0x00600000,
|
||||
}, {
|
||||
.name = "U-Boot Config",
|
||||
.size = 0x00020000,
|
||||
.offset = 0x00760000,
|
||||
}, {
|
||||
.name = "NAS Config",
|
||||
.size = 0x00060000,
|
||||
.offset = 0x00700000,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data qnap_ts209_nor_flash_data = {
|
||||
.width = 1,
|
||||
.parts = qnap_ts209_partitions,
|
||||
.nr_parts = ARRAY_SIZE(qnap_ts209_partitions)
|
||||
};
|
||||
|
||||
static struct resource qnap_ts209_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = QNAP_TS209_NOR_BOOT_BASE,
|
||||
.end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device qnap_ts209_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &qnap_ts209_nor_flash_data,
|
||||
},
|
||||
.resource = &qnap_ts209_nor_flash_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* PCI
|
||||
****************************************************************************/
|
||||
|
||||
#define QNAP_TS209_PCI_SLOT0_OFFS 7
|
||||
#define QNAP_TS209_PCI_SLOT0_IRQ_PIN 6
|
||||
#define QNAP_TS209_PCI_SLOT1_IRQ_PIN 7
|
||||
|
||||
static void __init qnap_ts209_pci_preinit(void)
|
||||
{
|
||||
int pin;
|
||||
|
||||
/*
|
||||
* Configure PCI GPIO IRQ pins
|
||||
*/
|
||||
pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
|
||||
if (gpio_request(pin, "PCI Int1") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
|
||||
"set_irq_type pin %d\n", pin);
|
||||
gpio_free(pin);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
|
||||
"%d\n", pin);
|
||||
}
|
||||
|
||||
pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
|
||||
if (gpio_request(pin, "PCI Int2") == 0) {
|
||||
if (gpio_direction_input(pin) == 0) {
|
||||
irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
|
||||
} else {
|
||||
printk(KERN_ERR "qnap_ts209_pci_preinit failed "
|
||||
"to set_irq_type pin %d\n", pin);
|
||||
gpio_free(pin);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
|
||||
"%d\n", pin);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init qnap_ts209_pci_map_irq(const 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.
|
||||
*/
|
||||
switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) {
|
||||
case 0:
|
||||
return gpio_to_irq(QNAP_TS209_PCI_SLOT0_IRQ_PIN);
|
||||
case 1:
|
||||
return gpio_to_irq(QNAP_TS209_PCI_SLOT1_IRQ_PIN);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct hw_pci qnap_ts209_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.preinit = qnap_ts209_pci_preinit,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = qnap_ts209_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init qnap_ts209_pci_init(void)
|
||||
{
|
||||
if (machine_is_ts209())
|
||||
pci_common_init(&qnap_ts209_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(qnap_ts209_pci_init);
|
||||
|
||||
/*****************************************************************************
|
||||
* RTC S35390A on I2C bus
|
||||
****************************************************************************/
|
||||
|
||||
#define TS209_RTC_GPIO 3
|
||||
|
||||
static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
|
||||
I2C_BOARD_INFO("s35390a", 0x30),
|
||||
.irq = 0,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO Attached Keys
|
||||
* Power button is attached to the PIC microcontroller
|
||||
****************************************************************************/
|
||||
|
||||
#define QNAP_TS209_GPIO_KEY_MEDIA 1
|
||||
#define QNAP_TS209_GPIO_KEY_RESET 2
|
||||
|
||||
static struct gpio_keys_button qnap_ts209_buttons[] = {
|
||||
{
|
||||
.code = KEY_COPY,
|
||||
.gpio = QNAP_TS209_GPIO_KEY_MEDIA,
|
||||
.desc = "USB Copy Button",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.code = KEY_RESTART,
|
||||
.gpio = QNAP_TS209_GPIO_KEY_RESET,
|
||||
.desc = "Reset Button",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data qnap_ts209_button_data = {
|
||||
.buttons = qnap_ts209_buttons,
|
||||
.nbuttons = ARRAY_SIZE(qnap_ts209_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device qnap_ts209_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &qnap_ts209_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
static struct mv_sata_platform_data qnap_ts209_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int ts209_mpp_modes[] __initdata = {
|
||||
MPP0_UNUSED,
|
||||
MPP1_GPIO, /* USB copy button */
|
||||
MPP2_GPIO, /* Load defaults button */
|
||||
MPP3_GPIO, /* GPIO RTC */
|
||||
MPP4_UNUSED,
|
||||
MPP5_UNUSED,
|
||||
MPP6_GPIO, /* PCI Int A */
|
||||
MPP7_GPIO, /* PCI Int B */
|
||||
MPP8_UNUSED,
|
||||
MPP9_UNUSED,
|
||||
MPP10_UNUSED,
|
||||
MPP11_UNUSED,
|
||||
MPP12_SATA_LED, /* SATA 0 presence */
|
||||
MPP13_SATA_LED, /* SATA 1 presence */
|
||||
MPP14_SATA_LED, /* SATA 0 active */
|
||||
MPP15_SATA_LED, /* SATA 1 active */
|
||||
MPP16_UART, /* UART1 RXD */
|
||||
MPP17_UART, /* UART1 TXD */
|
||||
MPP18_GPIO, /* SW_RST */
|
||||
MPP19_UNUSED,
|
||||
0,
|
||||
};
|
||||
|
||||
static void __init qnap_ts209_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(ts209_mpp_modes);
|
||||
|
||||
/*
|
||||
* MPP[20] PCI clock 0
|
||||
* MPP[21] PCI clock 1
|
||||
* MPP[22] USB 0 over current
|
||||
* MPP[23-25] Reserved
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
QNAP_TS209_NOR_BOOT_BASE,
|
||||
QNAP_TS209_NOR_BOOT_SIZE);
|
||||
platform_device_register(&qnap_ts209_nor_flash);
|
||||
|
||||
orion5x_ehci0_init();
|
||||
orion5x_ehci1_init();
|
||||
qnap_tsx09_find_mac_addr(QNAP_TS209_NOR_BOOT_BASE +
|
||||
qnap_ts209_partitions[5].offset,
|
||||
qnap_ts209_partitions[5].size);
|
||||
orion5x_eth_init(&qnap_tsx09_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_sata_init(&qnap_ts209_sata_data);
|
||||
orion5x_uart0_init();
|
||||
orion5x_uart1_init();
|
||||
orion5x_xor_init();
|
||||
|
||||
platform_device_register(&qnap_ts209_button_device);
|
||||
|
||||
/* Get RTC IRQ and register the chip */
|
||||
if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) {
|
||||
if (gpio_direction_input(TS209_RTC_GPIO) == 0)
|
||||
qnap_ts209_i2c_rtc.irq = gpio_to_irq(TS209_RTC_GPIO);
|
||||
else
|
||||
gpio_free(TS209_RTC_GPIO);
|
||||
}
|
||||
if (qnap_ts209_i2c_rtc.irq == 0)
|
||||
pr_warn("qnap_ts209_init: failed to get RTC IRQ\n");
|
||||
i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
|
||||
|
||||
/* register tsx09 specific power-off method */
|
||||
pm_power_off = qnap_tsx09_power_off;
|
||||
}
|
||||
|
||||
MACHINE_START(TS209, "QNAP TS-109/TS-209")
|
||||
/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = qnap_ts209_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
323
arch/arm/mach-orion5x/ts409-setup.c
Normal file
323
arch/arm/mach-orion5x/ts409-setup.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* QNAP TS-409 Board Setup
|
||||
*
|
||||
* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com>
|
||||
*
|
||||
* Copyright (C) 2008 Sylver Bruneau <sylver.bruneau@gmail.com>
|
||||
* Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.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/gpio.h>
|
||||
#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/serial_reg.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"
|
||||
#include "tsx09-common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* QNAP TS-409 Info
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* QNAP TS-409 hardware :
|
||||
* - Marvell 88F5281-D0
|
||||
* - Marvell 88SX7042 SATA controller (PCIe)
|
||||
* - Marvell 88E1118 Gigabit Ethernet PHY
|
||||
* - RTC S35390A (@0x30) on I2C bus
|
||||
* - 8MB NOR flash
|
||||
* - 256MB of DDR-2 RAM
|
||||
*/
|
||||
|
||||
/*
|
||||
* 8MB NOR flash Device bus boot chip select
|
||||
*/
|
||||
|
||||
#define QNAP_TS409_NOR_BOOT_BASE 0xff800000
|
||||
#define QNAP_TS409_NOR_BOOT_SIZE SZ_8M
|
||||
|
||||
/****************************************************************************
|
||||
* 8MiB NOR flash. The struct mtd_partition is not in the same order as the
|
||||
* partitions on the device because we want to keep compatibility with
|
||||
* existing QNAP firmware.
|
||||
*
|
||||
* Layout as used by QNAP:
|
||||
* [2] 0x00000000-0x00200000 : "Kernel"
|
||||
* [3] 0x00200000-0x00600000 : "RootFS1"
|
||||
* [4] 0x00600000-0x00700000 : "RootFS2"
|
||||
* [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
|
||||
* [5] 0x00760000-0x00780000 : "U-Boot Config"
|
||||
* [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
|
||||
***************************************************************************/
|
||||
static struct mtd_partition qnap_ts409_partitions[] = {
|
||||
{
|
||||
.name = "U-Boot",
|
||||
.size = 0x00080000,
|
||||
.offset = 0x00780000,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
}, {
|
||||
.name = "Kernel",
|
||||
.size = 0x00200000,
|
||||
.offset = 0,
|
||||
}, {
|
||||
.name = "RootFS1",
|
||||
.size = 0x00400000,
|
||||
.offset = 0x00200000,
|
||||
}, {
|
||||
.name = "RootFS2",
|
||||
.size = 0x00100000,
|
||||
.offset = 0x00600000,
|
||||
}, {
|
||||
.name = "U-Boot Config",
|
||||
.size = 0x00020000,
|
||||
.offset = 0x00760000,
|
||||
}, {
|
||||
.name = "NAS Config",
|
||||
.size = 0x00060000,
|
||||
.offset = 0x00700000,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data qnap_ts409_nor_flash_data = {
|
||||
.width = 1,
|
||||
.parts = qnap_ts409_partitions,
|
||||
.nr_parts = ARRAY_SIZE(qnap_ts409_partitions)
|
||||
};
|
||||
|
||||
static struct resource qnap_ts409_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = QNAP_TS409_NOR_BOOT_BASE,
|
||||
.end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device qnap_ts409_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = { .platform_data = &qnap_ts409_nor_flash_data, },
|
||||
.num_resources = 1,
|
||||
.resource = &qnap_ts409_nor_flash_resource,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* PCI
|
||||
****************************************************************************/
|
||||
|
||||
static int __init qnap_ts409_pci_map_irq(const 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 isn't used on the TS-409
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct hw_pci qnap_ts409_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = qnap_ts409_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init qnap_ts409_pci_init(void)
|
||||
{
|
||||
if (machine_is_ts409())
|
||||
pci_common_init(&qnap_ts409_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(qnap_ts409_pci_init);
|
||||
|
||||
/*****************************************************************************
|
||||
* RTC S35390A on I2C bus
|
||||
****************************************************************************/
|
||||
|
||||
#define TS409_RTC_GPIO 10
|
||||
|
||||
static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = {
|
||||
I2C_BOARD_INFO("s35390a", 0x30),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LEDs attached to GPIO
|
||||
****************************************************************************/
|
||||
|
||||
static struct gpio_led ts409_led_pins[] = {
|
||||
{
|
||||
.name = "ts409:red:sata1",
|
||||
.gpio = 4,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "ts409:red:sata2",
|
||||
.gpio = 5,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "ts409:red:sata3",
|
||||
.gpio = 6,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "ts409:red:sata4",
|
||||
.gpio = 7,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data ts409_led_data = {
|
||||
.leds = ts409_led_pins,
|
||||
.num_leds = ARRAY_SIZE(ts409_led_pins),
|
||||
};
|
||||
|
||||
static struct platform_device ts409_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &ts409_led_data,
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* GPIO Attached Keys
|
||||
* Power button is attached to the PIC microcontroller
|
||||
****************************************************************************/
|
||||
|
||||
#define QNAP_TS409_GPIO_KEY_RESET 14
|
||||
#define QNAP_TS409_GPIO_KEY_MEDIA 15
|
||||
|
||||
static struct gpio_keys_button qnap_ts409_buttons[] = {
|
||||
{
|
||||
.code = KEY_RESTART,
|
||||
.gpio = QNAP_TS409_GPIO_KEY_RESET,
|
||||
.desc = "Reset Button",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.code = KEY_COPY,
|
||||
.gpio = QNAP_TS409_GPIO_KEY_MEDIA,
|
||||
.desc = "USB Copy Button",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data qnap_ts409_button_data = {
|
||||
.buttons = qnap_ts409_buttons,
|
||||
.nbuttons = ARRAY_SIZE(qnap_ts409_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device qnap_ts409_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &qnap_ts409_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int ts409_mpp_modes[] __initdata = {
|
||||
MPP0_UNUSED,
|
||||
MPP1_UNUSED,
|
||||
MPP2_UNUSED,
|
||||
MPP3_UNUSED,
|
||||
MPP4_GPIO, /* HDD 1 status */
|
||||
MPP5_GPIO, /* HDD 2 status */
|
||||
MPP6_GPIO, /* HDD 3 status */
|
||||
MPP7_GPIO, /* HDD 4 status */
|
||||
MPP8_UNUSED,
|
||||
MPP9_UNUSED,
|
||||
MPP10_GPIO, /* RTC int */
|
||||
MPP11_UNUSED,
|
||||
MPP12_UNUSED,
|
||||
MPP13_UNUSED,
|
||||
MPP14_GPIO, /* SW_RST */
|
||||
MPP15_GPIO, /* USB copy button */
|
||||
MPP16_UART, /* UART1 RXD */
|
||||
MPP17_UART, /* UART1 TXD */
|
||||
MPP18_UNUSED,
|
||||
MPP19_UNUSED,
|
||||
0,
|
||||
};
|
||||
|
||||
static void __init qnap_ts409_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(ts409_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
QNAP_TS409_NOR_BOOT_BASE,
|
||||
QNAP_TS409_NOR_BOOT_SIZE);
|
||||
platform_device_register(&qnap_ts409_nor_flash);
|
||||
|
||||
orion5x_ehci0_init();
|
||||
qnap_tsx09_find_mac_addr(QNAP_TS409_NOR_BOOT_BASE +
|
||||
qnap_ts409_partitions[5].offset,
|
||||
qnap_ts409_partitions[5].size);
|
||||
orion5x_eth_init(&qnap_tsx09_eth_data);
|
||||
orion5x_i2c_init();
|
||||
orion5x_uart0_init();
|
||||
orion5x_uart1_init();
|
||||
|
||||
platform_device_register(&qnap_ts409_button_device);
|
||||
|
||||
/* Get RTC IRQ and register the chip */
|
||||
if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) {
|
||||
if (gpio_direction_input(TS409_RTC_GPIO) == 0)
|
||||
qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO);
|
||||
else
|
||||
gpio_free(TS409_RTC_GPIO);
|
||||
}
|
||||
if (qnap_ts409_i2c_rtc.irq == 0)
|
||||
pr_warn("qnap_ts409_init: failed to get RTC IRQ\n");
|
||||
i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1);
|
||||
platform_device_register(&ts409_leds);
|
||||
|
||||
/* register tsx09 specific power-off method */
|
||||
pm_power_off = qnap_tsx09_power_off;
|
||||
}
|
||||
|
||||
MACHINE_START(TS409, "QNAP TS-409")
|
||||
/* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = qnap_ts409_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
41
arch/arm/mach-orion5x/ts78xx-fpga.h
Normal file
41
arch/arm/mach-orion5x/ts78xx-fpga.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#define TS7800_FPGA_MAGIC 0x00b480
|
||||
#define FPGAID(_magic, _rev) ((_magic << 8) + _rev)
|
||||
|
||||
/*
|
||||
* get yer id's from http://ts78xx.digriz.org.uk/
|
||||
* do *not* make up your own or 'borrow' any!
|
||||
*/
|
||||
enum fpga_ids {
|
||||
/* Technologic Systems */
|
||||
TS7800_REV_1 = FPGAID(TS7800_FPGA_MAGIC, 0x01),
|
||||
TS7800_REV_2 = FPGAID(TS7800_FPGA_MAGIC, 0x02),
|
||||
TS7800_REV_3 = FPGAID(TS7800_FPGA_MAGIC, 0x03),
|
||||
TS7800_REV_4 = FPGAID(TS7800_FPGA_MAGIC, 0x04),
|
||||
TS7800_REV_5 = FPGAID(TS7800_FPGA_MAGIC, 0x05),
|
||||
TS7800_REV_6 = FPGAID(TS7800_FPGA_MAGIC, 0x06),
|
||||
TS7800_REV_7 = FPGAID(TS7800_FPGA_MAGIC, 0x07),
|
||||
TS7800_REV_8 = FPGAID(TS7800_FPGA_MAGIC, 0x08),
|
||||
TS7800_REV_9 = FPGAID(TS7800_FPGA_MAGIC, 0x09),
|
||||
|
||||
/* Unaffordable & Expensive */
|
||||
UAE_DUMMY = FPGAID(0xffffff, 0x01),
|
||||
};
|
||||
|
||||
struct fpga_device {
|
||||
unsigned present:1;
|
||||
unsigned init:1;
|
||||
};
|
||||
|
||||
struct fpga_devices {
|
||||
/* Technologic Systems */
|
||||
struct fpga_device ts_rtc;
|
||||
struct fpga_device ts_nand;
|
||||
struct fpga_device ts_rng;
|
||||
};
|
||||
|
||||
struct ts78xx_fpga_data {
|
||||
unsigned int id;
|
||||
int state;
|
||||
|
||||
struct fpga_devices supports;
|
||||
};
|
624
arch/arm/mach-orion5x/ts78xx-setup.c
Normal file
624
arch/arm/mach-orion5x/ts78xx-setup.c
Normal file
|
@ -0,0 +1,624 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/ts78xx-setup.c
|
||||
*
|
||||
* Maintainer: Alexander Clouter <alex@digriz.org.uk>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/m48t86.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/timeriomem-rng.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
#include "ts78xx-fpga.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* TS-78xx Info
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* FPGA - lives where the PCI bus would be at ORION5X_PCI_MEM_PHYS_BASE
|
||||
*/
|
||||
#define TS78XX_FPGA_REGS_PHYS_BASE 0xe8000000
|
||||
#define TS78XX_FPGA_REGS_VIRT_BASE IOMEM(0xff900000)
|
||||
#define TS78XX_FPGA_REGS_SIZE SZ_1M
|
||||
|
||||
static struct ts78xx_fpga_data ts78xx_fpga = {
|
||||
.id = 0,
|
||||
.state = 1,
|
||||
/* .supports = ... - populated by ts78xx_fpga_supports() */
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* I/O Address Mapping
|
||||
****************************************************************************/
|
||||
static struct map_desc ts78xx_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = (unsigned long)TS78XX_FPGA_REGS_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(TS78XX_FPGA_REGS_PHYS_BASE),
|
||||
.length = TS78XX_FPGA_REGS_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init ts78xx_map_io(void)
|
||||
{
|
||||
orion5x_map_io();
|
||||
iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
static struct mv643xx_eth_platform_data ts78xx_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
static struct mv_sata_platform_data ts78xx_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
|
||||
****************************************************************************/
|
||||
#define TS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE + 0x808)
|
||||
#define TS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE + 0x80c)
|
||||
|
||||
static unsigned char ts78xx_ts_rtc_readbyte(unsigned long addr)
|
||||
{
|
||||
writeb(addr, TS_RTC_CTRL);
|
||||
return readb(TS_RTC_DATA);
|
||||
}
|
||||
|
||||
static void ts78xx_ts_rtc_writebyte(unsigned char value, unsigned long addr)
|
||||
{
|
||||
writeb(addr, TS_RTC_CTRL);
|
||||
writeb(value, TS_RTC_DATA);
|
||||
}
|
||||
|
||||
static struct m48t86_ops ts78xx_ts_rtc_ops = {
|
||||
.readbyte = ts78xx_ts_rtc_readbyte,
|
||||
.writebyte = ts78xx_ts_rtc_writebyte,
|
||||
};
|
||||
|
||||
static struct platform_device ts78xx_ts_rtc_device = {
|
||||
.name = "rtc-m48t86",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &ts78xx_ts_rtc_ops,
|
||||
},
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* TS uses some of the user storage space on the RTC chip so see if it is
|
||||
* present; as it's an optional feature at purchase time and not all boards
|
||||
* will have it present
|
||||
*
|
||||
* I've used the method TS use in their rtc7800.c example for the detection
|
||||
*
|
||||
* TODO: track down a guinea pig without an RTC to see if we can work out a
|
||||
* better RTC detection routine
|
||||
*/
|
||||
static int ts78xx_ts_rtc_load(void)
|
||||
{
|
||||
int rc;
|
||||
unsigned char tmp_rtc0, tmp_rtc1;
|
||||
|
||||
tmp_rtc0 = ts78xx_ts_rtc_readbyte(126);
|
||||
tmp_rtc1 = ts78xx_ts_rtc_readbyte(127);
|
||||
|
||||
ts78xx_ts_rtc_writebyte(0x00, 126);
|
||||
ts78xx_ts_rtc_writebyte(0x55, 127);
|
||||
if (ts78xx_ts_rtc_readbyte(127) == 0x55) {
|
||||
ts78xx_ts_rtc_writebyte(0xaa, 127);
|
||||
if (ts78xx_ts_rtc_readbyte(127) == 0xaa
|
||||
&& ts78xx_ts_rtc_readbyte(126) == 0x00) {
|
||||
ts78xx_ts_rtc_writebyte(tmp_rtc0, 126);
|
||||
ts78xx_ts_rtc_writebyte(tmp_rtc1, 127);
|
||||
|
||||
if (ts78xx_fpga.supports.ts_rtc.init == 0) {
|
||||
rc = platform_device_register(&ts78xx_ts_rtc_device);
|
||||
if (!rc)
|
||||
ts78xx_fpga.supports.ts_rtc.init = 1;
|
||||
} else
|
||||
rc = platform_device_add(&ts78xx_ts_rtc_device);
|
||||
|
||||
if (rc)
|
||||
pr_info("RTC could not be registered: %d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
pr_info("RTC not found\n");
|
||||
return -ENODEV;
|
||||
};
|
||||
|
||||
static void ts78xx_ts_rtc_unload(void)
|
||||
{
|
||||
platform_device_del(&ts78xx_ts_rtc_device);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* NAND Flash
|
||||
****************************************************************************/
|
||||
#define TS_NAND_CTRL (TS78XX_FPGA_REGS_VIRT_BASE + 0x800) /* VIRT */
|
||||
#define TS_NAND_DATA (TS78XX_FPGA_REGS_PHYS_BASE + 0x804) /* PHYS */
|
||||
|
||||
/*
|
||||
* hardware specific access to control-lines
|
||||
*
|
||||
* ctrl:
|
||||
* NAND_NCE: bit 0 -> bit 2
|
||||
* NAND_CLE: bit 1 -> bit 1
|
||||
* NAND_ALE: bit 2 -> bit 0
|
||||
*/
|
||||
static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
||||
unsigned int ctrl)
|
||||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
|
||||
if (ctrl & NAND_CTRL_CHANGE) {
|
||||
unsigned char bits;
|
||||
|
||||
bits = (ctrl & NAND_NCE) << 2;
|
||||
bits |= ctrl & NAND_CLE;
|
||||
bits |= (ctrl & NAND_ALE) >> 2;
|
||||
|
||||
writeb((readb(TS_NAND_CTRL) & ~0x7) | bits, TS_NAND_CTRL);
|
||||
}
|
||||
|
||||
if (cmd != NAND_CMD_NONE)
|
||||
writeb(cmd, this->IO_ADDR_W);
|
||||
}
|
||||
|
||||
static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
|
||||
{
|
||||
return readb(TS_NAND_CTRL) & 0x20;
|
||||
}
|
||||
|
||||
static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd,
|
||||
const uint8_t *buf, int len)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
void __iomem *io_base = chip->IO_ADDR_W;
|
||||
unsigned long off = ((unsigned long)buf & 3);
|
||||
int sz;
|
||||
|
||||
if (off) {
|
||||
sz = min_t(int, 4 - off, len);
|
||||
writesb(io_base, buf, sz);
|
||||
buf += sz;
|
||||
len -= sz;
|
||||
}
|
||||
|
||||
sz = len >> 2;
|
||||
if (sz) {
|
||||
u32 *buf32 = (u32 *)buf;
|
||||
writesl(io_base, buf32, sz);
|
||||
buf += sz << 2;
|
||||
len -= sz << 2;
|
||||
}
|
||||
|
||||
if (len)
|
||||
writesb(io_base, buf, len);
|
||||
}
|
||||
|
||||
static void ts78xx_ts_nand_read_buf(struct mtd_info *mtd,
|
||||
uint8_t *buf, int len)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
void __iomem *io_base = chip->IO_ADDR_R;
|
||||
unsigned long off = ((unsigned long)buf & 3);
|
||||
int sz;
|
||||
|
||||
if (off) {
|
||||
sz = min_t(int, 4 - off, len);
|
||||
readsb(io_base, buf, sz);
|
||||
buf += sz;
|
||||
len -= sz;
|
||||
}
|
||||
|
||||
sz = len >> 2;
|
||||
if (sz) {
|
||||
u32 *buf32 = (u32 *)buf;
|
||||
readsl(io_base, buf32, sz);
|
||||
buf += sz << 2;
|
||||
len -= sz << 2;
|
||||
}
|
||||
|
||||
if (len)
|
||||
readsb(io_base, buf, len);
|
||||
}
|
||||
|
||||
static struct mtd_partition ts78xx_ts_nand_parts[] = {
|
||||
{
|
||||
.name = "mbr",
|
||||
.offset = 0,
|
||||
.size = SZ_128K,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
}, {
|
||||
.name = "kernel",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_4M,
|
||||
}, {
|
||||
.name = "initrd",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_4M,
|
||||
}, {
|
||||
.name = "rootfs",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_nand_data ts78xx_ts_nand_data = {
|
||||
.chip = {
|
||||
.nr_chips = 1,
|
||||
.partitions = ts78xx_ts_nand_parts,
|
||||
.nr_partitions = ARRAY_SIZE(ts78xx_ts_nand_parts),
|
||||
.chip_delay = 15,
|
||||
.bbt_options = NAND_BBT_USE_FLASH,
|
||||
},
|
||||
.ctrl = {
|
||||
/*
|
||||
* The HW ECC offloading functions, used to give about a 9%
|
||||
* performance increase for 'dd if=/dev/mtdblockX' and 5% for
|
||||
* nanddump. This all however was changed by git commit
|
||||
* e6cf5df1838c28bb060ac45b5585e48e71bbc740 so now there is
|
||||
* no performance advantage to be had so we no longer bother
|
||||
*/
|
||||
.cmd_ctrl = ts78xx_ts_nand_cmd_ctrl,
|
||||
.dev_ready = ts78xx_ts_nand_dev_ready,
|
||||
.write_buf = ts78xx_ts_nand_write_buf,
|
||||
.read_buf = ts78xx_ts_nand_read_buf,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource ts78xx_ts_nand_resources
|
||||
= DEFINE_RES_MEM(TS_NAND_DATA, 4);
|
||||
|
||||
static struct platform_device ts78xx_ts_nand_device = {
|
||||
.name = "gen_nand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &ts78xx_ts_nand_data,
|
||||
},
|
||||
.resource = &ts78xx_ts_nand_resources,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
static int ts78xx_ts_nand_load(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (ts78xx_fpga.supports.ts_nand.init == 0) {
|
||||
rc = platform_device_register(&ts78xx_ts_nand_device);
|
||||
if (!rc)
|
||||
ts78xx_fpga.supports.ts_nand.init = 1;
|
||||
} else
|
||||
rc = platform_device_add(&ts78xx_ts_nand_device);
|
||||
|
||||
if (rc)
|
||||
pr_info("NAND could not be registered: %d\n", rc);
|
||||
return rc;
|
||||
};
|
||||
|
||||
static void ts78xx_ts_nand_unload(void)
|
||||
{
|
||||
platform_device_del(&ts78xx_ts_nand_device);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* HW RNG
|
||||
****************************************************************************/
|
||||
#define TS_RNG_DATA (TS78XX_FPGA_REGS_PHYS_BASE | 0x044)
|
||||
|
||||
static struct resource ts78xx_ts_rng_resource
|
||||
= DEFINE_RES_MEM(TS_RNG_DATA, 4);
|
||||
|
||||
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
|
||||
.period = 1000000, /* one second */
|
||||
};
|
||||
|
||||
static struct platform_device ts78xx_ts_rng_device = {
|
||||
.name = "timeriomem_rng",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &ts78xx_ts_rng_data,
|
||||
},
|
||||
.resource = &ts78xx_ts_rng_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
static int ts78xx_ts_rng_load(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (ts78xx_fpga.supports.ts_rng.init == 0) {
|
||||
rc = platform_device_register(&ts78xx_ts_rng_device);
|
||||
if (!rc)
|
||||
ts78xx_fpga.supports.ts_rng.init = 1;
|
||||
} else
|
||||
rc = platform_device_add(&ts78xx_ts_rng_device);
|
||||
|
||||
if (rc)
|
||||
pr_info("RNG could not be registered: %d\n", rc);
|
||||
return rc;
|
||||
};
|
||||
|
||||
static void ts78xx_ts_rng_unload(void)
|
||||
{
|
||||
platform_device_del(&ts78xx_ts_rng_device);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* FPGA 'hotplug' support code
|
||||
****************************************************************************/
|
||||
static void ts78xx_fpga_devices_zero_init(void)
|
||||
{
|
||||
ts78xx_fpga.supports.ts_rtc.init = 0;
|
||||
ts78xx_fpga.supports.ts_nand.init = 0;
|
||||
ts78xx_fpga.supports.ts_rng.init = 0;
|
||||
}
|
||||
|
||||
static void ts78xx_fpga_supports(void)
|
||||
{
|
||||
/* TODO: put this 'table' into ts78xx-fpga.h */
|
||||
switch (ts78xx_fpga.id) {
|
||||
case TS7800_REV_1:
|
||||
case TS7800_REV_2:
|
||||
case TS7800_REV_3:
|
||||
case TS7800_REV_4:
|
||||
case TS7800_REV_5:
|
||||
case TS7800_REV_6:
|
||||
case TS7800_REV_7:
|
||||
case TS7800_REV_8:
|
||||
case TS7800_REV_9:
|
||||
ts78xx_fpga.supports.ts_rtc.present = 1;
|
||||
ts78xx_fpga.supports.ts_nand.present = 1;
|
||||
ts78xx_fpga.supports.ts_rng.present = 1;
|
||||
break;
|
||||
default:
|
||||
/* enable devices if magic matches */
|
||||
switch ((ts78xx_fpga.id >> 8) & 0xffffff) {
|
||||
case TS7800_FPGA_MAGIC:
|
||||
pr_warn("unrecognised FPGA revision 0x%.2x\n",
|
||||
ts78xx_fpga.id & 0xff);
|
||||
ts78xx_fpga.supports.ts_rtc.present = 1;
|
||||
ts78xx_fpga.supports.ts_nand.present = 1;
|
||||
ts78xx_fpga.supports.ts_rng.present = 1;
|
||||
break;
|
||||
default:
|
||||
ts78xx_fpga.supports.ts_rtc.present = 0;
|
||||
ts78xx_fpga.supports.ts_nand.present = 0;
|
||||
ts78xx_fpga.supports.ts_rng.present = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ts78xx_fpga_load_devices(void)
|
||||
{
|
||||
int tmp, ret = 0;
|
||||
|
||||
if (ts78xx_fpga.supports.ts_rtc.present == 1) {
|
||||
tmp = ts78xx_ts_rtc_load();
|
||||
if (tmp)
|
||||
ts78xx_fpga.supports.ts_rtc.present = 0;
|
||||
ret |= tmp;
|
||||
}
|
||||
if (ts78xx_fpga.supports.ts_nand.present == 1) {
|
||||
tmp = ts78xx_ts_nand_load();
|
||||
if (tmp)
|
||||
ts78xx_fpga.supports.ts_nand.present = 0;
|
||||
ret |= tmp;
|
||||
}
|
||||
if (ts78xx_fpga.supports.ts_rng.present == 1) {
|
||||
tmp = ts78xx_ts_rng_load();
|
||||
if (tmp)
|
||||
ts78xx_fpga.supports.ts_rng.present = 0;
|
||||
ret |= tmp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ts78xx_fpga_unload_devices(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ts78xx_fpga.supports.ts_rtc.present == 1)
|
||||
ts78xx_ts_rtc_unload();
|
||||
if (ts78xx_fpga.supports.ts_nand.present == 1)
|
||||
ts78xx_ts_nand_unload();
|
||||
if (ts78xx_fpga.supports.ts_rng.present == 1)
|
||||
ts78xx_ts_rng_unload();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ts78xx_fpga_load(void)
|
||||
{
|
||||
ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
|
||||
|
||||
pr_info("FPGA magic=0x%.6x, rev=0x%.2x\n",
|
||||
(ts78xx_fpga.id >> 8) & 0xffffff,
|
||||
ts78xx_fpga.id & 0xff);
|
||||
|
||||
ts78xx_fpga_supports();
|
||||
|
||||
if (ts78xx_fpga_load_devices()) {
|
||||
ts78xx_fpga.state = -1;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int ts78xx_fpga_unload(void)
|
||||
{
|
||||
unsigned int fpga_id;
|
||||
|
||||
fpga_id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
|
||||
|
||||
/*
|
||||
* There does not seem to be a feasible way to block access to the GPIO
|
||||
* pins from userspace (/dev/mem). This if clause should hopefully warn
|
||||
* those foolish enough not to follow 'policy' :)
|
||||
*
|
||||
* UrJTAG SVN since r1381 can be used to reprogram the FPGA
|
||||
*/
|
||||
if (ts78xx_fpga.id != fpga_id) {
|
||||
pr_err("FPGA magic/rev mismatch\n"
|
||||
"TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
|
||||
(ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
|
||||
(fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
|
||||
ts78xx_fpga.state = -1;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (ts78xx_fpga_unload_devices()) {
|
||||
ts78xx_fpga.state = -1;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static ssize_t ts78xx_fpga_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
if (ts78xx_fpga.state < 0)
|
||||
return sprintf(buf, "borked\n");
|
||||
|
||||
return sprintf(buf, "%s\n", (ts78xx_fpga.state) ? "online" : "offline");
|
||||
}
|
||||
|
||||
static ssize_t ts78xx_fpga_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, const char *buf, size_t n)
|
||||
{
|
||||
int value, ret;
|
||||
|
||||
if (ts78xx_fpga.state < 0) {
|
||||
pr_err("FPGA borked, you must powercycle ASAP\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (strncmp(buf, "online", sizeof("online") - 1) == 0)
|
||||
value = 1;
|
||||
else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
|
||||
value = 0;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
if (ts78xx_fpga.state == value)
|
||||
return n;
|
||||
|
||||
ret = (ts78xx_fpga.state == 0)
|
||||
? ts78xx_fpga_load()
|
||||
: ts78xx_fpga_unload();
|
||||
|
||||
if (!(ret < 0))
|
||||
ts78xx_fpga.state = value;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static struct kobj_attribute ts78xx_fpga_attr =
|
||||
__ATTR(ts78xx_fpga, 0644, ts78xx_fpga_show, ts78xx_fpga_store);
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
static unsigned int ts78xx_mpp_modes[] __initdata = {
|
||||
MPP0_UNUSED,
|
||||
MPP1_GPIO, /* JTAG Clock */
|
||||
MPP2_GPIO, /* JTAG Data In */
|
||||
MPP3_GPIO, /* Lat ECP2 256 FPGA - PB2B */
|
||||
MPP4_GPIO, /* JTAG Data Out */
|
||||
MPP5_GPIO, /* JTAG TMS */
|
||||
MPP6_GPIO, /* Lat ECP2 256 FPGA - PB31A_CLK4+ */
|
||||
MPP7_GPIO, /* Lat ECP2 256 FPGA - PB22B */
|
||||
MPP8_UNUSED,
|
||||
MPP9_UNUSED,
|
||||
MPP10_UNUSED,
|
||||
MPP11_UNUSED,
|
||||
MPP12_UNUSED,
|
||||
MPP13_UNUSED,
|
||||
MPP14_UNUSED,
|
||||
MPP15_UNUSED,
|
||||
MPP16_UART,
|
||||
MPP17_UART,
|
||||
MPP18_UART,
|
||||
MPP19_UART,
|
||||
/*
|
||||
* MPP[20] PCI Clock Out 1
|
||||
* MPP[21] PCI Clock Out 0
|
||||
* MPP[22] Unused
|
||||
* MPP[23] Unused
|
||||
* MPP[24] Unused
|
||||
* MPP[25] Unused
|
||||
*/
|
||||
0,
|
||||
};
|
||||
|
||||
static void __init ts78xx_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(ts78xx_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_ehci1_init();
|
||||
orion5x_eth_init(&ts78xx_eth_data);
|
||||
orion5x_sata_init(&ts78xx_sata_data);
|
||||
orion5x_uart0_init();
|
||||
orion5x_uart1_init();
|
||||
orion5x_xor_init();
|
||||
|
||||
/* FPGA init */
|
||||
ts78xx_fpga_devices_zero_init();
|
||||
ret = ts78xx_fpga_load();
|
||||
ret = sysfs_create_file(firmware_kobj, &ts78xx_fpga_attr.attr);
|
||||
if (ret)
|
||||
pr_err("sysfs_create_file failed: %d\n", ret);
|
||||
}
|
||||
|
||||
MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
|
||||
/* Maintainer: Alexander Clouter <alex@digriz.org.uk> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = ts78xx_init,
|
||||
.map_io = ts78xx_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
135
arch/arm/mach-orion5x/tsx09-common.c
Normal file
135
arch/arm/mach-orion5x/tsx09-common.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* QNAP TS-x09 Boards common functions
|
||||
*
|
||||
* Maintainers: Lennert Buytenhek <buytenh@marvell.com>
|
||||
* Byron Bradley <byron.bbradley@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <mach/orion5x.h>
|
||||
#include "tsx09-common.h"
|
||||
#include "common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* QNAP TS-x09 specific power off method via UART1-attached PIC
|
||||
****************************************************************************/
|
||||
|
||||
#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
|
||||
|
||||
void qnap_tsx09_power_off(void)
|
||||
{
|
||||
/* 19200 baud divisor */
|
||||
const unsigned divisor = ((orion5x_tclk + (8 * 19200)) / (16 * 19200));
|
||||
|
||||
pr_info("%s: triggering power-off...\n", __func__);
|
||||
|
||||
/* hijack uart1 and reset into sane state (19200,8n1) */
|
||||
writel(0x83, UART1_REG(LCR));
|
||||
writel(divisor & 0xff, UART1_REG(DLL));
|
||||
writel((divisor >> 8) & 0xff, UART1_REG(DLM));
|
||||
writel(0x03, UART1_REG(LCR));
|
||||
writel(0x00, UART1_REG(IER));
|
||||
writel(0x00, UART1_REG(FCR));
|
||||
writel(0x00, UART1_REG(MCR));
|
||||
|
||||
/* send the power-off command 'A' to PIC */
|
||||
writel('A', UART1_REG(TX));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
|
||||
struct mv643xx_eth_platform_data qnap_tsx09_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
static int __init qnap_tsx09_parse_hex_nibble(char n)
|
||||
{
|
||||
if (n >= '0' && n <= '9')
|
||||
return n - '0';
|
||||
|
||||
if (n >= 'A' && n <= 'F')
|
||||
return n - 'A' + 10;
|
||||
|
||||
if (n >= 'a' && n <= 'f')
|
||||
return n - 'a' + 10;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __init qnap_tsx09_parse_hex_byte(const char *b)
|
||||
{
|
||||
int hi;
|
||||
int lo;
|
||||
|
||||
hi = qnap_tsx09_parse_hex_nibble(b[0]);
|
||||
lo = qnap_tsx09_parse_hex_nibble(b[1]);
|
||||
|
||||
if (hi < 0 || lo < 0)
|
||||
return -1;
|
||||
|
||||
return (hi << 4) | lo;
|
||||
}
|
||||
|
||||
static int __init qnap_tsx09_check_mac_addr(const char *addr_str)
|
||||
{
|
||||
u_int8_t addr[6];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
int byte;
|
||||
|
||||
/*
|
||||
* Enforce "xx:xx:xx:xx:xx:xx\n" format.
|
||||
*/
|
||||
if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
|
||||
return -1;
|
||||
|
||||
byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3));
|
||||
if (byte < 0)
|
||||
return -1;
|
||||
addr[i] = byte;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "tsx09: found ethernet mac address ");
|
||||
for (i = 0; i < 6; i++)
|
||||
printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
|
||||
|
||||
memcpy(qnap_tsx09_eth_data.mac_addr, addr, 6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The 'NAS Config' flash partition has an ext2 filesystem which
|
||||
* contains a file that has the ethernet MAC address in plain text
|
||||
* (format "xx:xx:xx:xx:xx:xx\n").
|
||||
*/
|
||||
void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
for (addr = mem_base; addr < (mem_base + size); addr += 1024) {
|
||||
char *nor_page;
|
||||
int ret = 0;
|
||||
|
||||
nor_page = ioremap(addr, 1024);
|
||||
if (nor_page != NULL) {
|
||||
ret = qnap_tsx09_check_mac_addr(nor_page);
|
||||
iounmap(nor_page);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
}
|
20
arch/arm/mach-orion5x/tsx09-common.h
Normal file
20
arch/arm/mach-orion5x/tsx09-common.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef __ARCH_ORION5X_TSX09_COMMON_H
|
||||
#define __ARCH_ORION5X_TSX09_COMMON_H
|
||||
|
||||
/*
|
||||
* QNAP TS-x09 Boards power-off function
|
||||
*/
|
||||
extern void qnap_tsx09_power_off(void);
|
||||
|
||||
/*
|
||||
* QNAP TS-x09 Boards function to find Ethernet MAC address in flash memory
|
||||
*/
|
||||
extern void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size);
|
||||
|
||||
/*
|
||||
* QNAP TS-x09 Boards ethernet declaration
|
||||
*/
|
||||
extern struct mv643xx_eth_platform_data qnap_tsx09_eth_data;
|
||||
|
||||
|
||||
#endif
|
184
arch/arm/mach-orion5x/wnr854t-setup.c
Normal file
184
arch/arm/mach-orion5x/wnr854t-setup.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/wnr854t-setup.c
|
||||
*
|
||||
* 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/gpio.h>
|
||||
#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/ethtool.h>
|
||||
#include <net/dsa.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"
|
||||
|
||||
static unsigned int wnr854t_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* Power LED green (0=on) */
|
||||
MPP1_GPIO, /* Reset Button (0=off) */
|
||||
MPP2_GPIO, /* Power LED blink (0=off) */
|
||||
MPP3_GPIO, /* WAN Status LED amber (0=off) */
|
||||
MPP4_GPIO, /* PCI int */
|
||||
MPP5_GPIO, /* ??? */
|
||||
MPP6_GPIO, /* ??? */
|
||||
MPP7_GPIO, /* ??? */
|
||||
MPP8_UNUSED, /* ??? */
|
||||
MPP9_GIGE, /* GE_RXERR */
|
||||
MPP10_UNUSED, /* ??? */
|
||||
MPP11_UNUSED, /* ??? */
|
||||
MPP12_GIGE, /* GE_TXD[4] */
|
||||
MPP13_GIGE, /* GE_TXD[5] */
|
||||
MPP14_GIGE, /* GE_TXD[6] */
|
||||
MPP15_GIGE, /* GE_TXD[7] */
|
||||
MPP16_GIGE, /* GE_RXD[4] */
|
||||
MPP17_GIGE, /* GE_RXD[5] */
|
||||
MPP18_GIGE, /* GE_RXD[6] */
|
||||
MPP19_GIGE, /* GE_RXD[7] */
|
||||
0,
|
||||
};
|
||||
|
||||
/*
|
||||
* 8M NOR flash Device bus boot chip select
|
||||
*/
|
||||
#define WNR854T_NOR_BOOT_BASE 0xf4000000
|
||||
#define WNR854T_NOR_BOOT_SIZE SZ_8M
|
||||
|
||||
static struct mtd_partition wnr854t_nor_flash_partitions[] = {
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = 0x00000000,
|
||||
.size = 0x00100000,
|
||||
}, {
|
||||
.name = "rootfs",
|
||||
.offset = 0x00100000,
|
||||
.size = 0x00660000,
|
||||
}, {
|
||||
.name = "uboot",
|
||||
.offset = 0x00760000,
|
||||
.size = 0x00040000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data wnr854t_nor_flash_data = {
|
||||
.width = 2,
|
||||
.parts = wnr854t_nor_flash_partitions,
|
||||
.nr_parts = ARRAY_SIZE(wnr854t_nor_flash_partitions),
|
||||
};
|
||||
|
||||
static struct resource wnr854t_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = WNR854T_NOR_BOOT_BASE,
|
||||
.end = WNR854T_NOR_BOOT_BASE + WNR854T_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device wnr854t_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &wnr854t_nor_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &wnr854t_nor_flash_resource,
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data wnr854t_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_NONE,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static struct dsa_chip_data wnr854t_switch_chip_data = {
|
||||
.port_names[0] = "lan3",
|
||||
.port_names[1] = "lan4",
|
||||
.port_names[2] = "wan",
|
||||
.port_names[3] = "cpu",
|
||||
.port_names[5] = "lan1",
|
||||
.port_names[7] = "lan2",
|
||||
};
|
||||
|
||||
static struct dsa_platform_data wnr854t_switch_plat_data = {
|
||||
.nr_chips = 1,
|
||||
.chip = &wnr854t_switch_chip_data,
|
||||
};
|
||||
|
||||
static void __init wnr854t_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(wnr854t_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_eth_init(&wnr854t_eth_data);
|
||||
orion5x_eth_switch_init(&wnr854t_switch_plat_data, NO_IRQ);
|
||||
orion5x_uart0_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
WNR854T_NOR_BOOT_BASE,
|
||||
WNR854T_NOR_BOOT_SIZE);
|
||||
platform_device_register(&wnr854t_nor_flash);
|
||||
}
|
||||
|
||||
static int __init wnr854t_pci_map_irq(const 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;
|
||||
|
||||
/*
|
||||
* Mini-PCI slot.
|
||||
*/
|
||||
if (slot == 7)
|
||||
return gpio_to_irq(4);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct hw_pci wnr854t_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = wnr854t_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init wnr854t_pci_init(void)
|
||||
{
|
||||
if (machine_is_wnr854t())
|
||||
pci_common_init(&wnr854t_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(wnr854t_pci_init);
|
||||
|
||||
MACHINE_START(WNR854T, "Netgear WNR854T")
|
||||
/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = wnr854t_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
272
arch/arm/mach-orion5x/wrt350n-v2-setup.c
Normal file
272
arch/arm/mach-orion5x/wrt350n-v2-setup.c
Normal file
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* arch/arm/mach-orion5x/wrt350n-v2-setup.c
|
||||
*
|
||||
* 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/gpio.h>
|
||||
#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/ethtool.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
#include <net/dsa.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"
|
||||
|
||||
/*
|
||||
* LEDs attached to GPIO
|
||||
*/
|
||||
static struct gpio_led wrt350n_v2_led_pins[] = {
|
||||
{
|
||||
.name = "wrt350nv2:green:power",
|
||||
.gpio = 0,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "wrt350nv2:green:security",
|
||||
.gpio = 1,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "wrt350nv2:orange:power",
|
||||
.gpio = 5,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "wrt350nv2:green:usb",
|
||||
.gpio = 6,
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.name = "wrt350nv2:green:wireless",
|
||||
.gpio = 7,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data wrt350n_v2_led_data = {
|
||||
.leds = wrt350n_v2_led_pins,
|
||||
.num_leds = ARRAY_SIZE(wrt350n_v2_led_pins),
|
||||
};
|
||||
|
||||
static struct platform_device wrt350n_v2_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &wrt350n_v2_led_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Buttons attached to GPIO
|
||||
*/
|
||||
static struct gpio_keys_button wrt350n_v2_buttons[] = {
|
||||
{
|
||||
.code = KEY_RESTART,
|
||||
.gpio = 3,
|
||||
.desc = "Reset Button",
|
||||
.active_low = 1,
|
||||
}, {
|
||||
.code = KEY_WPS_BUTTON,
|
||||
.gpio = 2,
|
||||
.desc = "WPS Button",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data wrt350n_v2_button_data = {
|
||||
.buttons = wrt350n_v2_buttons,
|
||||
.nbuttons = ARRAY_SIZE(wrt350n_v2_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device wrt350n_v2_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &wrt350n_v2_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* General setup
|
||||
*/
|
||||
static unsigned int wrt350n_v2_mpp_modes[] __initdata = {
|
||||
MPP0_GPIO, /* Power LED green (0=on) */
|
||||
MPP1_GPIO, /* Security LED (0=on) */
|
||||
MPP2_GPIO, /* Internal Button (0=on) */
|
||||
MPP3_GPIO, /* Reset Button (0=on) */
|
||||
MPP4_GPIO, /* PCI int */
|
||||
MPP5_GPIO, /* Power LED orange (0=on) */
|
||||
MPP6_GPIO, /* USB LED (0=on) */
|
||||
MPP7_GPIO, /* Wireless LED (0=on) */
|
||||
MPP8_UNUSED, /* ??? */
|
||||
MPP9_GIGE, /* GE_RXERR */
|
||||
MPP10_UNUSED, /* ??? */
|
||||
MPP11_UNUSED, /* ??? */
|
||||
MPP12_GIGE, /* GE_TXD[4] */
|
||||
MPP13_GIGE, /* GE_TXD[5] */
|
||||
MPP14_GIGE, /* GE_TXD[6] */
|
||||
MPP15_GIGE, /* GE_TXD[7] */
|
||||
MPP16_GIGE, /* GE_RXD[4] */
|
||||
MPP17_GIGE, /* GE_RXD[5] */
|
||||
MPP18_GIGE, /* GE_RXD[6] */
|
||||
MPP19_GIGE, /* GE_RXD[7] */
|
||||
0,
|
||||
};
|
||||
|
||||
/*
|
||||
* 8M NOR flash Device bus boot chip select
|
||||
*/
|
||||
#define WRT350N_V2_NOR_BOOT_BASE 0xf4000000
|
||||
#define WRT350N_V2_NOR_BOOT_SIZE SZ_8M
|
||||
|
||||
static struct mtd_partition wrt350n_v2_nor_flash_partitions[] = {
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = 0x00000000,
|
||||
.size = 0x00760000,
|
||||
}, {
|
||||
.name = "rootfs",
|
||||
.offset = 0x001a0000,
|
||||
.size = 0x005c0000,
|
||||
}, {
|
||||
.name = "lang",
|
||||
.offset = 0x00760000,
|
||||
.size = 0x00040000,
|
||||
}, {
|
||||
.name = "nvram",
|
||||
.offset = 0x007a0000,
|
||||
.size = 0x00020000,
|
||||
}, {
|
||||
.name = "u-boot",
|
||||
.offset = 0x007c0000,
|
||||
.size = 0x00040000,
|
||||
},
|
||||
};
|
||||
|
||||
static struct physmap_flash_data wrt350n_v2_nor_flash_data = {
|
||||
.width = 1,
|
||||
.parts = wrt350n_v2_nor_flash_partitions,
|
||||
.nr_parts = ARRAY_SIZE(wrt350n_v2_nor_flash_partitions),
|
||||
};
|
||||
|
||||
static struct resource wrt350n_v2_nor_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = WRT350N_V2_NOR_BOOT_BASE,
|
||||
.end = WRT350N_V2_NOR_BOOT_BASE + WRT350N_V2_NOR_BOOT_SIZE - 1,
|
||||
};
|
||||
|
||||
static struct platform_device wrt350n_v2_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &wrt350n_v2_nor_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &wrt350n_v2_nor_flash_resource,
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_NONE,
|
||||
.speed = SPEED_1000,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static struct dsa_chip_data wrt350n_v2_switch_chip_data = {
|
||||
.port_names[0] = "lan2",
|
||||
.port_names[1] = "lan1",
|
||||
.port_names[2] = "wan",
|
||||
.port_names[3] = "cpu",
|
||||
.port_names[5] = "lan3",
|
||||
.port_names[7] = "lan4",
|
||||
};
|
||||
|
||||
static struct dsa_platform_data wrt350n_v2_switch_plat_data = {
|
||||
.nr_chips = 1,
|
||||
.chip = &wrt350n_v2_switch_chip_data,
|
||||
};
|
||||
|
||||
static void __init wrt350n_v2_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup basic Orion functions. Need to be called early.
|
||||
*/
|
||||
orion5x_init();
|
||||
|
||||
orion5x_mpp_conf(wrt350n_v2_mpp_modes);
|
||||
|
||||
/*
|
||||
* Configure peripherals.
|
||||
*/
|
||||
orion5x_ehci0_init();
|
||||
orion5x_eth_init(&wrt350n_v2_eth_data);
|
||||
orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
|
||||
orion5x_uart0_init();
|
||||
|
||||
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
|
||||
ORION_MBUS_DEVBUS_BOOT_ATTR,
|
||||
WRT350N_V2_NOR_BOOT_BASE,
|
||||
WRT350N_V2_NOR_BOOT_SIZE);
|
||||
platform_device_register(&wrt350n_v2_nor_flash);
|
||||
platform_device_register(&wrt350n_v2_leds);
|
||||
platform_device_register(&wrt350n_v2_button_device);
|
||||
}
|
||||
|
||||
static int __init wrt350n_v2_pci_map_irq(const 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;
|
||||
|
||||
/*
|
||||
* Mini-PCI slot.
|
||||
*/
|
||||
if (slot == 7)
|
||||
return gpio_to_irq(4);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct hw_pci wrt350n_v2_pci __initdata = {
|
||||
.nr_controllers = 2,
|
||||
.setup = orion5x_pci_sys_setup,
|
||||
.scan = orion5x_pci_sys_scan_bus,
|
||||
.map_irq = wrt350n_v2_pci_map_irq,
|
||||
};
|
||||
|
||||
static int __init wrt350n_v2_pci_init(void)
|
||||
{
|
||||
if (machine_is_wrt350n_v2())
|
||||
pci_common_init(&wrt350n_v2_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(wrt350n_v2_pci_init);
|
||||
|
||||
MACHINE_START(WRT350N_V2, "Linksys WRT350N v2")
|
||||
/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
|
||||
.atag_offset = 0x100,
|
||||
.init_machine = wrt350n_v2_init,
|
||||
.map_io = orion5x_map_io,
|
||||
.init_early = orion5x_init_early,
|
||||
.init_irq = orion5x_init_irq,
|
||||
.init_time = orion5x_timer_init,
|
||||
.fixup = tag_fixup_mem32,
|
||||
.restart = orion5x_restart,
|
||||
MACHINE_END
|
Loading…
Add table
Add a link
Reference in a new issue