POWERPC: overhaul with cpm2_map mechanism
[deliverable/linux.git] / arch / ppc / platforms / mpc866ads_setup.c
1 /*arch/ppc/platforms/mpc866ads-setup.c
2 *
3 * Platform setup for the Freescale mpc866ads board
4 *
5 * Vitaly Bordug <vbordug@ru.mvista.com>
6 *
7 * Copyright 2005-2006 MontaVista Software Inc.
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 */
13
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/param.h>
17 #include <linux/string.h>
18 #include <linux/ioport.h>
19 #include <linux/device.h>
20
21 #include <linux/fs_enet_pd.h>
22 #include <linux/fs_uart_pd.h>
23 #include <linux/mii.h>
24
25 #include <asm/delay.h>
26 #include <asm/io.h>
27 #include <asm/machdep.h>
28 #include <asm/page.h>
29 #include <asm/processor.h>
30 #include <asm/system.h>
31 #include <asm/time.h>
32 #include <asm/ppcboot.h>
33 #include <asm/8xx_immap.h>
34 #include <asm/commproc.h>
35 #include <asm/ppc_sys.h>
36 #include <asm/mpc8xx.h>
37
38 extern unsigned char __res[];
39
40 static void setup_fec1_ioports(void);
41 static void setup_scc1_ioports(void);
42 static void setup_smc1_ioports(void);
43 static void setup_smc2_ioports(void);
44
45 static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
46
47 static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
48
49 static struct fs_platform_info mpc8xx_enet_pdata[] = {
50 [fsid_fec1] = {
51 .rx_ring = 128,
52 .tx_ring = 16,
53 .rx_copybreak = 240,
54
55 .use_napi = 1,
56 .napi_weight = 17,
57
58 .init_ioports = setup_fec1_ioports,
59
60 .bus_id = "0:0f",
61 .has_phy = 1,
62 },
63 [fsid_scc1] = {
64 .rx_ring = 64,
65 .tx_ring = 8,
66 .rx_copybreak = 240,
67 .use_napi = 1,
68 .napi_weight = 17,
69
70
71 .init_ioports = setup_scc1_ioports,
72
73 .bus_id = "fixed@100:1",
74 },
75 };
76
77 static struct fs_uart_platform_info mpc866_uart_pdata[] = {
78 [fsid_smc1_uart] = {
79 .brg = 1,
80 .fs_no = fsid_smc1_uart,
81 .init_ioports = setup_smc1_ioports,
82 .tx_num_fifo = 4,
83 .tx_buf_size = 32,
84 .rx_num_fifo = 4,
85 .rx_buf_size = 32,
86 },
87 [fsid_smc2_uart] = {
88 .brg = 2,
89 .fs_no = fsid_smc2_uart,
90 .init_ioports = setup_smc2_ioports,
91 .tx_num_fifo = 4,
92 .tx_buf_size = 32,
93 .rx_num_fifo = 4,
94 .rx_buf_size = 32,
95 },
96 };
97
98 void __init board_init(void)
99 {
100 volatile cpm8xx_t *cp = cpmp;
101 unsigned *bcsr_io;
102
103 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
104
105 if (bcsr_io == NULL) {
106 printk(KERN_CRIT "Could not remap BCSR1\n");
107 return;
108 }
109
110 #ifdef CONFIG_SERIAL_CPM_SMC1
111 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
112 clrbits32(bcsr_io,(0x80000000 >> 7));
113 cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
114 cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
115 #else
116 setbits32(bcsr_io,(0x80000000 >> 7));
117
118 cp->cp_pbpar &= ~(0x000000c0);
119 cp->cp_pbdir |= 0x000000c0;
120 cp->cp_smc[0].smc_smcmr = 0;
121 cp->cp_smc[0].smc_smce = 0;
122 #endif
123
124 #ifdef CONFIG_SERIAL_CPM_SMC2
125 cp->cp_simode &= ~(0xe0000000 >> 1);
126 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
127 clrbits32(bcsr_io,(0x80000000 >> 13));
128 cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
129 cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
130 #else
131 clrbits32(bcsr_io,(0x80000000 >> 13));
132 cp->cp_pbpar &= ~(0x00000c00);
133 cp->cp_pbdir |= 0x00000c00;
134 cp->cp_smc[1].smc_smcmr = 0;
135 cp->cp_smc[1].smc_smce = 0;
136 #endif
137 iounmap(bcsr_io);
138 }
139
140 static void setup_fec1_ioports(struct fs_platform_info*)
141 {
142 immap_t *immap = (immap_t *) IMAP_ADDR;
143
144 setbits16(&immap->im_ioport.iop_pdpar, 0x1fff);
145 setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
146 }
147
148 static void setup_scc1_ioports(struct fs_platform_info*)
149 {
150 immap_t *immap = (immap_t *) IMAP_ADDR;
151 unsigned *bcsr_io;
152
153 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
154
155 if (bcsr_io == NULL) {
156 printk(KERN_CRIT "Could not remap BCSR1\n");
157 return;
158 }
159
160 /* Enable the PHY.
161 */
162 clrbits32(bcsr_io,BCSR1_ETHEN);
163
164 /* Configure port A pins for Txd and Rxd.
165 */
166 /* Disable receive and transmit in case EPPC-Bug started it.
167 */
168 setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
169 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
170 clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD);
171
172 /* Configure port C pins to enable CLSN and RENA.
173 */
174 clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
175 clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
176 setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
177 /* Configure port A for TCLK and RCLK.
178 */
179 setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
180 clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
181 clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
182 clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
183
184 /* Configure Serial Interface clock routing.
185 * First, clear all SCC bits to zero, then set the ones we want.
186 */
187 clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
188 setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
189
190 /* In the original SCC enet driver the following code is placed at
191 the end of the initialization */
192 setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
193 setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
194
195 }
196
197 static void setup_smc1_ioports(struct fs_uart_platform_info*)
198 {
199 immap_t *immap = (immap_t *) IMAP_ADDR;
200 unsigned *bcsr_io;
201 unsigned int iobits = 0x000000c0;
202
203 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
204
205 if (bcsr_io == NULL) {
206 printk(KERN_CRIT "Could not remap BCSR1\n");
207 return;
208 }
209
210 clrbits32(bcsr_io,BCSR1_RS232EN_1);
211 iounmap(bcsr_io);
212
213 setbits32(&immap->im_cpm.cp_pbpar, iobits);
214 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
215 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
216
217 }
218
219 static void setup_smc2_ioports(struct fs_uart_platform_info*)
220 {
221 immap_t *immap = (immap_t *) IMAP_ADDR;
222 unsigned *bcsr_io;
223 unsigned int iobits = 0x00000c00;
224
225 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
226
227 if (bcsr_io == NULL) {
228 printk(KERN_CRIT "Could not remap BCSR1\n");
229 return;
230 }
231
232 clrbits32(bcsr_io,BCSR1_RS232EN_2);
233
234 iounmap(bcsr_io);
235
236 #ifndef CONFIG_SERIAL_CPM_ALT_SMC2
237 setbits32(&immap->im_cpm.cp_pbpar, iobits);
238 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
239 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
240 #else
241 setbits16(&immap->im_ioport.iop_papar, iobits);
242 clrbits16(&immap->im_ioport.iop_padir, iobits);
243 clrbits16(&immap->im_ioport.iop_paodr, iobits);
244 #endif
245
246 }
247
248 static int ma_count = 0;
249
250 static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
251 {
252 struct fs_platform_info *fpi;
253
254 volatile cpm8xx_t *cp;
255 bd_t *bd = (bd_t *) __res;
256 char *e;
257 int i;
258
259 /* Get pointer to Communication Processor */
260 cp = cpmp;
261
262 if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) {
263 printk(KERN_ERR"No network-suitable #%d device on bus", fs_no);
264 return;
265 }
266
267
268 fpi = &mpc8xx_enet_pdata[fs_no];
269 fpi->fs_no = fs_no;
270 pdev->dev.platform_data = fpi;
271
272 e = (unsigned char *)&bd->bi_enetaddr;
273 for (i = 0; i < 6; i++)
274 fpi->macaddr[i] = *e++;
275
276 fpi->macaddr[5] += ma_count++;
277 }
278
279 static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev,
280 int idx)
281 {
282 /* This is for FEC devices only */
283 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
284 return;
285 mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
286 }
287
288 static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
289 int idx)
290 {
291 /* This is for SCC devices only */
292 if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
293 return;
294
295 mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
296 }
297
298 static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev,
299 int idx)
300 {
301 bd_t *bd = (bd_t *) __res;
302 struct fs_uart_platform_info *pinfo;
303 int num = ARRAY_SIZE(mpc866_uart_pdata);
304
305 int id = fs_uart_id_smc2fsid(idx);
306
307 /* no need to alter anything if console */
308 if ((id <= num) && (!pdev->dev.platform_data)) {
309 pinfo = &mpc866_uart_pdata[id];
310 pinfo->uart_clk = bd->bi_intfreq;
311 pdev->dev.platform_data = pinfo;
312 }
313 }
314
315 static int mpc866ads_platform_notify(struct device *dev)
316 {
317 static const struct platform_notify_dev_map dev_map[] = {
318 {
319 .bus_id = "fsl-cpm-fec",
320 .rtn = mpc866ads_fixup_fec_enet_pdata,
321 },
322 {
323 .bus_id = "fsl-cpm-scc",
324 .rtn = mpc866ads_fixup_scc_enet_pdata,
325 },
326 {
327 .bus_id = "fsl-cpm-smc:uart",
328 .rtn = mpc866ads_fixup_uart_pdata
329 },
330 {
331 .bus_id = NULL
332 }
333 };
334
335 platform_notify_map(dev_map,dev);
336
337 return 0;
338 }
339
340 int __init mpc866ads_init(void)
341 {
342 bd_t *bd = (bd_t *) __res;
343 struct fs_mii_fec_platform_info* fmpi;
344
345 printk(KERN_NOTICE "mpc866ads: Init\n");
346
347 platform_notify = mpc866ads_platform_notify;
348
349 ppc_sys_device_initfunc();
350 ppc_sys_device_disable_all();
351
352 #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC1
353 ppc_sys_device_enable(MPC8xx_CPM_SCC1);
354 #endif
355 ppc_sys_device_enable(MPC8xx_CPM_FEC1);
356
357 ppc_sys_device_enable(MPC8xx_MDIO_FEC);
358
359 fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data =
360 &mpc8xx_mdio_fec_pdata;
361
362 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
363 /* No PHY interrupt line here */
364 fmpi->irq[0xf] = -1;
365
366 /* Since either of the uarts could be used as console, they need to ready */
367 #ifdef CONFIG_SERIAL_CPM_SMC1
368 ppc_sys_device_enable(MPC8xx_CPM_SMC1);
369 ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
370 #endif
371
372 #ifdef CONFIG_SERIAL_CPM_SMC
373 ppc_sys_device_enable(MPC8xx_CPM_SMC2);
374 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
375 #endif
376 ppc_sys_device_enable(MPC8xx_MDIO_FEC);
377
378 fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data =
379 &mpc8xx_mdio_fec_pdata;
380
381 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
382 /* No PHY interrupt line here */
383 fmpi->irq[0xf] = -1;
384
385 return 0;
386 }
387
388 /*
389 To prevent confusion, console selection is gross:
390 by 0 assumed SMC1 and by 1 assumed SMC2
391 */
392 struct platform_device* early_uart_get_pdev(int index)
393 {
394 bd_t *bd = (bd_t *) __res;
395 struct fs_uart_platform_info *pinfo;
396
397 struct platform_device* pdev = NULL;
398 if(index) { /*assume SMC2 here*/
399 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
400 pinfo = &mpc866_uart_pdata[1];
401 } else { /*over SMC1*/
402 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
403 pinfo = &mpc866_uart_pdata[0];
404 }
405
406 pinfo->uart_clk = bd->bi_intfreq;
407 pdev->dev.platform_data = pinfo;
408 ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
409 return NULL;
410 }
411
412 arch_initcall(mpc866ads_init);
This page took 0.03932 seconds and 5 git commands to generate.