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>
24 #include <linux/phy.h>
26 #include <asm/delay.h>
28 #include <asm/machdep.h>
30 #include <asm/processor.h>
31 #include <asm/system.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>
39 extern unsigned char __res
[];
41 static void setup_fec1_ioports(struct fs_platform_info
*);
42 static void setup_scc1_ioports(struct fs_platform_info
*);
43 static void setup_smc1_ioports(struct fs_uart_platform_info
*);
44 static void setup_smc2_ioports(struct fs_uart_platform_info
*);
46 static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata
;
48 static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata
;
50 static struct fs_platform_info mpc8xx_enet_pdata
[] = {
59 .init_ioports
= setup_fec1_ioports
,
72 .init_ioports
= setup_scc1_ioports
,
74 .bus_id
= "fixed@100:1",
78 static struct fs_uart_platform_info mpc866_uart_pdata
[] = {
81 .fs_no
= fsid_smc1_uart
,
82 .init_ioports
= setup_smc1_ioports
,
90 .fs_no
= fsid_smc2_uart
,
91 .init_ioports
= setup_smc2_ioports
,
99 void __init
board_init(void)
101 volatile cpm8xx_t
*cp
= cpmp
;
104 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
106 if (bcsr_io
== NULL
) {
107 printk(KERN_CRIT
"Could not remap BCSR1\n");
111 #ifdef CONFIG_SERIAL_CPM_SMC1
112 cp
->cp_simode
&= ~(0xe0000000 >> 17); /* brg1 */
113 clrbits32(bcsr_io
,(0x80000000 >> 7));
114 cp
->cp_smc
[0].smc_smcm
|= (SMCM_RX
| SMCM_TX
);
115 cp
->cp_smc
[0].smc_smcmr
&= ~(SMCMR_REN
| SMCMR_TEN
);
117 setbits32(bcsr_io
,(0x80000000 >> 7));
119 cp
->cp_pbpar
&= ~(0x000000c0);
120 cp
->cp_pbdir
|= 0x000000c0;
121 cp
->cp_smc
[0].smc_smcmr
= 0;
122 cp
->cp_smc
[0].smc_smce
= 0;
125 #ifdef CONFIG_SERIAL_CPM_SMC2
126 cp
->cp_simode
&= ~(0xe0000000 >> 1);
127 cp
->cp_simode
|= (0x20000000 >> 1); /* brg2 */
128 clrbits32(bcsr_io
,(0x80000000 >> 13));
129 cp
->cp_smc
[1].smc_smcm
|= (SMCM_RX
| SMCM_TX
);
130 cp
->cp_smc
[1].smc_smcmr
&= ~(SMCMR_REN
| SMCMR_TEN
);
132 clrbits32(bcsr_io
,(0x80000000 >> 13));
133 cp
->cp_pbpar
&= ~(0x00000c00);
134 cp
->cp_pbdir
|= 0x00000c00;
135 cp
->cp_smc
[1].smc_smcmr
= 0;
136 cp
->cp_smc
[1].smc_smce
= 0;
141 static void setup_fec1_ioports(struct fs_platform_info
* pdata
)
143 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
145 setbits16(&immap
->im_ioport
.iop_pdpar
, 0x1fff);
146 setbits16(&immap
->im_ioport
.iop_pddir
, 0x1fff);
149 static void setup_scc1_ioports(struct fs_platform_info
* pdata
)
151 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
154 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
156 if (bcsr_io
== NULL
) {
157 printk(KERN_CRIT
"Could not remap BCSR1\n");
163 clrbits32(bcsr_io
,BCSR1_ETHEN
);
165 /* Configure port A pins for Txd and Rxd.
167 /* Disable receive and transmit in case EPPC-Bug started it.
169 setbits16(&immap
->im_ioport
.iop_papar
, PA_ENET_RXD
| PA_ENET_TXD
);
170 clrbits16(&immap
->im_ioport
.iop_padir
, PA_ENET_RXD
| PA_ENET_TXD
);
171 clrbits16(&immap
->im_ioport
.iop_paodr
, PA_ENET_TXD
);
173 /* Configure port C pins to enable CLSN and RENA.
175 clrbits16(&immap
->im_ioport
.iop_pcpar
, PC_ENET_CLSN
| PC_ENET_RENA
);
176 clrbits16(&immap
->im_ioport
.iop_pcdir
, PC_ENET_CLSN
| PC_ENET_RENA
);
177 setbits16(&immap
->im_ioport
.iop_pcso
, PC_ENET_CLSN
| PC_ENET_RENA
);
178 /* Configure port A for TCLK and RCLK.
180 setbits16(&immap
->im_ioport
.iop_papar
, PA_ENET_TCLK
| PA_ENET_RCLK
);
181 clrbits16(&immap
->im_ioport
.iop_padir
, PA_ENET_TCLK
| PA_ENET_RCLK
);
182 clrbits32(&immap
->im_cpm
.cp_pbpar
, PB_ENET_TENA
);
183 clrbits32(&immap
->im_cpm
.cp_pbdir
, PB_ENET_TENA
);
185 /* Configure Serial Interface clock routing.
186 * First, clear all SCC bits to zero, then set the ones we want.
188 clrbits32(&immap
->im_cpm
.cp_sicr
, SICR_ENET_MASK
);
189 setbits32(&immap
->im_cpm
.cp_sicr
, SICR_ENET_CLKRT
);
191 /* In the original SCC enet driver the following code is placed at
192 the end of the initialization */
193 setbits32(&immap
->im_cpm
.cp_pbpar
, PB_ENET_TENA
);
194 setbits32(&immap
->im_cpm
.cp_pbdir
, PB_ENET_TENA
);
198 static void setup_smc1_ioports(struct fs_uart_platform_info
* pdata
)
200 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
202 unsigned int iobits
= 0x000000c0;
204 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
206 if (bcsr_io
== NULL
) {
207 printk(KERN_CRIT
"Could not remap BCSR1\n");
211 clrbits32(bcsr_io
,BCSR1_RS232EN_1
);
214 setbits32(&immap
->im_cpm
.cp_pbpar
, iobits
);
215 clrbits32(&immap
->im_cpm
.cp_pbdir
, iobits
);
216 clrbits16(&immap
->im_cpm
.cp_pbodr
, iobits
);
220 static void setup_smc2_ioports(struct fs_uart_platform_info
* pdata
)
222 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
224 unsigned int iobits
= 0x00000c00;
226 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
228 if (bcsr_io
== NULL
) {
229 printk(KERN_CRIT
"Could not remap BCSR1\n");
233 clrbits32(bcsr_io
,BCSR1_RS232EN_2
);
237 #ifndef CONFIG_SERIAL_CPM_ALT_SMC2
238 setbits32(&immap
->im_cpm
.cp_pbpar
, iobits
);
239 clrbits32(&immap
->im_cpm
.cp_pbdir
, iobits
);
240 clrbits16(&immap
->im_cpm
.cp_pbodr
, iobits
);
242 setbits16(&immap
->im_ioport
.iop_papar
, iobits
);
243 clrbits16(&immap
->im_ioport
.iop_padir
, iobits
);
244 clrbits16(&immap
->im_ioport
.iop_paodr
, iobits
);
249 static int ma_count
= 0;
251 static void mpc866ads_fixup_enet_pdata(struct platform_device
*pdev
, int fs_no
)
253 struct fs_platform_info
*fpi
;
255 volatile cpm8xx_t
*cp
;
256 bd_t
*bd
= (bd_t
*) __res
;
260 /* Get pointer to Communication Processor */
263 if(fs_no
>= ARRAY_SIZE(mpc8xx_enet_pdata
)) {
264 printk(KERN_ERR
"No network-suitable #%d device on bus", fs_no
);
269 fpi
= &mpc8xx_enet_pdata
[fs_no
];
271 pdev
->dev
.platform_data
= fpi
;
273 e
= (unsigned char *)&bd
->bi_enetaddr
;
274 for (i
= 0; i
< 6; i
++)
275 fpi
->macaddr
[i
] = *e
++;
277 fpi
->macaddr
[5] += ma_count
++;
280 static void mpc866ads_fixup_fec_enet_pdata(struct platform_device
*pdev
,
283 /* This is for FEC devices only */
284 if (!pdev
|| !pdev
->name
|| (!strstr(pdev
->name
, "fsl-cpm-fec")))
286 mpc866ads_fixup_enet_pdata(pdev
, fsid_fec1
+ pdev
->id
- 1);
289 static void mpc866ads_fixup_scc_enet_pdata(struct platform_device
*pdev
,
292 /* This is for SCC devices only */
293 if (!pdev
|| !pdev
->name
|| (!strstr(pdev
->name
, "fsl-cpm-scc")))
296 mpc866ads_fixup_enet_pdata(pdev
, fsid_scc1
+ pdev
->id
- 1);
299 static void __init
mpc866ads_fixup_uart_pdata(struct platform_device
*pdev
,
302 bd_t
*bd
= (bd_t
*) __res
;
303 struct fs_uart_platform_info
*pinfo
;
304 int num
= ARRAY_SIZE(mpc866_uart_pdata
);
306 int id
= fs_uart_id_smc2fsid(idx
);
308 /* no need to alter anything if console */
309 if ((id
< num
) && (!pdev
->dev
.platform_data
)) {
310 pinfo
= &mpc866_uart_pdata
[id
];
311 pinfo
->uart_clk
= bd
->bi_intfreq
;
312 pdev
->dev
.platform_data
= pinfo
;
316 static int mpc866ads_platform_notify(struct device
*dev
)
318 static const struct platform_notify_dev_map dev_map
[] = {
320 .bus_id
= "fsl-cpm-fec",
321 .rtn
= mpc866ads_fixup_fec_enet_pdata
,
324 .bus_id
= "fsl-cpm-scc",
325 .rtn
= mpc866ads_fixup_scc_enet_pdata
,
328 .bus_id
= "fsl-cpm-smc:uart",
329 .rtn
= mpc866ads_fixup_uart_pdata
336 platform_notify_map(dev_map
,dev
);
341 int __init
mpc866ads_init(void)
343 bd_t
*bd
= (bd_t
*) __res
;
344 struct fs_mii_fec_platform_info
* fmpi
;
346 printk(KERN_NOTICE
"mpc866ads: Init\n");
348 platform_notify
= mpc866ads_platform_notify
;
350 ppc_sys_device_initfunc();
351 ppc_sys_device_disable_all();
353 #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC1
354 ppc_sys_device_enable(MPC8xx_CPM_SCC1
);
356 ppc_sys_device_enable(MPC8xx_CPM_FEC1
);
358 ppc_sys_device_enable(MPC8xx_MDIO_FEC
);
360 fmpi
= ppc_sys_platform_devices
[MPC8xx_MDIO_FEC
].dev
.platform_data
=
361 &mpc8xx_mdio_fec_pdata
;
363 fmpi
->mii_speed
= ((((bd
->bi_intfreq
+ 4999999) / 2500000) / 2) & 0x3F) << 1;
364 /* No PHY interrupt line here */
365 fmpi
->irq
[0xf] = PHY_POLL
;
367 /* Since either of the uarts could be used as console, they need to ready */
368 #ifdef CONFIG_SERIAL_CPM_SMC1
369 ppc_sys_device_enable(MPC8xx_CPM_SMC1
);
370 ppc_sys_device_setfunc(MPC8xx_CPM_SMC1
, PPC_SYS_FUNC_UART
);
373 #ifdef CONFIG_SERIAL_CPM_SMC2
374 ppc_sys_device_enable(MPC8xx_CPM_SMC2
);
375 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2
, PPC_SYS_FUNC_UART
);
377 ppc_sys_device_enable(MPC8xx_MDIO_FEC
);
379 fmpi
= ppc_sys_platform_devices
[MPC8xx_MDIO_FEC
].dev
.platform_data
=
380 &mpc8xx_mdio_fec_pdata
;
382 fmpi
->mii_speed
= ((((bd
->bi_intfreq
+ 4999999) / 2500000) / 2) & 0x3F) << 1;
383 /* No PHY interrupt line here */
384 fmpi
->irq
[0xf] = PHY_POLL
;
390 To prevent confusion, console selection is gross:
391 by 0 assumed SMC1 and by 1 assumed SMC2
393 struct platform_device
* early_uart_get_pdev(int index
)
395 bd_t
*bd
= (bd_t
*) __res
;
396 struct fs_uart_platform_info
*pinfo
;
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];
407 pinfo
->uart_clk
= bd
->bi_intfreq
;
408 pdev
->dev
.platform_data
= pinfo
;
409 ppc_sys_fixup_mem_resource(pdev
, IMAP_ADDR
);
413 arch_initcall(mpc866ads_init
);