aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2007-07-16 18:22:01 -0400
committerKumar Gala <galak@kernel.crashing.org>2007-10-03 21:36:36 -0400
commit663edbd2640447dc43840568cd5701e6c9878d63 (patch)
treea68f486d53e7d82c86b1fa2fe75ea87d1ea35b56
parentfb533d0c5a9783ecafa9a177bace6384c47282a9 (diff)
[POWERPC] 8xx: Add pin and clock setting functions.
These let board code set up pins and clocks without having to put magic numbers directly into the registers. The clock function is mostly duplicated from the cpm2 version; hopefully this stuff can be merged at some point. Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--arch/powerpc/sysdev/commproc.c201
-rw-r--r--include/asm-powerpc/commproc.h49
2 files changed, 250 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index f8f3741acd..428eb8c151 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}
diff --git a/include/asm-powerpc/commproc.h b/include/asm-powerpc/commproc.h
index 86fcf265c5..5dec32404f 100644
--- a/include/asm-powerpc/commproc.h
+++ b/include/asm-powerpc/commproc.h
@@ -691,4 +691,53 @@ extern void cpm_free_handler(int vec);
691 691
692#define IMAP_ADDR (get_immrbase()) 692#define IMAP_ADDR (get_immrbase())
693 693
694#define CPM_PIN_INPUT 0
695#define CPM_PIN_OUTPUT 1
696#define CPM_PIN_PRIMARY 0
697#define CPM_PIN_SECONDARY 2
698#define CPM_PIN_GPIO 4
699#define CPM_PIN_OPENDRAIN 8
700
701enum cpm_port {
702 CPM_PORTA,
703 CPM_PORTB,
704 CPM_PORTC,
705 CPM_PORTD,
706 CPM_PORTE,
707};
708
709void cpm1_set_pin(enum cpm_port port, int pin, int flags);
710
711enum cpm_clk_dir {
712 CPM_CLK_RX,
713 CPM_CLK_TX,
714 CPM_CLK_RTX
715};
716
717enum cpm_clk_target {
718 CPM_CLK_SCC1,
719 CPM_CLK_SCC2,
720 CPM_CLK_SCC3,
721 CPM_CLK_SCC4,
722 CPM_CLK_SMC1,
723 CPM_CLK_SMC2,
724};
725
726enum cpm_clk {
727 CPM_BRG1, /* Baud Rate Generator 1 */
728 CPM_BRG2, /* Baud Rate Generator 2 */
729 CPM_BRG3, /* Baud Rate Generator 3 */
730 CPM_BRG4, /* Baud Rate Generator 4 */
731 CPM_CLK1, /* Clock 1 */
732 CPM_CLK2, /* Clock 2 */
733 CPM_CLK3, /* Clock 3 */
734 CPM_CLK4, /* Clock 4 */
735 CPM_CLK5, /* Clock 5 */
736 CPM_CLK6, /* Clock 6 */
737 CPM_CLK7, /* Clock 7 */
738 CPM_CLK8, /* Clock 8 */
739};
740
741int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode);
742
694#endif /* __CPM_8XX__ */ 743#endif /* __CPM_8XX__ */