openwrt/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/common.c
Florian Fainelli 7c984552ed remove platform specific initialization from ethernet driver
Hardware filtering must always be enabled as long as there is an Ethernet
device registered, and use device tree for setting the link activity and
buffer shifting enable/disable bit.

SVN-Revision: 32486
2012-06-23 11:03:35 +00:00

164 lines
3.3 KiB
C

/*
* 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 <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/hardware.h>
#include <mach/cpu.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
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
},
};
#define SYSDBG_BS2 0x04
#define LED_CFG_MASK 0x03
#define CPU_MODE_SHIFT 23
#define CPU_MODE_MASK 0x03
#define SYSDBG_SYSCTL_MAC 0x1d
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 = __raw_readl(_CONFADDR_DBGLED);
if (value)
reg |= 0x80;
else
reg &= ~0x80;
__raw_writel(reg, _CONFADDR_DBGLED);
}
static void mcs814x_eth_led_cfg_set(u8 cfg)
{
u32 reg;
reg = __raw_readl(_CONFADDR_SYSDBG + SYSDBG_BS2);
reg &= ~LED_CFG_MASK;
reg |= cfg;
__raw_writel(reg, _CONFADDR_SYSDBG + SYSDBG_BS2);
}
static void mcs814x_eth_buffer_shifting_set(u8 value)
{
u8 reg;
reg = __raw_readb(_CONFADDR_SYSDBG + SYSDBG_SYSCTL_MAC);
if (value)
reg |= 0x01;
else
reg &= ~0x01;
__raw_writeb(reg, _CONFADDR_SYSDBG + 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));
}
void __init mcs814x_init_machine(void)
{
u32 bs2, cpu_mode;
int gpio;
bs2 = __raw_readl(_CONFADDR_SYSDBG + 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));
}
void mcs814x_restart(char mode, const char *cmd)
{
__raw_writel(~(1 << 31), _CONFADDR_SYSDBG);
}