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