diff options
Diffstat (limited to 'arch/ppc/platforms/mpc885ads_setup.c')
-rw-r--r-- | arch/ppc/platforms/mpc885ads_setup.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c index 50a99e5f7c68..4b88679cd31c 100644 --- a/arch/ppc/platforms/mpc885ads_setup.c +++ b/arch/ppc/platforms/mpc885ads_setup.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | 21 | ||
22 | #include <linux/fs_enet_pd.h> | 22 | #include <linux/fs_enet_pd.h> |
23 | #include <linux/fs_uart_pd.h> | ||
23 | #include <linux/mii.h> | 24 | #include <linux/mii.h> |
24 | 25 | ||
25 | #include <asm/delay.h> | 26 | #include <asm/delay.h> |
@@ -35,9 +36,32 @@ | |||
35 | #include <asm/ppc_sys.h> | 36 | #include <asm/ppc_sys.h> |
36 | 37 | ||
37 | extern unsigned char __res[]; | 38 | extern unsigned char __res[]; |
39 | static void setup_smc1_ioports(void); | ||
40 | static void setup_smc2_ioports(void); | ||
38 | 41 | ||
39 | static void __init mpc885ads_scc_phy_init(char); | 42 | static void __init mpc885ads_scc_phy_init(char); |
40 | 43 | ||
44 | static struct fs_uart_platform_info mpc885_uart_pdata[] = { | ||
45 | [fsid_smc1_uart] = { | ||
46 | .brg = 1, | ||
47 | .fs_no = fsid_smc1_uart, | ||
48 | .init_ioports = setup_smc1_ioports, | ||
49 | .tx_num_fifo = 4, | ||
50 | .tx_buf_size = 32, | ||
51 | .rx_num_fifo = 4, | ||
52 | .rx_buf_size = 32, | ||
53 | }, | ||
54 | [fsid_smc2_uart] = { | ||
55 | .brg = 2, | ||
56 | .fs_no = fsid_smc2_uart, | ||
57 | .init_ioports = setup_smc2_ioports, | ||
58 | .tx_num_fifo = 4, | ||
59 | .tx_buf_size = 32, | ||
60 | .rx_num_fifo = 4, | ||
61 | .rx_buf_size = 32, | ||
62 | }, | ||
63 | }; | ||
64 | |||
41 | static struct fs_mii_bus_info fec_mii_bus_info = { | 65 | static struct fs_mii_bus_info fec_mii_bus_info = { |
42 | .method = fsmii_fec, | 66 | .method = fsmii_fec, |
43 | .id = 0, | 67 | .id = 0, |
@@ -116,6 +140,8 @@ void __init board_init(void) | |||
116 | #ifdef CONFIG_SERIAL_CPM_SMC1 | 140 | #ifdef CONFIG_SERIAL_CPM_SMC1 |
117 | cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */ | 141 | cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */ |
118 | clrbits32(bcsr_io, BCSR1_RS232EN_1); | 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); | ||
119 | #else | 145 | #else |
120 | setbits32(bcsr_io,BCSR1_RS232EN_1); | 146 | setbits32(bcsr_io,BCSR1_RS232EN_1); |
121 | cp->cp_smc[0].smc_smcmr = 0; | 147 | cp->cp_smc[0].smc_smcmr = 0; |
@@ -126,6 +152,8 @@ void __init board_init(void) | |||
126 | cp->cp_simode &= ~(0xe0000000 >> 1); | 152 | cp->cp_simode &= ~(0xe0000000 >> 1); |
127 | cp->cp_simode |= (0x20000000 >> 1); /* brg2 */ | 153 | cp->cp_simode |= (0x20000000 >> 1); /* brg2 */ |
128 | clrbits32(bcsr_io,BCSR1_RS232EN_2); | 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); | ||
129 | #else | 157 | #else |
130 | setbits32(bcsr_io,BCSR1_RS232EN_2); | 158 | setbits32(bcsr_io,BCSR1_RS232EN_2); |
131 | cp->cp_smc[1].smc_smcmr = 0; | 159 | cp->cp_smc[1].smc_smcmr = 0; |
@@ -343,6 +371,70 @@ static void mpc885ads_scc_phy_init(char phy_addr) | |||
343 | out_be32(&fecp->fec_mii_speed, 0); | 371 | out_be32(&fecp->fec_mii_speed, 0); |
344 | } | 372 | } |
345 | 373 | ||
374 | static void setup_smc1_ioports(void) | ||
375 | { | ||
376 | immap_t *immap = (immap_t *) IMAP_ADDR; | ||
377 | unsigned *bcsr_io; | ||
378 | unsigned int iobits = 0x000000c0; | ||
379 | |||
380 | bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); | ||
381 | |||
382 | if (bcsr_io == NULL) { | ||
383 | printk(KERN_CRIT "Could not remap BCSR1\n"); | ||
384 | return; | ||
385 | } | ||
386 | clrbits32(bcsr_io,BCSR1_RS232EN_1); | ||
387 | iounmap(bcsr_io); | ||
388 | |||
389 | setbits32(&immap->im_cpm.cp_pbpar, iobits); | ||
390 | clrbits32(&immap->im_cpm.cp_pbdir, iobits); | ||
391 | clrbits16(&immap->im_cpm.cp_pbodr, iobits); | ||
392 | } | ||
393 | |||
394 | static void setup_smc2_ioports(void) | ||
395 | { | ||
396 | immap_t *immap = (immap_t *) IMAP_ADDR; | ||
397 | unsigned *bcsr_io; | ||
398 | unsigned int iobits = 0x00000c00; | ||
399 | |||
400 | bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); | ||
401 | |||
402 | if (bcsr_io == NULL) { | ||
403 | printk(KERN_CRIT "Could not remap BCSR1\n"); | ||
404 | return; | ||
405 | } | ||
406 | clrbits32(bcsr_io,BCSR1_RS232EN_2); | ||
407 | iounmap(bcsr_io); | ||
408 | |||
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); | ||
413 | #else | ||
414 | setbits16(&immap->im_ioport.iop_papar, iobits); | ||
415 | clrbits16(&immap->im_ioport.iop_padir, iobits); | ||
416 | clrbits16(&immap->im_ioport.iop_paodr, iobits); | ||
417 | #endif | ||
418 | } | ||
419 | |||
420 | static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev, | ||
421 | int idx) | ||
422 | { | ||
423 | bd_t *bd = (bd_t *) __res; | ||
424 | struct fs_uart_platform_info *pinfo; | ||
425 | int num = ARRAY_SIZE(mpc885_uart_pdata); | ||
426 | |||
427 | int id = fs_uart_id_smc2fsid(idx); | ||
428 | |||
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; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | |||
346 | static int mpc885ads_platform_notify(struct device *dev) | 438 | static int mpc885ads_platform_notify(struct device *dev) |
347 | { | 439 | { |
348 | 440 | ||
@@ -356,12 +448,17 @@ static int mpc885ads_platform_notify(struct device *dev) | |||
356 | .rtn = mpc885ads_fixup_scc_enet_pdata, | 448 | .rtn = mpc885ads_fixup_scc_enet_pdata, |
357 | }, | 449 | }, |
358 | { | 450 | { |
451 | .bus_id = "fsl-cpm-smc:uart", | ||
452 | .rtn = mpc885ads_fixup_uart_pdata | ||
453 | }, | ||
454 | { | ||
359 | .bus_id = NULL | 455 | .bus_id = NULL |
360 | } | 456 | } |
361 | }; | 457 | }; |
362 | 458 | ||
363 | platform_notify_map(dev_map,dev); | 459 | platform_notify_map(dev_map,dev); |
364 | 460 | ||
461 | return 0; | ||
365 | } | 462 | } |
366 | 463 | ||
367 | int __init mpc885ads_init(void) | 464 | int __init mpc885ads_init(void) |
@@ -383,7 +480,41 @@ int __init mpc885ads_init(void) | |||
383 | ppc_sys_device_enable(MPC8xx_CPM_FEC2); | 480 | ppc_sys_device_enable(MPC8xx_CPM_FEC2); |
384 | #endif | 481 | #endif |
385 | 482 | ||
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); | ||
486 | #endif | ||
487 | |||
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); | ||
491 | #endif | ||
386 | return 0; | 492 | return 0; |
387 | } | 493 | } |
388 | 494 | ||
389 | arch_initcall(mpc885ads_init); | 495 | arch_initcall(mpc885ads_init); |
496 | |||
497 | /* | ||
498 | To prevent confusion, console selection is gross: | ||
499 | by 0 assumed SMC1 and by 1 assumed SMC2 | ||
500 | */ | ||
501 | struct platform_device* early_uart_get_pdev(int index) | ||
502 | { | ||
503 | bd_t *bd = (bd_t *) __res; | ||
504 | struct fs_uart_platform_info *pinfo; | ||
505 | |||
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]; | ||
513 | } | ||
514 | |||
515 | pinfo->uart_clk = bd->bi_intfreq; | ||
516 | pdev->dev.platform_data = pinfo; | ||
517 | ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR); | ||
518 | return NULL; | ||
519 | } | ||
520 | |||