Pull button into test branch
[sfrench/cifs-2.6.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] = PHY_POLL;
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] = PHY_POLL;
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);