]>
Commit | Line | Data |
---|---|---|
20906ece | 1 | /* |
df34403d VB |
2 | * Platform setup for the Freescale mpc885ads board |
3 | * | |
4 | * Vitaly Bordug <vbordug@ru.mvista.com> | |
5 | * | |
6 | * Copyright 2005 MontaVista Software Inc. | |
7 | * | |
20906ece SW |
8 | * Heavily modified by Scott Wood <scottwood@freescale.com> |
9 | * Copyright 2007 Freescale Semiconductor, Inc. | |
10 | * | |
df34403d VB |
11 | * This file is licensed under the terms of the GNU General Public License |
12 | * version 2. This program is licensed "as is" without any warranty of any | |
13 | * kind, whether express or implied. | |
14 | */ | |
15 | ||
16 | #include <linux/init.h> | |
17 | #include <linux/module.h> | |
18 | #include <linux/param.h> | |
19 | #include <linux/string.h> | |
20 | #include <linux/ioport.h> | |
21 | #include <linux/device.h> | |
22 | #include <linux/delay.h> | |
df34403d VB |
23 | |
24 | #include <linux/fs_enet_pd.h> | |
25 | #include <linux/fs_uart_pd.h> | |
80128ff7 | 26 | #include <linux/fsl_devices.h> |
df34403d | 27 | #include <linux/mii.h> |
20906ece | 28 | #include <linux/of_platform.h> |
df34403d VB |
29 | |
30 | #include <asm/delay.h> | |
31 | #include <asm/io.h> | |
32 | #include <asm/machdep.h> | |
33 | #include <asm/page.h> | |
34 | #include <asm/processor.h> | |
35 | #include <asm/system.h> | |
36 | #include <asm/time.h> | |
df34403d VB |
37 | #include <asm/mpc8xx.h> |
38 | #include <asm/8xx_immap.h> | |
b5677d84 | 39 | #include <asm/cpm1.h> |
df34403d | 40 | #include <asm/fs_pd.h> |
20906ece | 41 | #include <asm/udbg.h> |
df34403d | 42 | |
02753cb6 | 43 | #include "mpc885ads.h" |
49b51545 | 44 | #include "mpc8xx.h" |
df34403d | 45 | |
20906ece | 46 | static u32 __iomem *bcsr, *bcsr5; |
df34403d | 47 | |
80128ff7 VB |
48 | #ifdef CONFIG_PCMCIA_M8XX |
49 | static void pcmcia_hw_setup(int slot, int enable) | |
50 | { | |
80128ff7 | 51 | if (enable) |
20906ece | 52 | clrbits32(&bcsr[1], BCSR1_PCCEN); |
80128ff7 | 53 | else |
20906ece | 54 | setbits32(&bcsr[1], BCSR1_PCCEN); |
80128ff7 VB |
55 | } |
56 | ||
57 | static int pcmcia_set_voltage(int slot, int vcc, int vpp) | |
58 | { | |
59 | u32 reg = 0; | |
80128ff7 | 60 | |
99121c0d | 61 | switch (vcc) { |
80128ff7 VB |
62 | case 0: |
63 | break; | |
64 | case 33: | |
65 | reg |= BCSR1_PCCVCC0; | |
66 | break; | |
67 | case 50: | |
68 | reg |= BCSR1_PCCVCC1; | |
69 | break; | |
70 | default: | |
71 | return 1; | |
72 | } | |
73 | ||
99121c0d | 74 | switch (vpp) { |
80128ff7 VB |
75 | case 0: |
76 | break; | |
77 | case 33: | |
78 | case 50: | |
99121c0d | 79 | if (vcc == vpp) |
80128ff7 VB |
80 | reg |= BCSR1_PCCVPP1; |
81 | else | |
82 | return 1; | |
83 | break; | |
84 | case 120: | |
85 | if ((vcc == 33) || (vcc == 50)) | |
86 | reg |= BCSR1_PCCVPP0; | |
87 | else | |
88 | return 1; | |
89 | default: | |
90 | return 1; | |
91 | } | |
92 | ||
93 | /* first, turn off all power */ | |
20906ece | 94 | clrbits32(&bcsr[1], 0x00610000); |
80128ff7 VB |
95 | |
96 | /* enable new powersettings */ | |
20906ece | 97 | setbits32(&bcsr[1], reg); |
80128ff7 | 98 | |
80128ff7 VB |
99 | return 0; |
100 | } | |
101 | #endif | |
102 | ||
20906ece SW |
103 | struct cpm_pin { |
104 | int port, pin, flags; | |
105 | }; | |
df34403d | 106 | |
20906ece SW |
107 | static struct cpm_pin mpc885ads_pins[] = { |
108 | /* SMC1 */ | |
109 | {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */ | |
110 | {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ | |
df34403d | 111 | |
20906ece SW |
112 | /* SMC2 */ |
113 | #ifndef CONFIG_MPC8xx_SECOND_ETH_FEC2 | |
114 | {CPM_PORTE, 21, CPM_PIN_INPUT}, /* RX */ | |
115 | {CPM_PORTE, 20, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ | |
df34403d | 116 | #endif |
80128ff7 | 117 | |
20906ece SW |
118 | /* SCC3 */ |
119 | {CPM_PORTA, 9, CPM_PIN_INPUT}, /* RX */ | |
120 | {CPM_PORTA, 8, CPM_PIN_INPUT}, /* TX */ | |
121 | {CPM_PORTC, 4, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* RENA */ | |
122 | {CPM_PORTC, 5, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* CLSN */ | |
123 | {CPM_PORTE, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */ | |
124 | {CPM_PORTE, 17, CPM_PIN_INPUT}, /* CLK5 */ | |
125 | {CPM_PORTE, 16, CPM_PIN_INPUT}, /* CLK6 */ | |
126 | ||
127 | /* MII1 */ | |
128 | {CPM_PORTA, 0, CPM_PIN_INPUT}, | |
129 | {CPM_PORTA, 1, CPM_PIN_INPUT}, | |
130 | {CPM_PORTA, 2, CPM_PIN_INPUT}, | |
131 | {CPM_PORTA, 3, CPM_PIN_INPUT}, | |
132 | {CPM_PORTA, 4, CPM_PIN_OUTPUT}, | |
133 | {CPM_PORTA, 10, CPM_PIN_OUTPUT}, | |
134 | {CPM_PORTA, 11, CPM_PIN_OUTPUT}, | |
135 | {CPM_PORTB, 19, CPM_PIN_INPUT}, | |
136 | {CPM_PORTB, 31, CPM_PIN_INPUT}, | |
137 | {CPM_PORTC, 12, CPM_PIN_INPUT}, | |
138 | {CPM_PORTC, 13, CPM_PIN_INPUT}, | |
139 | {CPM_PORTE, 30, CPM_PIN_OUTPUT}, | |
140 | {CPM_PORTE, 31, CPM_PIN_OUTPUT}, | |
141 | ||
142 | /* MII2 */ | |
143 | #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 | |
144 | {CPM_PORTE, 14, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, | |
145 | {CPM_PORTE, 15, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, | |
146 | {CPM_PORTE, 16, CPM_PIN_OUTPUT}, | |
147 | {CPM_PORTE, 17, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, | |
148 | {CPM_PORTE, 18, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, | |
149 | {CPM_PORTE, 19, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, | |
150 | {CPM_PORTE, 20, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, | |
151 | {CPM_PORTE, 21, CPM_PIN_OUTPUT}, | |
152 | {CPM_PORTE, 22, CPM_PIN_OUTPUT}, | |
153 | {CPM_PORTE, 23, CPM_PIN_OUTPUT}, | |
154 | {CPM_PORTE, 24, CPM_PIN_OUTPUT}, | |
155 | {CPM_PORTE, 25, CPM_PIN_OUTPUT}, | |
156 | {CPM_PORTE, 26, CPM_PIN_OUTPUT}, | |
157 | {CPM_PORTE, 27, CPM_PIN_OUTPUT}, | |
158 | {CPM_PORTE, 28, CPM_PIN_OUTPUT}, | |
159 | {CPM_PORTE, 29, CPM_PIN_OUTPUT}, | |
80128ff7 | 160 | #endif |
20906ece | 161 | }; |
df34403d | 162 | |
20906ece | 163 | static void __init init_ioports(void) |
df34403d | 164 | { |
20906ece | 165 | int i; |
df34403d | 166 | |
20906ece SW |
167 | for (i = 0; i < ARRAY_SIZE(mpc885ads_pins); i++) { |
168 | struct cpm_pin *pin = &mpc885ads_pins[i]; | |
169 | cpm1_set_pin(pin->port, pin->pin, pin->flags); | |
170 | } | |
df34403d | 171 | |
20906ece SW |
172 | cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX); |
173 | cpm1_clk_setup(CPM_CLK_SMC2, CPM_BRG2, CPM_CLK_RTX); | |
174 | cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_TX); | |
175 | cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_RX); | |
df34403d | 176 | |
20906ece SW |
177 | /* Set FEC1 and FEC2 to MII mode */ |
178 | clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180); | |
df34403d VB |
179 | } |
180 | ||
20906ece | 181 | static void __init mpc885ads_setup_arch(void) |
df34403d | 182 | { |
20906ece | 183 | struct device_node *np; |
df34403d | 184 | |
20906ece SW |
185 | cpm_reset(); |
186 | init_ioports(); | |
df34403d | 187 | |
20906ece SW |
188 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc885ads-bcsr"); |
189 | if (!np) { | |
190 | printk(KERN_CRIT "Could not find fsl,mpc885ads-bcsr node\n"); | |
df34403d VB |
191 | return; |
192 | } | |
df34403d | 193 | |
20906ece SW |
194 | bcsr = of_iomap(np, 0); |
195 | bcsr5 = of_iomap(np, 1); | |
196 | of_node_put(np); | |
df34403d | 197 | |
20906ece | 198 | if (!bcsr || !bcsr5) { |
df34403d VB |
199 | printk(KERN_CRIT "Could not remap BCSR\n"); |
200 | return; | |
201 | } | |
202 | ||
20906ece SW |
203 | clrbits32(&bcsr[1], BCSR1_RS232EN_1); |
204 | #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 | |
205 | setbits32(&bcsr[1], BCSR1_RS232EN_2); | |
206 | #else | |
207 | clrbits32(&bcsr[1], BCSR1_RS232EN_2); | |
208 | #endif | |
df34403d | 209 | |
20906ece SW |
210 | clrbits32(bcsr5, BCSR5_MII1_EN); |
211 | setbits32(bcsr5, BCSR5_MII1_RST); | |
212 | udelay(1000); | |
213 | clrbits32(bcsr5, BCSR5_MII1_RST); | |
df34403d | 214 | |
20906ece SW |
215 | #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 |
216 | clrbits32(bcsr5, BCSR5_MII2_EN); | |
217 | setbits32(bcsr5, BCSR5_MII2_RST); | |
218 | udelay(1000); | |
219 | clrbits32(bcsr5, BCSR5_MII2_RST); | |
220 | #else | |
221 | setbits32(bcsr5, BCSR5_MII2_EN); | |
222 | #endif | |
df34403d | 223 | |
20906ece SW |
224 | #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3 |
225 | clrbits32(&bcsr[4], BCSR4_ETH10_RST); | |
226 | udelay(1000); | |
227 | setbits32(&bcsr[4], BCSR4_ETH10_RST); | |
df34403d | 228 | |
20906ece | 229 | setbits32(&bcsr[1], BCSR1_ETHEN); |
df34403d | 230 | |
20906ece SW |
231 | np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80"); |
232 | #else | |
233 | np = of_find_node_by_path("/soc@ff000000/cpm@9c0/ethernet@a40"); | |
234 | #endif | |
df34403d | 235 | |
20906ece SW |
236 | /* The SCC3 enet registers overlap the SMC1 registers, so |
237 | * one of the two must be removed from the device tree. | |
238 | */ | |
df34403d | 239 | |
20906ece SW |
240 | if (np) { |
241 | of_detach_node(np); | |
242 | of_node_put(np); | |
df34403d | 243 | } |
df34403d | 244 | |
20906ece SW |
245 | #ifdef CONFIG_PCMCIA_M8XX |
246 | /* Set up board specific hook-ups.*/ | |
247 | m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup; | |
248 | m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage; | |
249 | #endif | |
df34403d VB |
250 | } |
251 | ||
20906ece | 252 | static int __init mpc885ads_probe(void) |
df34403d | 253 | { |
20906ece SW |
254 | unsigned long root = of_get_flat_dt_root(); |
255 | return of_flat_dt_is_compatible(root, "fsl,mpc885ads"); | |
df34403d VB |
256 | } |
257 | ||
20906ece SW |
258 | static struct of_device_id __initdata of_bus_ids[] = { |
259 | { .name = "soc", }, | |
260 | { .name = "cpm", }, | |
261 | { .name = "localbus", }, | |
262 | {}, | |
263 | }; | |
df34403d | 264 | |
20906ece | 265 | static int __init declare_of_platform_devices(void) |
df34403d | 266 | { |
20906ece | 267 | /* Publish the QE devices */ |
6869e4ad | 268 | of_platform_bus_probe(NULL, of_bus_ids, NULL); |
df34403d VB |
269 | |
270 | return 0; | |
271 | } | |
6869e4ad | 272 | machine_device_initcall(mpc885_ads, declare_of_platform_devices); |
20906ece SW |
273 | |
274 | define_machine(mpc885_ads) { | |
275 | .name = "Freescale MPC885 ADS", | |
276 | .probe = mpc885ads_probe, | |
277 | .setup_arch = mpc885ads_setup_arch, | |
d0a02a06 | 278 | .init_IRQ = mpc8xx_pics_init, |
20906ece SW |
279 | .get_irq = mpc8xx_get_irq, |
280 | .restart = mpc8xx_restart, | |
281 | .calibrate_decr = mpc8xx_calibrate_decr, | |
282 | .set_rtc_time = mpc8xx_set_rtc_time, | |
283 | .get_rtc_time = mpc8xx_get_rtc_time, | |
284 | .progress = udbg_progress, | |
408e83a6 | 285 | }; |