diff options
author | Florian Fainelli <florian@openwrt.org> | 2015-04-04 18:01:07 +0000 |
---|---|---|
committer | Florian Fainelli <florian@openwrt.org> | 2015-04-04 18:01:07 +0000 |
commit | d030e21a01634dd74b84b4b1de55fe1a86ad1a15 (patch) | |
tree | a06c2ec374a34c9b7fff6551e596e381eb87e263 /target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/common.c | |
parent | 71f35a88e4666f4f310efb4563ebfce54045636f (diff) | |
download | master-187ad058-d030e21a01634dd74b84b4b1de55fe1a86ad1a15.tar.gz master-187ad058-d030e21a01634dd74b84b4b1de55fe1a86ad1a15.tar.bz2 master-187ad058-d030e21a01634dd74b84b4b1de55fe1a86ad1a15.zip |
mcs814x: add support for 3.18
Signed-off-by: Florian Fainelli <florian@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@45273 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/common.c')
-rw-r--r-- | target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/common.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/common.c b/target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/common.c new file mode 100644 index 0000000000..3f1be1fe2d --- /dev/null +++ b/target/linux/mcs814x/files-3.18/arch/arm/mach-mcs814x/common.c @@ -0,0 +1,166 @@ +/* + * arch/arm/mach-mcs814x/common.c + * + * Core functions for Moschip MCS814x 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 <linux/gpio.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/reboot.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/mcs814x.h> +#include <mach/cpu.h> +#include <asm/pgtable.h> +#include <asm/mach/map.h> + +void __iomem *mcs814x_sysdbg_base; + +static struct map_desc mcs814x_io_desc[] __initdata = { + { + .virtual = MCS814X_IO_BASE, + .pfn = __phys_to_pfn(MCS814X_IO_START), + .length = MCS814X_IO_SIZE, + .type = MT_DEVICE + }, +}; + +struct cpu_mode { + const char *name; + int gpio_start; + int gpio_end; +}; + +static const struct cpu_mode cpu_modes[] = { + { + .name = "I2S", + .gpio_start = 4, + .gpio_end = 8, + }, + { + .name = "UART", + .gpio_start = 4, + .gpio_end = 9, + }, + { + .name = "External MII", + .gpio_start = 0, + .gpio_end = 16, + }, + { + .name = "Normal", + .gpio_start = -1, + .gpio_end = -1, + }, +}; + +static void mcs814x_eth_hardware_filter_set(u8 value) +{ + u32 reg; + + reg = readl_relaxed(MCS814X_VIRT_BASE + MCS814X_DBGLED); + if (value) + reg |= 0x80; + else + reg &= ~0x80; + writel_relaxed(reg, MCS814X_VIRT_BASE + MCS814X_DBGLED); +} + +static void mcs814x_eth_led_cfg_set(u8 cfg) +{ + u32 reg; + + reg = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS2); + reg &= ~LED_CFG_MASK; + reg |= cfg; + writel_relaxed(reg, mcs814x_sysdbg_base + SYSDBG_BS2); +} + +static void mcs814x_eth_buffer_shifting_set(u8 value) +{ + u8 reg; + + reg = readb_relaxed(mcs814x_sysdbg_base + SYSDBG_SYSCTL_MAC); + if (value) + reg |= BUF_SHIFT_BIT; + else + reg &= ~BUF_SHIFT_BIT; + writeb_relaxed(reg, mcs814x_sysdbg_base + SYSDBG_SYSCTL_MAC); +} + +static struct of_device_id mcs814x_eth_ids[] __initdata = { + { .compatible = "moschip,nuport-mac", }, + { /* sentinel */ }, +}; + +/* Configure platform specific knobs based on ethernet device node + * properties */ +static void mcs814x_eth_init(void) +{ + struct device_node *np; + const unsigned int *intspec; + + np = of_find_matching_node(NULL, mcs814x_eth_ids); + if (!np) + return; + + /* hardware filter must always be enabled */ + mcs814x_eth_hardware_filter_set(1); + + intspec = of_get_property(np, "nuport-mac,buffer-shifting", NULL); + if (!intspec) + mcs814x_eth_buffer_shifting_set(0); + else + mcs814x_eth_buffer_shifting_set(1); + + intspec = of_get_property(np, "nuport-mac,link-activity", NULL); + if (intspec) + mcs814x_eth_led_cfg_set(be32_to_cpup(intspec)); + + of_node_put(np); +} + +void __init mcs814x_init_machine(void) +{ + u32 bs2, cpu_mode; + int gpio; + + bs2 = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS2); + cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK; + + pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name); + + /* request the gpios since the pins are muxed for functionnality */ + for (gpio = cpu_modes[cpu_mode].gpio_start; + gpio == cpu_modes[cpu_mode].gpio_end; gpio++) { + if (gpio != -1) + gpio_request(gpio, cpu_modes[cpu_mode].name); + } + + mcs814x_eth_init(); +} + +void __init mcs814x_map_io(void) +{ + iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc)); + + mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG, + MCS814X_SYSDBG_SIZE); + if (!mcs814x_sysdbg_base) + panic("unable to remap sysdbg base"); +} + +void mcs814x_restart(enum reboot_mode mode, const char *cmd) +{ + writel_relaxed(~(1 << 31), mcs814x_sysdbg_base); +} |