aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/commproc.c
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 /arch/powerpc/sysdev/commproc.c
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>
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}