aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/commproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/commproc.c')
-rw-r--r--arch/powerpc/sysdev/commproc.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index f8f3741acd87..428eb8c151b9 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -397,3 +397,204 @@ uint cpm_dpram_phys(u8 *addr)
397 return (dpram_pbase + (uint)(addr - dpram_vbase)); 397 return (dpram_pbase + (uint)(addr - dpram_vbase));
398} 398}
399EXPORT_SYMBOL(cpm_dpram_phys); 399EXPORT_SYMBOL(cpm_dpram_phys);
400
401struct cpm_ioport16 {
402 __be16 dir, par, sor, dat, intr;
403 __be16 res[3];
404};
405
406struct cpm_ioport32 {
407 __be32 dir, par, sor;
408};
409
410static void cpm1_set_pin32(int port, int pin, int flags)
411{
412 struct cpm_ioport32 __iomem *iop;
413 pin = 1 << (31 - pin);
414
415 if (port == CPM_PORTB)
416 iop = (struct cpm_ioport32 __iomem *)
417 &mpc8xx_immr->im_cpm.cp_pbdir;
418 else
419 iop = (struct cpm_ioport32 __iomem *)
420 &mpc8xx_immr->im_cpm.cp_pedir;
421
422 if (flags & CPM_PIN_OUTPUT)
423 setbits32(&iop->dir, pin);
424 else
425 clrbits32(&iop->dir, pin);
426
427 if (!(flags & CPM_PIN_GPIO))
428 setbits32(&iop->par, pin);
429 else
430 clrbits32(&iop->par, pin);
431
432 if (port == CPM_PORTE) {
433 if (flags & CPM_PIN_SECONDARY)
434 setbits32(&iop->sor, pin);
435 else
436 clrbits32(&iop->sor, pin);
437
438 if (flags & CPM_PIN_OPENDRAIN)
439 setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
440 else
441 clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
442 }
443}
444
445static void cpm1_set_pin16(int port, int pin, int flags)
446{
447 struct cpm_ioport16 __iomem *iop =
448 (struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport;
449
450 pin = 1 << (15 - pin);
451
452 if (port != 0)
453 iop += port - 1;
454
455 if (flags & CPM_PIN_OUTPUT)
456 setbits16(&iop->dir, pin);
457 else
458 clrbits16(&iop->dir, pin);
459
460 if (!(flags & CPM_PIN_GPIO))
461 setbits16(&iop->par, pin);
462 else
463 clrbits16(&iop->par, pin);
464
465 if (port == CPM_PORTC) {
466 if (flags & CPM_PIN_SECONDARY)
467 setbits16(&iop->sor, pin);
468 else
469 clrbits16(&iop->sor, pin);
470 }
471}
472
473void cpm1_set_pin(enum cpm_port port, int pin, int flags)
474{
475 if (port == CPM_PORTB || port == CPM_PORTE)
476 cpm1_set_pin32(port, pin, flags);
477 else
478 cpm1_set_pin16(port, pin, flags);
479}
480
481int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
482{
483 int shift;
484 int i, bits = 0;
485 u32 __iomem *reg;
486 u32 mask = 7;
487
488 u8 clk_map[][3] = {
489 {CPM_CLK_SCC1, CPM_BRG1, 0},
490 {CPM_CLK_SCC1, CPM_BRG2, 1},
491 {CPM_CLK_SCC1, CPM_BRG3, 2},
492 {CPM_CLK_SCC1, CPM_BRG4, 3},
493 {CPM_CLK_SCC1, CPM_CLK1, 4},
494 {CPM_CLK_SCC1, CPM_CLK2, 5},
495 {CPM_CLK_SCC1, CPM_CLK3, 6},
496 {CPM_CLK_SCC1, CPM_CLK4, 7},
497
498 {CPM_CLK_SCC2, CPM_BRG1, 0},
499 {CPM_CLK_SCC2, CPM_BRG2, 1},
500 {CPM_CLK_SCC2, CPM_BRG3, 2},
501 {CPM_CLK_SCC2, CPM_BRG4, 3},
502 {CPM_CLK_SCC2, CPM_CLK1, 4},
503 {CPM_CLK_SCC2, CPM_CLK2, 5},
504 {CPM_CLK_SCC2, CPM_CLK3, 6},
505 {CPM_CLK_SCC2, CPM_CLK4, 7},
506
507 {CPM_CLK_SCC3, CPM_BRG1, 0},
508 {CPM_CLK_SCC3, CPM_BRG2, 1},
509 {CPM_CLK_SCC3, CPM_BRG3, 2},
510 {CPM_CLK_SCC3, CPM_BRG4, 3},
511 {CPM_CLK_SCC3, CPM_CLK5, 4},
512 {CPM_CLK_SCC3, CPM_CLK6, 5},
513 {CPM_CLK_SCC3, CPM_CLK7, 6},
514 {CPM_CLK_SCC3, CPM_CLK8, 7},
515
516 {CPM_CLK_SCC4, CPM_BRG1, 0},
517 {CPM_CLK_SCC4, CPM_BRG2, 1},
518 {CPM_CLK_SCC4, CPM_BRG3, 2},
519 {CPM_CLK_SCC4, CPM_BRG4, 3},
520 {CPM_CLK_SCC4, CPM_CLK5, 4},
521 {CPM_CLK_SCC4, CPM_CLK6, 5},
522 {CPM_CLK_SCC4, CPM_CLK7, 6},
523 {CPM_CLK_SCC4, CPM_CLK8, 7},
524
525 {CPM_CLK_SMC1, CPM_BRG1, 0},
526 {CPM_CLK_SMC1, CPM_BRG2, 1},
527 {CPM_CLK_SMC1, CPM_BRG3, 2},
528 {CPM_CLK_SMC1, CPM_BRG4, 3},
529 {CPM_CLK_SMC1, CPM_CLK1, 4},
530 {CPM_CLK_SMC1, CPM_CLK2, 5},
531 {CPM_CLK_SMC1, CPM_CLK3, 6},
532 {CPM_CLK_SMC1, CPM_CLK4, 7},
533
534 {CPM_CLK_SMC2, CPM_BRG1, 0},
535 {CPM_CLK_SMC2, CPM_BRG2, 1},
536 {CPM_CLK_SMC2, CPM_BRG3, 2},
537 {CPM_CLK_SMC2, CPM_BRG4, 3},
538 {CPM_CLK_SMC2, CPM_CLK5, 4},
539 {CPM_CLK_SMC2, CPM_CLK6, 5},
540 {CPM_CLK_SMC2, CPM_CLK7, 6},
541 {CPM_CLK_SMC2, CPM_CLK8, 7},
542 };
543
544 switch (target) {
545 case CPM_CLK_SCC1:
546 reg = &mpc8xx_immr->im_cpm.cp_sicr;
547 shift = 0;
548 break;
549
550 case CPM_CLK_SCC2:
551 reg = &mpc8xx_immr->im_cpm.cp_sicr;
552 shift = 8;
553 break;
554
555 case CPM_CLK_SCC3:
556 reg = &mpc8xx_immr->im_cpm.cp_sicr;
557 shift = 16;
558 break;
559
560 case CPM_CLK_SCC4:
561 reg = &mpc8xx_immr->im_cpm.cp_sicr;
562 shift = 24;
563 break;
564
565 case CPM_CLK_SMC1:
566 reg = &mpc8xx_immr->im_cpm.cp_simode;
567 shift = 12;
568 break;
569
570 case CPM_CLK_SMC2:
571 reg = &mpc8xx_immr->im_cpm.cp_simode;
572 shift = 28;
573 break;
574
575 default:
576 printk(KERN_ERR "cpm1_clock_setup: invalid clock target\n");
577 return -EINVAL;
578 }
579
580 if (reg == &mpc8xx_immr->im_cpm.cp_sicr && mode == CPM_CLK_RX)
581 shift += 3;
582
583 for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
584 if (clk_map[i][0] == target && clk_map[i][1] == clock) {
585 bits = clk_map[i][2];
586 break;
587 }
588 }
589
590 if (i == ARRAY_SIZE(clk_map)) {
591 printk(KERN_ERR "cpm1_clock_setup: invalid clock combination\n");
592 return -EINVAL;
593 }
594
595 bits <<= shift;
596 mask <<= shift;
597 out_be32(reg, (in_be32(reg) & ~mask) | bits);
598
599 return 0;
600}