mpc52xx_setup.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * arch/ppc/syslib/mpc52xx_setup.c
  3. *
  4. * Common code for the boards based on Freescale MPC52xx embedded CPU.
  5. *
  6. *
  7. * Maintainer : Sylvain Munaut <tnt@246tNt.com>
  8. *
  9. * Support for other bootloaders than UBoot by Dale Farnsworth
  10. * <dfarnsworth@mvista.com>
  11. *
  12. * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
  13. * Copyright (C) 2003 Montavista Software, Inc
  14. *
  15. * This file is licensed under the terms of the GNU General Public License
  16. * version 2. This program is licensed "as is" without any warranty of any
  17. * kind, whether express or implied.
  18. */
  19. #include <linux/config.h>
  20. #include <asm/io.h>
  21. #include <asm/time.h>
  22. #include <asm/mpc52xx.h>
  23. #include <asm/mpc52xx_psc.h>
  24. #include <asm/pgtable.h>
  25. #include <asm/ppcboot.h>
  26. extern bd_t __res;
  27. static int core_mult[] = { /* CPU Frequency multiplier, taken */
  28. 0, 0, 0, 10, 20, 20, 25, 45, /* from the datasheet used to compute */
  29. 30, 55, 40, 50, 0, 60, 35, 0, /* CPU frequency from XLB freq and */
  30. 30, 25, 65, 10, 70, 20, 75, 45, /* external jumper config */
  31. 0, 55, 40, 50, 80, 60, 35, 0
  32. };
  33. void
  34. mpc52xx_restart(char *cmd)
  35. {
  36. struct mpc52xx_gpt __iomem *gpt0 = MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));
  37. local_irq_disable();
  38. /* Turn on the watchdog and wait for it to expire. It effectively
  39. does a reset */
  40. out_be32(&gpt0->count, 0x000000ff);
  41. out_be32(&gpt0->mode, 0x00009004);
  42. while (1);
  43. }
  44. void
  45. mpc52xx_halt(void)
  46. {
  47. local_irq_disable();
  48. while (1);
  49. }
  50. void
  51. mpc52xx_power_off(void)
  52. {
  53. /* By default we don't have any way of shut down.
  54. If a specific board wants to, it can set the power down
  55. code to any hardware implementation dependent code */
  56. mpc52xx_halt();
  57. }
  58. void __init
  59. mpc52xx_set_bat(void)
  60. {
  61. /* Set BAT 2 to map the 0xf0000000 area */
  62. /* This mapping is used during mpc52xx_progress,
  63. * mpc52xx_find_end_of_memory, and UARTs/GPIO access for debug
  64. */
  65. mb();
  66. mtspr(SPRN_DBAT2U, 0xf0001ffe);
  67. mtspr(SPRN_DBAT2L, 0xf000002a);
  68. mb();
  69. }
  70. void __init
  71. mpc52xx_map_io(void)
  72. {
  73. /* Here we only map the MBAR */
  74. io_block_mapping(
  75. MPC52xx_MBAR_VIRT, MPC52xx_MBAR, MPC52xx_MBAR_SIZE, _PAGE_IO);
  76. }
  77. #ifdef CONFIG_SERIAL_TEXT_DEBUG
  78. #ifndef MPC52xx_PF_CONSOLE_PORT
  79. #error "mpc52xx PSC for console not selected"
  80. #endif
  81. static void
  82. mpc52xx_psc_putc(struct mpc52xx_psc __iomem *psc, unsigned char c)
  83. {
  84. while (!(in_be16(&psc->mpc52xx_psc_status) &
  85. MPC52xx_PSC_SR_TXRDY));
  86. out_8(&psc->mpc52xx_psc_buffer_8, c);
  87. }
  88. void
  89. mpc52xx_progress(char *s, unsigned short hex)
  90. {
  91. char c;
  92. struct mpc52xx_psc __iomem *psc;
  93. psc = MPC52xx_VA(MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT));
  94. while ((c = *s++) != 0) {
  95. if (c == '\n')
  96. mpc52xx_psc_putc(psc, '\r');
  97. mpc52xx_psc_putc(psc, c);
  98. }
  99. mpc52xx_psc_putc(psc, '\r');
  100. mpc52xx_psc_putc(psc, '\n');
  101. }
  102. #endif /* CONFIG_SERIAL_TEXT_DEBUG */
  103. unsigned long __init
  104. mpc52xx_find_end_of_memory(void)
  105. {
  106. u32 ramsize = __res.bi_memsize;
  107. /*
  108. * if bootloader passed a memsize, just use it
  109. * else get size from sdram config registers
  110. */
  111. if (ramsize == 0) {
  112. struct mpc52xx_mmap_ctl __iomem *mmap_ctl;
  113. u32 sdram_config_0, sdram_config_1;
  114. /* Temp BAT2 mapping active when this is called ! */
  115. mmap_ctl = MPC52xx_VA(MPC52xx_MMAP_CTL_OFFSET);
  116. sdram_config_0 = in_be32(&mmap_ctl->sdram0);
  117. sdram_config_1 = in_be32(&mmap_ctl->sdram1);
  118. if ((sdram_config_0 & 0x1f) >= 0x13)
  119. ramsize = 1 << ((sdram_config_0 & 0xf) + 17);
  120. if (((sdram_config_1 & 0x1f) >= 0x13) &&
  121. ((sdram_config_1 & 0xfff00000) == ramsize))
  122. ramsize += 1 << ((sdram_config_1 & 0xf) + 17);
  123. }
  124. return ramsize;
  125. }
  126. void __init
  127. mpc52xx_calibrate_decr(void)
  128. {
  129. int current_time, previous_time;
  130. int tbl_start, tbl_end;
  131. unsigned int xlbfreq, cpufreq, ipbfreq, pcifreq, divisor;
  132. xlbfreq = __res.bi_busfreq;
  133. /* if bootloader didn't pass bus frequencies, calculate them */
  134. if (xlbfreq == 0) {
  135. /* Get RTC & Clock manager modules */
  136. struct mpc52xx_rtc __iomem *rtc;
  137. struct mpc52xx_cdm __iomem *cdm;
  138. rtc = ioremap(MPC52xx_PA(MPC52xx_RTC_OFFSET), MPC52xx_RTC_SIZE);
  139. cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
  140. if ((rtc==NULL) || (cdm==NULL))
  141. panic("Can't ioremap RTC/CDM while computing bus freq");
  142. /* Count bus clock during 1/64 sec */
  143. out_be32(&rtc->dividers, 0x8f1f0000); /* Set RTC 64x faster */
  144. previous_time = in_be32(&rtc->time);
  145. while ((current_time = in_be32(&rtc->time)) == previous_time) ;
  146. tbl_start = get_tbl();
  147. previous_time = current_time;
  148. while ((current_time = in_be32(&rtc->time)) == previous_time) ;
  149. tbl_end = get_tbl();
  150. out_be32(&rtc->dividers, 0xffff0000); /* Restore RTC */
  151. /* Compute all frequency from that & CDM settings */
  152. xlbfreq = (tbl_end - tbl_start) << 8;
  153. cpufreq = (xlbfreq * core_mult[in_be32(&cdm->rstcfg)&0x1f])/10;
  154. ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ?
  155. xlbfreq / 2 : xlbfreq;
  156. switch (in_8(&cdm->pci_clk_sel) & 3) {
  157. case 0:
  158. pcifreq = ipbfreq;
  159. break;
  160. case 1:
  161. pcifreq = ipbfreq / 2;
  162. break;
  163. default:
  164. pcifreq = xlbfreq / 4;
  165. break;
  166. }
  167. __res.bi_busfreq = xlbfreq;
  168. __res.bi_intfreq = cpufreq;
  169. __res.bi_ipbfreq = ipbfreq;
  170. __res.bi_pcifreq = pcifreq;
  171. /* Release mapping */
  172. iounmap(rtc);
  173. iounmap(cdm);
  174. }
  175. divisor = 4;
  176. tb_ticks_per_jiffy = xlbfreq / HZ / divisor;
  177. tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
  178. }
  179. int mpc52xx_match_psc_function(int psc_idx, const char *func)
  180. {
  181. struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
  182. while ((cf->id != -1) && (cf->func != NULL)) {
  183. if ((cf->id == psc_idx) && !strcmp(cf->func,func))
  184. return 1;
  185. cf++;
  186. }
  187. return 0;
  188. }