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