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