Merge branch 'upstream' of git://lost.foo-projects.org/~ahkok/git/netdev-2.6 into...
[linux-2.6] / arch / ppc / platforms / mpc885ads_setup.c
1 /*arch/ppc/platforms/mpc885ads-setup.c
2  *
3  * Platform setup for the Freescale mpc885ads board
4  *
5  * Vitaly Bordug <vbordug@ru.mvista.com>
6  *
7  * Copyright 2005 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
37 extern unsigned char __res[];
38 static void setup_smc1_ioports(void);
39 static void setup_smc2_ioports(void);
40
41 static void __init mpc885ads_scc_phy_init(char);
42
43 static struct fs_uart_platform_info mpc885_uart_pdata[] = {
44         [fsid_smc1_uart] = {
45                 .brg            = 1,
46                 .fs_no          = fsid_smc1_uart,
47                 .init_ioports   = setup_smc1_ioports,
48                 .tx_num_fifo    = 4,
49                 .tx_buf_size    = 32,
50                 .rx_num_fifo    = 4,
51                 .rx_buf_size    = 32,
52         },
53         [fsid_smc2_uart] = {
54                 .brg            = 2,
55                 .fs_no          = fsid_smc2_uart,
56                 .init_ioports   = setup_smc2_ioports,
57                 .tx_num_fifo    = 4,
58                 .tx_buf_size    = 32,
59                 .rx_num_fifo    = 4,
60                 .rx_buf_size    = 32,
61         },
62 };
63
64 static struct fs_mii_bus_info fec_mii_bus_info = {
65         .method = fsmii_fec,
66         .id = 0,
67 };
68
69 static struct fs_mii_bus_info scc_mii_bus_info = {
70 #ifdef CONFIG_SCC_ENET_8xx_FIXED
71         .method = fsmii_fixed,
72 #else
73         .method = fsmii_fec,
74 #endif
75
76         .id = 0,
77 };
78
79 static struct fs_platform_info mpc8xx_fec_pdata[] = {
80         {
81          .rx_ring = 128,
82          .tx_ring = 16,
83          .rx_copybreak = 240,
84
85          .use_napi = 1,
86          .napi_weight = 17,
87
88          .phy_addr = 0,
89          .phy_irq = SIU_IRQ7,
90
91          .bus_info = &fec_mii_bus_info,
92          }, {
93              .rx_ring = 128,
94              .tx_ring = 16,
95              .rx_copybreak = 240,
96
97              .use_napi = 1,
98              .napi_weight = 17,
99
100              .phy_addr = 1,
101              .phy_irq = SIU_IRQ7,
102
103              .bus_info = &fec_mii_bus_info,
104              }
105 };
106
107 static struct fs_platform_info mpc8xx_scc_pdata = {
108         .rx_ring = 64,
109         .tx_ring = 8,
110         .rx_copybreak = 240,
111
112         .use_napi = 1,
113         .napi_weight = 17,
114
115         .phy_addr = 2,
116 #ifdef CONFIG_MPC8xx_SCC_ENET_FIXED
117         .phy_irq = -1,
118 #else
119         .phy_irq = SIU_IRQ7,
120 #endif
121
122         .bus_info = &scc_mii_bus_info,
123 };
124
125 void __init board_init(void)
126 {
127         volatile cpm8xx_t *cp = cpmp;
128         unsigned int *bcsr_io;
129
130 #ifdef CONFIG_FS_ENET
131         immap_t *immap = (immap_t *) IMAP_ADDR;
132 #endif
133         bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
134
135         if (bcsr_io == NULL) {
136                 printk(KERN_CRIT "Could not remap BCSR\n");
137                 return;
138         }
139 #ifdef CONFIG_SERIAL_CPM_SMC1
140         cp->cp_simode &= ~(0xe0000000 >> 17);   /* brg1 */
141         clrbits32(bcsr_io, BCSR1_RS232EN_1);
142         cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
143         cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
144 #else
145         setbits32(bcsr_io,BCSR1_RS232EN_1);
146         cp->cp_smc[0].smc_smcmr = 0;
147         cp->cp_smc[0].smc_smce = 0;
148 #endif
149
150 #ifdef CONFIG_SERIAL_CPM_SMC2
151         cp->cp_simode &= ~(0xe0000000 >> 1);
152         cp->cp_simode |= (0x20000000 >> 1);     /* brg2 */
153         clrbits32(bcsr_io,BCSR1_RS232EN_2);
154         cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
155         cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
156 #else
157         setbits32(bcsr_io,BCSR1_RS232EN_2);
158         cp->cp_smc[1].smc_smcmr = 0;
159         cp->cp_smc[1].smc_smce = 0;
160 #endif
161         iounmap(bcsr_io);
162
163 #ifdef CONFIG_FS_ENET
164         /* use MDC for MII (common) */
165         setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
166         clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
167 #endif
168 }
169
170 static void setup_fec1_ioports(void)
171 {
172         immap_t *immap = (immap_t *) IMAP_ADDR;
173
174         /* configure FEC1 pins  */
175         setbits16(&immap->im_ioport.iop_papar, 0xf830);
176         setbits16(&immap->im_ioport.iop_padir, 0x0830);
177         clrbits16(&immap->im_ioport.iop_padir, 0xf000);
178         setbits32(&immap->im_cpm.cp_pbpar, 0x00001001);
179
180         clrbits32(&immap->im_cpm.cp_pbdir, 0x00001001);
181         setbits16(&immap->im_ioport.iop_pcpar, 0x000c);
182         clrbits16(&immap->im_ioport.iop_pcdir, 0x000c);
183         setbits32(&immap->im_cpm.cp_pepar, 0x00000003);
184
185         setbits32(&immap->im_cpm.cp_pedir, 0x00000003);
186         clrbits32(&immap->im_cpm.cp_peso, 0x00000003);
187         clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
188 }
189
190 static void setup_fec2_ioports(void)
191 {
192         immap_t *immap = (immap_t *) IMAP_ADDR;
193
194         /* configure FEC2 pins */
195         setbits32(&immap->im_cpm.cp_pepar, 0x0003fffc);
196         setbits32(&immap->im_cpm.cp_pedir, 0x0003fffc);
197         setbits32(&immap->im_cpm.cp_peso, 0x00037800);
198         clrbits32(&immap->im_cpm.cp_peso, 0x000087fc);
199         clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
200 }
201
202 static void setup_scc3_ioports(void)
203 {
204         immap_t *immap = (immap_t *) IMAP_ADDR;
205         unsigned *bcsr_io;
206
207         bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE);
208
209         if (bcsr_io == NULL) {
210                 printk(KERN_CRIT "Could not remap BCSR\n");
211                 return;
212         }
213
214         /* Enable the PHY.
215          */
216         setbits32(bcsr_io+4, BCSR4_ETH10_RST);
217         /* Configure port A pins for Txd and Rxd.
218          */
219         setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
220         clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
221
222         /* Configure port C pins to enable CLSN and RENA.
223          */
224         clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
225         clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
226         setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
227
228         /* Configure port E for TCLK and RCLK.
229          */
230         setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TCLK | PE_ENET_RCLK);
231         clrbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA);
232         clrbits32(&immap->im_cpm.cp_pedir,
233                   PE_ENET_TCLK | PE_ENET_RCLK | PE_ENET_TENA);
234         clrbits32(&immap->im_cpm.cp_peso, PE_ENET_TCLK | PE_ENET_RCLK);
235         setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
236
237         /* Configure Serial Interface clock routing.
238          * First, clear all SCC bits to zero, then set the ones we want.
239          */
240         clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
241         setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
242
243         /* Disable Rx and Tx. SMC1 sshould be stopped if SCC3 eternet are used.
244          */
245         immap->im_cpm.cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
246         /* On the MPC885ADS SCC ethernet PHY is initialized in the full duplex mode
247          * by H/W setting after reset. SCC ethernet controller support only half duplex.
248          * This discrepancy of modes causes a lot of carrier lost errors.
249          */
250
251         /* In the original SCC enet driver the following code is placed at
252            the end of the initialization */
253         setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA);
254         clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TENA);
255         setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
256
257         setbits32(bcsr_io+1, BCSR1_ETHEN);
258         iounmap(bcsr_io);
259 }
260
261 static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
262 {
263         struct fs_platform_info *fpi = pdev->dev.platform_data;
264
265         volatile cpm8xx_t *cp;
266         bd_t *bd = (bd_t *) __res;
267         char *e;
268         int i;
269
270         /* Get pointer to Communication Processor */
271         cp = cpmp;
272         switch (fs_no) {
273         case fsid_fec1:
274                 fpi = &mpc8xx_fec_pdata[0];
275                 fpi->init_ioports = &setup_fec1_ioports;
276                 break;
277         case fsid_fec2:
278                 fpi = &mpc8xx_fec_pdata[1];
279                 fpi->init_ioports = &setup_fec2_ioports;
280                 break;
281         case fsid_scc3:
282                 fpi = &mpc8xx_scc_pdata;
283                 fpi->init_ioports = &setup_scc3_ioports;
284                 mpc885ads_scc_phy_init(fpi->phy_addr);
285                 break;
286         default:
287                 printk(KERN_WARNING"Device %s is not supported!\n", pdev->name);
288                 return;
289         }
290
291         pdev->dev.platform_data = fpi;
292         fpi->fs_no = fs_no;
293
294         e = (unsigned char *)&bd->bi_enetaddr;
295         for (i = 0; i < 6; i++)
296                 fpi->macaddr[i] = *e++;
297
298         fpi->macaddr[5 - pdev->id]++;
299
300 }
301
302 static void mpc885ads_fixup_fec_enet_pdata(struct platform_device *pdev,
303                                            int idx)
304 {
305         /* This is for FEC devices only */
306         if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
307                 return;
308         mpc885ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
309 }
310
311 static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev,
312                                                   int idx)
313 {
314         /* This is for SCC devices only */
315         if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
316                 return;
317
318         mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
319 }
320
321 /* SCC ethernet controller does not have MII management channel. FEC1 MII
322  * channel is used to communicate with the 10Mbit PHY.
323  */
324
325 #define MII_ECNTRL_PINMUX        0x4
326 #define FEC_ECNTRL_PINMUX        0x00000004
327 #define FEC_RCNTRL_MII_MODE        0x00000004
328
329 /* Make MII read/write commands.
330  */
331 #define mk_mii_write(REG, VAL, PHY_ADDR)    (0x50020000 | (((REG) & 0x1f) << 18) | \
332                 ((VAL) & 0xffff) | ((PHY_ADDR) << 23))
333
334 static void mpc885ads_scc_phy_init(char phy_addr)
335 {
336         volatile immap_t *immap;
337         volatile fec_t *fecp;
338         bd_t *bd;
339
340         bd = (bd_t *) __res;
341         immap = (immap_t *) IMAP_ADDR;  /* pointer to internal registers */
342         fecp = &(immap->im_cpm.cp_fec);
343
344         /* Enable MII pins of the FEC1
345          */
346         setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
347         clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
348         /* Set MII speed to 2.5 MHz
349          */
350         out_be32(&fecp->fec_mii_speed,
351                  ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1);
352
353         /* Enable FEC pin MUX
354          */
355         setbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
356         setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
357
358         out_be32(&fecp->fec_mii_data,
359                  mk_mii_write(MII_BMCR, BMCR_ISOLATE, phy_addr));
360         udelay(100);
361         out_be32(&fecp->fec_mii_data,
362                  mk_mii_write(MII_ADVERTISE,
363                               ADVERTISE_10HALF | ADVERTISE_CSMA, phy_addr));
364         udelay(100);
365
366         /* Disable FEC MII settings
367          */
368         clrbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
369         clrbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
370         out_be32(&fecp->fec_mii_speed, 0);
371 }
372
373 static void setup_smc1_ioports(void)
374 {
375         immap_t *immap = (immap_t *) IMAP_ADDR;
376         unsigned *bcsr_io;
377         unsigned int iobits = 0x000000c0;
378
379         bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
380
381         if (bcsr_io == NULL) {
382                 printk(KERN_CRIT "Could not remap BCSR1\n");
383                 return;
384         }
385         clrbits32(bcsr_io,BCSR1_RS232EN_1);
386         iounmap(bcsr_io);
387
388         setbits32(&immap->im_cpm.cp_pbpar, iobits);
389         clrbits32(&immap->im_cpm.cp_pbdir, iobits);
390         clrbits16(&immap->im_cpm.cp_pbodr, iobits);
391 }
392
393 static void setup_smc2_ioports(void)
394 {
395         immap_t *immap = (immap_t *) IMAP_ADDR;
396         unsigned *bcsr_io;
397         unsigned int iobits = 0x00000c00;
398
399         bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
400
401         if (bcsr_io == NULL) {
402                 printk(KERN_CRIT "Could not remap BCSR1\n");
403                 return;
404         }
405         clrbits32(bcsr_io,BCSR1_RS232EN_2);
406         iounmap(bcsr_io);
407
408 #ifndef CONFIG_SERIAL_CPM_ALT_SMC2
409         setbits32(&immap->im_cpm.cp_pbpar, iobits);
410         clrbits32(&immap->im_cpm.cp_pbdir, iobits);
411         clrbits16(&immap->im_cpm.cp_pbodr, iobits);
412 #else
413         setbits16(&immap->im_ioport.iop_papar, iobits);
414         clrbits16(&immap->im_ioport.iop_padir, iobits);
415         clrbits16(&immap->im_ioport.iop_paodr, iobits);
416 #endif
417 }
418
419 static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev,
420                                               int idx)
421 {
422         bd_t *bd = (bd_t *) __res;
423         struct fs_uart_platform_info *pinfo;
424         int num = ARRAY_SIZE(mpc885_uart_pdata);
425
426         int id = fs_uart_id_smc2fsid(idx);
427
428         /* no need to alter anything if console */
429         if ((id <= num) && (!pdev->dev.platform_data)) {
430                 pinfo = &mpc885_uart_pdata[id];
431                 pinfo->uart_clk = bd->bi_intfreq;
432                 pdev->dev.platform_data = pinfo;
433         }
434 }
435
436
437 static int mpc885ads_platform_notify(struct device *dev)
438 {
439
440         static const struct platform_notify_dev_map dev_map[] = {
441                 {
442                         .bus_id = "fsl-cpm-fec",
443                         .rtn = mpc885ads_fixup_fec_enet_pdata,
444                 },
445                 {
446                         .bus_id = "fsl-cpm-scc",
447                         .rtn = mpc885ads_fixup_scc_enet_pdata,
448                 },
449                 {
450                         .bus_id = "fsl-cpm-smc:uart",
451                         .rtn = mpc885ads_fixup_uart_pdata
452                 },
453                 {
454                         .bus_id = NULL
455                 }
456         };
457
458         platform_notify_map(dev_map,dev);
459
460         return 0;
461 }
462
463 int __init mpc885ads_init(void)
464 {
465         printk(KERN_NOTICE "mpc885ads: Init\n");
466
467         platform_notify = mpc885ads_platform_notify;
468
469         ppc_sys_device_initfunc();
470         ppc_sys_device_disable_all();
471
472         ppc_sys_device_enable(MPC8xx_CPM_FEC1);
473
474 #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
475         ppc_sys_device_enable(MPC8xx_CPM_SCC1);
476
477 #endif
478 #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
479         ppc_sys_device_enable(MPC8xx_CPM_FEC2);
480 #endif
481
482 #ifdef CONFIG_SERIAL_CPM_SMC1
483         ppc_sys_device_enable(MPC8xx_CPM_SMC1);
484         ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
485 #endif
486
487 #ifdef CONFIG_SERIAL_CPM_SMC2
488         ppc_sys_device_enable(MPC8xx_CPM_SMC2);
489         ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
490 #endif
491         return 0;
492 }
493
494 arch_initcall(mpc885ads_init);
495
496 /*
497    To prevent confusion, console selection is gross:
498    by 0 assumed SMC1 and by 1 assumed SMC2
499  */
500 struct platform_device* early_uart_get_pdev(int index)
501 {
502         bd_t *bd = (bd_t *) __res;
503         struct fs_uart_platform_info *pinfo;
504
505         struct platform_device* pdev = NULL;
506         if(index) { /*assume SMC2 here*/
507                 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
508                 pinfo = &mpc885_uart_pdata[1];
509         } else { /*over SMC1*/
510                 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
511                 pinfo = &mpc885_uart_pdata[0];
512         }
513
514         pinfo->uart_clk = bd->bi_intfreq;
515         pdev->dev.platform_data = pinfo;
516         ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
517         return NULL;
518 }
519