1 /*arch/ppc/platforms/mpc885ads-setup.c
3 * Platform setup for the Freescale mpc885ads board
5 * Vitaly Bordug <vbordug@ru.mvista.com>
7 * Copyright 2005 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/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>
22 #include <linux/fs_enet_pd.h>
23 #include <linux/fs_uart_pd.h>
24 #include <linux/mii.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>
38 extern unsigned char __res
[];
39 static void setup_smc1_ioports(void);
40 static void setup_smc2_ioports(void);
42 static void __init
mpc885ads_scc_phy_init(char);
44 static struct fs_uart_platform_info mpc885_uart_pdata
[] = {
47 .fs_no
= fsid_smc1_uart
,
48 .init_ioports
= setup_smc1_ioports
,
56 .fs_no
= fsid_smc2_uart
,
57 .init_ioports
= setup_smc2_ioports
,
65 static struct fs_mii_bus_info fec_mii_bus_info
= {
70 static struct fs_mii_bus_info scc_mii_bus_info
= {
71 #ifdef CONFIG_SCC_ENET_8xx_FIXED
72 .method
= fsmii_fixed
,
80 static struct fs_platform_info mpc8xx_fec_pdata
[] = {
92 .bus_info
= &fec_mii_bus_info
,
104 .bus_info
= &fec_mii_bus_info
,
108 static struct fs_platform_info mpc8xx_scc_pdata
= {
117 #ifdef CONFIG_MPC8xx_SCC_ENET_FIXED
123 .bus_info
= &scc_mii_bus_info
,
126 void __init
board_init(void)
128 volatile cpm8xx_t
*cp
= cpmp
;
129 unsigned int *bcsr_io
;
131 #ifdef CONFIG_FS_ENET
132 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
134 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
136 if (bcsr_io
== NULL
) {
137 printk(KERN_CRIT
"Could not remap BCSR\n");
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
);
146 setbits32(bcsr_io
,BCSR1_RS232EN_1
);
147 cp
->cp_smc
[0].smc_smcmr
= 0;
148 cp
->cp_smc
[0].smc_smce
= 0;
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
);
158 setbits32(bcsr_io
,BCSR1_RS232EN_2
);
159 cp
->cp_smc
[1].smc_smcmr
= 0;
160 cp
->cp_smc
[1].smc_smce
= 0;
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);
171 static void setup_fec1_ioports(void)
173 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
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);
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);
186 setbits32(&immap
->im_cpm
.cp_pedir
, 0x00000003);
187 clrbits32(&immap
->im_cpm
.cp_peso
, 0x00000003);
188 clrbits32(&immap
->im_cpm
.cp_cptr
, 0x00000100);
191 static void setup_fec2_ioports(void)
193 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
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);
203 static void setup_scc3_ioports(void)
205 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
208 bcsr_io
= ioremap(BCSR_ADDR
, BCSR_SIZE
);
210 if (bcsr_io
== NULL
) {
211 printk(KERN_CRIT
"Could not remap BCSR\n");
217 setbits32(bcsr_io
+4, BCSR4_ETH10_RST
);
218 /* Configure port A pins for Txd and Rxd.
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
);
223 /* Configure port C pins to enable CLSN and RENA.
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
);
229 /* Configure port E for TCLK and RCLK.
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
);
238 /* Configure Serial Interface clock routing.
239 * First, clear all SCC bits to zero, then set the ones we want.
241 clrbits32(&immap
->im_cpm
.cp_sicr
, SICR_ENET_MASK
);
242 setbits32(&immap
->im_cpm
.cp_sicr
, SICR_ENET_CLKRT
);
244 /* Disable Rx and Tx. SMC1 sshould be stopped if SCC3 eternet are used.
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.
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
);
258 setbits32(bcsr_io
+1, BCSR1_ETHEN
);
262 static void mpc885ads_fixup_enet_pdata(struct platform_device
*pdev
, int fs_no
)
264 struct fs_platform_info
*fpi
= pdev
->dev
.platform_data
;
266 volatile cpm8xx_t
*cp
;
267 bd_t
*bd
= (bd_t
*) __res
;
271 /* Get pointer to Communication Processor */
275 fpi
= &mpc8xx_fec_pdata
[0];
276 fpi
->init_ioports
= &setup_fec1_ioports
;
279 fpi
= &mpc8xx_fec_pdata
[1];
280 fpi
->init_ioports
= &setup_fec2_ioports
;
283 fpi
= &mpc8xx_scc_pdata
;
284 fpi
->init_ioports
= &setup_scc3_ioports
;
285 mpc885ads_scc_phy_init(fpi
->phy_addr
);
288 printk(KERN_WARNING
"Device %s is not supported!\n", pdev
->name
);
292 pdev
->dev
.platform_data
= fpi
;
295 e
= (unsigned char *)&bd
->bi_enetaddr
;
296 for (i
= 0; i
< 6; i
++)
297 fpi
->macaddr
[i
] = *e
++;
299 fpi
->macaddr
[5 - pdev
->id
]++;
303 static void mpc885ads_fixup_fec_enet_pdata(struct platform_device
*pdev
,
306 /* This is for FEC devices only */
307 if (!pdev
|| !pdev
->name
|| (!strstr(pdev
->name
, "fsl-cpm-fec")))
309 mpc885ads_fixup_enet_pdata(pdev
, fsid_fec1
+ pdev
->id
- 1);
312 static void __init
mpc885ads_fixup_scc_enet_pdata(struct platform_device
*pdev
,
315 /* This is for SCC devices only */
316 if (!pdev
|| !pdev
->name
|| (!strstr(pdev
->name
, "fsl-cpm-scc")))
319 mpc885ads_fixup_enet_pdata(pdev
, fsid_scc1
+ pdev
->id
- 1);
322 /* SCC ethernet controller does not have MII management channel. FEC1 MII
323 * channel is used to communicate with the 10Mbit PHY.
326 #define MII_ECNTRL_PINMUX 0x4
327 #define FEC_ECNTRL_PINMUX 0x00000004
328 #define FEC_RCNTRL_MII_MODE 0x00000004
330 /* Make MII read/write commands.
332 #define mk_mii_write(REG, VAL, PHY_ADDR) (0x50020000 | (((REG) & 0x1f) << 18) | \
333 ((VAL) & 0xffff) | ((PHY_ADDR) << 23))
335 static void mpc885ads_scc_phy_init(char phy_addr
)
337 volatile immap_t
*immap
;
338 volatile fec_t
*fecp
;
342 immap
= (immap_t
*) IMAP_ADDR
; /* pointer to internal registers */
343 fecp
= &(immap
->im_cpm
.cp_fec
);
345 /* Enable MII pins of the FEC1
347 setbits16(&immap
->im_ioport
.iop_pdpar
, 0x0080);
348 clrbits16(&immap
->im_ioport
.iop_pddir
, 0x0080);
349 /* Set MII speed to 2.5 MHz
351 out_be32(&fecp
->fec_mii_speed
,
352 ((((bd
->bi_intfreq
+ 4999999) / 2500000) / 2) & 0x3F) << 1);
354 /* Enable FEC pin MUX
356 setbits32(&fecp
->fec_ecntrl
, MII_ECNTRL_PINMUX
);
357 setbits32(&fecp
->fec_r_cntrl
, FEC_RCNTRL_MII_MODE
);
359 out_be32(&fecp
->fec_mii_data
,
360 mk_mii_write(MII_BMCR
, BMCR_ISOLATE
, phy_addr
));
362 out_be32(&fecp
->fec_mii_data
,
363 mk_mii_write(MII_ADVERTISE
,
364 ADVERTISE_10HALF
| ADVERTISE_CSMA
, phy_addr
));
367 /* Disable FEC MII settings
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);
374 static void setup_smc1_ioports(void)
376 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
378 unsigned int iobits
= 0x000000c0;
380 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
382 if (bcsr_io
== NULL
) {
383 printk(KERN_CRIT
"Could not remap BCSR1\n");
386 clrbits32(bcsr_io
,BCSR1_RS232EN_1
);
389 setbits32(&immap
->im_cpm
.cp_pbpar
, iobits
);
390 clrbits32(&immap
->im_cpm
.cp_pbdir
, iobits
);
391 clrbits16(&immap
->im_cpm
.cp_pbodr
, iobits
);
394 static void setup_smc2_ioports(void)
396 immap_t
*immap
= (immap_t
*) IMAP_ADDR
;
398 unsigned int iobits
= 0x00000c00;
400 bcsr_io
= ioremap(BCSR1
, sizeof(unsigned long));
402 if (bcsr_io
== NULL
) {
403 printk(KERN_CRIT
"Could not remap BCSR1\n");
406 clrbits32(bcsr_io
,BCSR1_RS232EN_2
);
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
);
414 setbits16(&immap
->im_ioport
.iop_papar
, iobits
);
415 clrbits16(&immap
->im_ioport
.iop_padir
, iobits
);
416 clrbits16(&immap
->im_ioport
.iop_paodr
, iobits
);
420 static void __init
mpc885ads_fixup_uart_pdata(struct platform_device
*pdev
,
423 bd_t
*bd
= (bd_t
*) __res
;
424 struct fs_uart_platform_info
*pinfo
;
425 int num
= ARRAY_SIZE(mpc885_uart_pdata
);
427 int id
= fs_uart_id_smc2fsid(idx
);
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
;
438 static int mpc885ads_platform_notify(struct device
*dev
)
441 static const struct platform_notify_dev_map dev_map
[] = {
443 .bus_id
= "fsl-cpm-fec",
444 .rtn
= mpc885ads_fixup_fec_enet_pdata
,
447 .bus_id
= "fsl-cpm-scc",
448 .rtn
= mpc885ads_fixup_scc_enet_pdata
,
451 .bus_id
= "fsl-cpm-smc:uart",
452 .rtn
= mpc885ads_fixup_uart_pdata
459 platform_notify_map(dev_map
,dev
);
464 int __init
mpc885ads_init(void)
466 printk(KERN_NOTICE
"mpc885ads: Init\n");
468 platform_notify
= mpc885ads_platform_notify
;
470 ppc_sys_device_initfunc();
471 ppc_sys_device_disable_all();
473 ppc_sys_device_enable(MPC8xx_CPM_FEC1
);
475 #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
476 ppc_sys_device_enable(MPC8xx_CPM_SCC1
);
479 #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
480 ppc_sys_device_enable(MPC8xx_CPM_FEC2
);
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
);
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
);
495 arch_initcall(mpc885ads_init
);
498 To prevent confusion, console selection is gross:
499 by 0 assumed SMC1 and by 1 assumed SMC2
501 struct platform_device
* early_uart_get_pdev(int index
)
503 bd_t
*bd
= (bd_t
*) __res
;
504 struct fs_uart_platform_info
*pinfo
;
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];
515 pinfo
->uart_clk
= bd
->bi_intfreq
;
516 pdev
->dev
.platform_data
= pinfo
;
517 ppc_sys_fixup_mem_resource(pdev
, IMAP_ADDR
);