ppc83xx_setup.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * arch/ppc/syslib/ppc83xx_setup.c
  3. *
  4. * MPC83XX common board code
  5. *
  6. * Maintainer: Kumar Gala <kumar.gala@freescale.com>
  7. *
  8. * Copyright 2005 Freescale Semiconductor Inc.
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the
  12. * Free Software Foundation; either version 2 of the License, or (at your
  13. * option) any later version.
  14. */
  15. #include <linux/config.h>
  16. #include <linux/types.h>
  17. #include <linux/module.h>
  18. #include <linux/init.h>
  19. #include <linux/pci.h>
  20. #include <linux/serial.h>
  21. #include <linux/tty.h> /* for linux/serial_core.h */
  22. #include <linux/serial_core.h>
  23. #include <linux/serial_8250.h>
  24. #include <asm/prom.h>
  25. #include <asm/time.h>
  26. #include <asm/mpc83xx.h>
  27. #include <asm/mmu.h>
  28. #include <asm/ppc_sys.h>
  29. #include <asm/kgdb.h>
  30. #include <asm/delay.h>
  31. #include <syslib/ppc83xx_setup.h>
  32. phys_addr_t immrbar;
  33. /* Return the amount of memory */
  34. unsigned long __init
  35. mpc83xx_find_end_of_memory(void)
  36. {
  37. bd_t *binfo;
  38. binfo = (bd_t *) __res;
  39. return binfo->bi_memsize;
  40. }
  41. long __init
  42. mpc83xx_time_init(void)
  43. {
  44. #define SPCR_OFFS 0x00000110
  45. #define SPCR_TBEN 0x00400000
  46. bd_t *binfo = (bd_t *)__res;
  47. u32 *spcr = ioremap(binfo->bi_immr_base + SPCR_OFFS, 4);
  48. *spcr |= SPCR_TBEN;
  49. iounmap(spcr);
  50. return 0;
  51. }
  52. /* The decrementer counts at the system (internal) clock freq divided by 4 */
  53. void __init
  54. mpc83xx_calibrate_decr(void)
  55. {
  56. bd_t *binfo = (bd_t *) __res;
  57. unsigned int freq, divisor;
  58. freq = binfo->bi_busfreq;
  59. divisor = 4;
  60. tb_ticks_per_jiffy = freq / HZ / divisor;
  61. tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
  62. }
  63. #ifdef CONFIG_SERIAL_8250
  64. void __init
  65. mpc83xx_early_serial_map(void)
  66. {
  67. #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
  68. struct uart_port serial_req;
  69. #endif
  70. struct plat_serial8250_port *pdata;
  71. bd_t *binfo = (bd_t *) __res;
  72. pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(MPC83xx_DUART);
  73. /* Setup serial port access */
  74. pdata[0].uartclk = binfo->bi_busfreq;
  75. pdata[0].mapbase += binfo->bi_immr_base;
  76. pdata[0].membase = ioremap(pdata[0].mapbase, 0x100);
  77. #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
  78. memset(&serial_req, 0, sizeof (serial_req));
  79. serial_req.iotype = SERIAL_IO_MEM;
  80. serial_req.mapbase = pdata[0].mapbase;
  81. serial_req.membase = pdata[0].membase;
  82. serial_req.regshift = 0;
  83. gen550_init(0, &serial_req);
  84. #endif
  85. pdata[1].uartclk = binfo->bi_busfreq;
  86. pdata[1].mapbase += binfo->bi_immr_base;
  87. pdata[1].membase = ioremap(pdata[1].mapbase, 0x100);
  88. #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
  89. /* Assume gen550_init() doesn't modify serial_req */
  90. serial_req.mapbase = pdata[1].mapbase;
  91. serial_req.membase = pdata[1].membase;
  92. gen550_init(1, &serial_req);
  93. #endif
  94. }
  95. #endif
  96. void
  97. mpc83xx_restart(char *cmd)
  98. {
  99. volatile unsigned char __iomem *reg;
  100. unsigned char tmp;
  101. reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
  102. local_irq_disable();
  103. /*
  104. * Unlock the BCSR bits so a PRST will update the contents.
  105. * Otherwise the reset asserts but doesn't clear.
  106. */
  107. tmp = in_8(reg + BCSR_MISC_REG3_OFF);
  108. tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
  109. out_8(reg + BCSR_MISC_REG3_OFF, tmp);
  110. /*
  111. * Trigger a reset via a low->high transition of the
  112. * PORESET bit.
  113. */
  114. tmp = in_8(reg + BCSR_MISC_REG2_OFF);
  115. tmp &= ~BCSR_MISC_REG2_PORESET;
  116. out_8(reg + BCSR_MISC_REG2_OFF, tmp);
  117. udelay(1);
  118. tmp |= BCSR_MISC_REG2_PORESET;
  119. out_8(reg + BCSR_MISC_REG2_OFF, tmp);
  120. for(;;);
  121. }
  122. void
  123. mpc83xx_power_off(void)
  124. {
  125. local_irq_disable();
  126. for(;;);
  127. }
  128. void
  129. mpc83xx_halt(void)
  130. {
  131. local_irq_disable();
  132. for(;;);
  133. }
  134. /* PCI SUPPORT DOES NOT EXIT, MODEL after ppc85xx_setup.c */