1 /*arch/ppc/platforms/mpc866ads-setup.c
3 * Platform setup for the Freescale mpc866ads board
5 * Vitaly Bordug <vbordug@ru.mvista.com>
7 * Copyright 2005-2006 MontaVista Software Inc.
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.
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>
21 #include <linux/fs_enet_pd.h>
22 #include <linux/fs_uart_pd.h>
23 #include <linux/mii.h>
25 #include <asm/delay.h>
27 #include <asm/machdep.h>
29 #include <asm/processor.h>
30 #include <asm/system.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>
38 extern unsigned char __res
[];
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);
45 static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata
;
47 static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata
;
49 static struct fs_platform_info mpc8xx_enet_pdata
[] = {
58 .init_ioports
= setup_fec1_ioports
,
71 .init_ioports
= setup_scc1_ioports
,
73 .bus_id
= "fixed@100:1",
77 static struct fs_uart_platform_info mpc866_uart_pdata
[] = {
80 .fs_no
= fsid_smc1_uart
,
81 .init_ioports
= setup_smc1_ioports
,
89 .fs_no
= fsid_smc2_uart
,
90 .init_ioports
= setup_smc2_ioports
,
98 void __init
board_init(void)
100 volatile cpm8xx_t
*cp
= cpmp
;
103 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
105 if (bcsr_io
== NULL
) {
106 printk(KERN_CRIT
"Could not remap BCSR1\n");
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
);
116 setbits32(bcsr_io
,(0x80000000 >> 7));
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;
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
);
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;
140 static void setup_fec1_ioports(struct fs_platform_info
*)
142 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
144 setbits16(&immap
->im_ioport
.iop_pdpar
, 0x1fff);
145 setbits16(&immap
->im_ioport
.iop_pddir
, 0x1fff);
148 static void setup_scc1_ioports(struct fs_platform_info
*)
150 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
153 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
155 if (bcsr_io
== NULL
) {
156 printk(KERN_CRIT
"Could not remap BCSR1\n");
162 clrbits32(bcsr_io
,BCSR1_ETHEN
);
164 /* Configure port A pins for Txd and Rxd.
166 /* Disable receive and transmit in case EPPC-Bug started it.
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
);
172 /* Configure port C pins to enable CLSN and RENA.
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.
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
);
184 /* Configure Serial Interface clock routing.
185 * First, clear all SCC bits to zero, then set the ones we want.
187 clrbits32(&immap
->im_cpm
.cp_sicr
, SICR_ENET_MASK
);
188 setbits32(&immap
->im_cpm
.cp_sicr
, SICR_ENET_CLKRT
);
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
);
197 static void setup_smc1_ioports(struct fs_uart_platform_info
*)
199 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
201 unsigned int iobits
= 0x000000c0;
203 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
205 if (bcsr_io
== NULL
) {
206 printk(KERN_CRIT
"Could not remap BCSR1\n");
210 clrbits32(bcsr_io
,BCSR1_RS232EN_1
);
213 setbits32(&immap
->im_cpm
.cp_pbpar
, iobits
);
214 clrbits32(&immap
->im_cpm
.cp_pbdir
, iobits
);
215 clrbits16(&immap
->im_cpm
.cp_pbodr
, iobits
);
219 static void setup_smc2_ioports(struct fs_uart_platform_info
*)
221 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
223 unsigned int iobits
= 0x00000c00;
225 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
227 if (bcsr_io
== NULL
) {
228 printk(KERN_CRIT
"Could not remap BCSR1\n");
232 clrbits32(bcsr_io
,BCSR1_RS232EN_2
);
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
);
241 setbits16(&immap
->im_ioport
.iop_papar
, iobits
);
242 clrbits16(&immap
->im_ioport
.iop_padir
, iobits
);
243 clrbits16(&immap
->im_ioport
.iop_paodr
, iobits
);
248 static int ma_count
= 0;
250 static void mpc866ads_fixup_enet_pdata(struct platform_device
*pdev
, int fs_no
)
252 struct fs_platform_info
*fpi
;
254 volatile cpm8xx_t
*cp
;
255 bd_t
*bd
= (bd_t
*) __res
;
259 /* Get pointer to Communication Processor */
262 if(fs_no
>= ARRAY_SIZE(mpc8xx_enet_pdata
)) {
263 printk(KERN_ERR
"No network-suitable #%d device on bus", fs_no
);
268 fpi
= &mpc8xx_enet_pdata
[fs_no
];
270 pdev
->dev
.platform_data
= fpi
;
272 e
= (unsigned char *)&bd
->bi_enetaddr
;
273 for (i
= 0; i
< 6; i
++)
274 fpi
->macaddr
[i
] = *e
++;
276 fpi
->macaddr
[5] += ma_count
++;
279 static void mpc866ads_fixup_fec_enet_pdata(struct platform_device
*pdev
,
282 /* This is for FEC devices only */
283 if (!pdev
|| !pdev
->name
|| (!strstr(pdev
->name
, "fsl-cpm-fec")))
285 mpc866ads_fixup_enet_pdata(pdev
, fsid_fec1
+ pdev
->id
- 1);
288 static void mpc866ads_fixup_scc_enet_pdata(struct platform_device
*pdev
,
291 /* This is for SCC devices only */
292 if (!pdev
|| !pdev
->name
|| (!strstr(pdev
->name
, "fsl-cpm-scc")))
295 mpc866ads_fixup_enet_pdata(pdev
, fsid_scc1
+ pdev
->id
- 1);
298 static void __init
mpc866ads_fixup_uart_pdata(struct platform_device
*pdev
,
301 bd_t
*bd
= (bd_t
*) __res
;
302 struct fs_uart_platform_info
*pinfo
;
303 int num
= ARRAY_SIZE(mpc866_uart_pdata
);
305 int id
= fs_uart_id_smc2fsid(idx
);
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
;
315 static int mpc866ads_platform_notify(struct device
*dev
)
317 static const struct platform_notify_dev_map dev_map
[] = {
319 .bus_id
= "fsl-cpm-fec",
320 .rtn
= mpc866ads_fixup_fec_enet_pdata
,
323 .bus_id
= "fsl-cpm-scc",
324 .rtn
= mpc866ads_fixup_scc_enet_pdata
,
327 .bus_id
= "fsl-cpm-smc:uart",
328 .rtn
= mpc866ads_fixup_uart_pdata
335 platform_notify_map(dev_map
,dev
);
340 int __init
mpc866ads_init(void)
342 bd_t
*bd
= (bd_t
*) __res
;
343 struct fs_mii_fec_platform_info
* fmpi
;
345 printk(KERN_NOTICE
"mpc866ads: Init\n");
347 platform_notify
= mpc866ads_platform_notify
;
349 ppc_sys_device_initfunc();
350 ppc_sys_device_disable_all();
352 #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC1
353 ppc_sys_device_enable(MPC8xx_CPM_SCC1
);
355 ppc_sys_device_enable(MPC8xx_CPM_FEC1
);
357 ppc_sys_device_enable(MPC8xx_MDIO_FEC
);
359 fmpi
= ppc_sys_platform_devices
[MPC8xx_MDIO_FEC
].dev
.platform_data
=
360 &mpc8xx_mdio_fec_pdata
;
362 fmpi
->mii_speed
= ((((bd
->bi_intfreq
+ 4999999) / 2500000) / 2) & 0x3F) << 1;
363 /* No PHY interrupt line here */
364 fmpi
->irq
[0xf] = PHY_POLL
;
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
);
372 #ifdef CONFIG_SERIAL_CPM_SMC2
373 ppc_sys_device_enable(MPC8xx_CPM_SMC2
);
374 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2
, PPC_SYS_FUNC_UART
);
376 ppc_sys_device_enable(MPC8xx_MDIO_FEC
);
378 fmpi
= ppc_sys_platform_devices
[MPC8xx_MDIO_FEC
].dev
.platform_data
=
379 &mpc8xx_mdio_fec_pdata
;
381 fmpi
->mii_speed
= ((((bd
->bi_intfreq
+ 4999999) / 2500000) / 2) & 0x3F) << 1;
382 /* No PHY interrupt line here */
383 fmpi
->irq
[0xf] = PHY_POLL
;
389 To prevent confusion, console selection is gross:
390 by 0 assumed SMC1 and by 1 assumed SMC2
392 struct platform_device
* early_uart_get_pdev(int index
)
394 bd_t
*bd
= (bd_t
*) __res
;
395 struct fs_uart_platform_info
*pinfo
;
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];
406 pinfo
->uart_clk
= bd
->bi_intfreq
;
407 pdev
->dev
.platform_data
= pinfo
;
408 ppc_sys_fixup_mem_resource(pdev
, IMAP_ADDR
);
412 arch_initcall(mpc866ads_init
);