Root/target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/common.c

1/*
2 * arch/arm/mach-mcs814x/common.c
3 *
4 * Core functions for Moschip MCS814x SoCs
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/io.h>
14#include <linux/gpio.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17
18#include <asm/setup.h>
19#include <asm/mach-types.h>
20#include <asm/mach/arch.h>
21#include <mach/mcs814x.h>
22#include <mach/cpu.h>
23#include <asm/pgtable.h>
24#include <asm/mach/map.h>
25
26void __iomem *mcs814x_sysdbg_base;
27
28static struct map_desc mcs814x_io_desc[] __initdata = {
29    {
30        .virtual = MCS814X_IO_BASE,
31        .pfn = __phys_to_pfn(MCS814X_IO_START),
32        .length = MCS814X_IO_SIZE,
33        .type = MT_DEVICE
34    },
35};
36
37struct cpu_mode {
38    const char *name;
39    int gpio_start;
40    int gpio_end;
41};
42
43static const struct cpu_mode cpu_modes[] = {
44    {
45        .name = "I2S",
46        .gpio_start = 4,
47        .gpio_end = 8,
48    },
49    {
50        .name = "UART",
51        .gpio_start = 4,
52        .gpio_end = 9,
53    },
54    {
55        .name = "External MII",
56        .gpio_start = 0,
57        .gpio_end = 16,
58    },
59    {
60        .name = "Normal",
61        .gpio_start = -1,
62        .gpio_end = -1,
63    },
64};
65
66static void mcs814x_eth_hardware_filter_set(u8 value)
67{
68    u32 reg;
69
70    reg = readl_relaxed(MCS814X_VIRT_BASE + MCS814X_DBGLED);
71    if (value)
72        reg |= 0x80;
73    else
74        reg &= ~0x80;
75    writel_relaxed(reg, MCS814X_VIRT_BASE + MCS814X_DBGLED);
76}
77
78static void mcs814x_eth_led_cfg_set(u8 cfg)
79{
80    u32 reg;
81
82    reg = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS2);
83    reg &= ~LED_CFG_MASK;
84    reg |= cfg;
85    writel_relaxed(reg, mcs814x_sysdbg_base + SYSDBG_BS2);
86}
87
88static void mcs814x_eth_buffer_shifting_set(u8 value)
89{
90    u8 reg;
91
92    reg = readb_relaxed(mcs814x_sysdbg_base + SYSDBG_SYSCTL_MAC);
93    if (value)
94        reg |= BUF_SHIFT_BIT;
95    else
96        reg &= ~BUF_SHIFT_BIT;
97    writeb_relaxed(reg, mcs814x_sysdbg_base + SYSDBG_SYSCTL_MAC);
98}
99
100static struct of_device_id mcs814x_eth_ids[] __initdata = {
101    { .compatible = "moschip,nuport-mac", },
102    { /* sentinel */ },
103};
104
105/* Configure platform specific knobs based on ethernet device node
106 * properties */
107static void mcs814x_eth_init(void)
108{
109    struct device_node *np;
110    const unsigned int *intspec;
111
112    np = of_find_matching_node(NULL, mcs814x_eth_ids);
113    if (!np)
114        return;
115
116    /* hardware filter must always be enabled */
117    mcs814x_eth_hardware_filter_set(1);
118
119    intspec = of_get_property(np, "nuport-mac,buffer-shifting", NULL);
120    if (!intspec)
121        mcs814x_eth_buffer_shifting_set(0);
122    else
123        mcs814x_eth_buffer_shifting_set(1);
124
125    intspec = of_get_property(np, "nuport-mac,link-activity", NULL);
126    if (intspec)
127        mcs814x_eth_led_cfg_set(be32_to_cpup(intspec));
128
129    of_node_put(np);
130}
131
132void __init mcs814x_init_machine(void)
133{
134    u32 bs2, cpu_mode;
135    int gpio;
136
137    bs2 = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS2);
138    cpu_mode = (bs2 >> CPU_MODE_SHIFT) & CPU_MODE_MASK;
139
140    pr_info("CPU mode: %s\n", cpu_modes[cpu_mode].name);
141
142    /* request the gpios since the pins are muxed for functionnality */
143    for (gpio = cpu_modes[cpu_mode].gpio_start;
144        gpio == cpu_modes[cpu_mode].gpio_end; gpio++) {
145        if (gpio != -1)
146            gpio_request(gpio, cpu_modes[cpu_mode].name);
147    }
148
149    mcs814x_eth_init();
150}
151
152void __init mcs814x_map_io(void)
153{
154    iotable_init(mcs814x_io_desc, ARRAY_SIZE(mcs814x_io_desc));
155
156    mcs814x_sysdbg_base = ioremap(MCS814X_IO_START + MCS814X_SYSDBG,
157                    MCS814X_SYSDBG_SIZE);
158    if (!mcs814x_sysdbg_base)
159        panic("unable to remap sysdbg base");
160}
161
162void mcs814x_restart(char mode, const char *cmd)
163{
164    writel_relaxed(~(1 << 31), mcs814x_sysdbg_base);
165}
166

Archive Download this file



interactive