csrc-octeon.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2007 by Ralf Baechle
  7. * Copyright (C) 2009, 2012 Cavium, Inc.
  8. */
  9. #include <linux/clocksource.h>
  10. #include <linux/export.h>
  11. #include <linux/init.h>
  12. #include <linux/smp.h>
  13. #include <asm/cpu-info.h>
  14. #include <asm/cpu-type.h>
  15. #include <asm/time.h>
  16. #include <asm/octeon/octeon.h>
  17. #include <asm/octeon/cvmx-ipd-defs.h>
  18. #include <asm/octeon/cvmx-mio-defs.h>
  19. static u64 f;
  20. static u64 rdiv;
  21. static u64 sdiv;
  22. static u64 octeon_udelay_factor;
  23. static u64 octeon_ndelay_factor;
  24. void __init octeon_setup_delays(void)
  25. {
  26. octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
  27. /*
  28. * For __ndelay we divide by 2^16, so the factor is multiplied
  29. * by the same amount.
  30. */
  31. octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
  32. preset_lpj = octeon_get_clock_rate() / HZ;
  33. if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
  34. union cvmx_mio_rst_boot rst_boot;
  35. rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
  36. rdiv = rst_boot.s.c_mul; /* CPU clock */
  37. sdiv = rst_boot.s.pnr_mul; /* I/O clock */
  38. f = (0x8000000000000000ull / sdiv) * 2;
  39. }
  40. }
  41. /*
  42. * Set the current core's cvmcount counter to the value of the
  43. * IPD_CLK_COUNT. We do this on all cores as they are brought
  44. * on-line. This allows for a read from a local cpu register to
  45. * access a synchronized counter.
  46. *
  47. * On CPU_CAVIUM_OCTEON2 the IPD_CLK_COUNT is scaled by rdiv/sdiv.
  48. */
  49. void octeon_init_cvmcount(void)
  50. {
  51. unsigned long flags;
  52. unsigned loops = 2;
  53. /* Clobber loops so GCC will not unroll the following while loop. */
  54. asm("" : "+r" (loops));
  55. local_irq_save(flags);
  56. /*
  57. * Loop several times so we are executing from the cache,
  58. * which should give more deterministic timing.
  59. */
  60. while (loops--) {
  61. u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT);
  62. if (rdiv != 0) {
  63. ipd_clk_count *= rdiv;
  64. if (f != 0) {
  65. asm("dmultu\t%[cnt],%[f]\n\t"
  66. "mfhi\t%[cnt]"
  67. : [cnt] "+r" (ipd_clk_count)
  68. : [f] "r" (f)
  69. : "hi", "lo");
  70. }
  71. }
  72. write_c0_cvmcount(ipd_clk_count);
  73. }
  74. local_irq_restore(flags);
  75. }
  76. static cycle_t octeon_cvmcount_read(struct clocksource *cs)
  77. {
  78. return read_c0_cvmcount();
  79. }
  80. static struct clocksource clocksource_mips = {
  81. .name = "OCTEON_CVMCOUNT",
  82. .read = octeon_cvmcount_read,
  83. .mask = CLOCKSOURCE_MASK(64),
  84. .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  85. };
  86. unsigned long long notrace sched_clock(void)
  87. {
  88. /* 64-bit arithmatic can overflow, so use 128-bit. */
  89. u64 t1, t2, t3;
  90. unsigned long long rv;
  91. u64 mult = clocksource_mips.mult;
  92. u64 shift = clocksource_mips.shift;
  93. u64 cnt = read_c0_cvmcount();
  94. asm (
  95. "dmultu\t%[cnt],%[mult]\n\t"
  96. "nor\t%[t1],$0,%[shift]\n\t"
  97. "mfhi\t%[t2]\n\t"
  98. "mflo\t%[t3]\n\t"
  99. "dsll\t%[t2],%[t2],1\n\t"
  100. "dsrlv\t%[rv],%[t3],%[shift]\n\t"
  101. "dsllv\t%[t1],%[t2],%[t1]\n\t"
  102. "or\t%[rv],%[t1],%[rv]\n\t"
  103. : [rv] "=&r" (rv), [t1] "=&r" (t1), [t2] "=&r" (t2), [t3] "=&r" (t3)
  104. : [cnt] "r" (cnt), [mult] "r" (mult), [shift] "r" (shift)
  105. : "hi", "lo");
  106. return rv;
  107. }
  108. void __init plat_time_init(void)
  109. {
  110. clocksource_mips.rating = 300;
  111. clocksource_register_hz(&clocksource_mips, octeon_get_clock_rate());
  112. }
  113. void __udelay(unsigned long us)
  114. {
  115. u64 cur, end, inc;
  116. cur = read_c0_cvmcount();
  117. inc = us * octeon_udelay_factor;
  118. end = cur + inc;
  119. while (end > cur)
  120. cur = read_c0_cvmcount();
  121. }
  122. EXPORT_SYMBOL(__udelay);
  123. void __ndelay(unsigned long ns)
  124. {
  125. u64 cur, end, inc;
  126. cur = read_c0_cvmcount();
  127. inc = ((ns * octeon_ndelay_factor) >> 16);
  128. end = cur + inc;
  129. while (end > cur)
  130. cur = read_c0_cvmcount();
  131. }
  132. EXPORT_SYMBOL(__ndelay);
  133. void __delay(unsigned long loops)
  134. {
  135. u64 cur, end;
  136. cur = read_c0_cvmcount();
  137. end = cur + loops;
  138. while (end > cur)
  139. cur = read_c0_cvmcount();
  140. }
  141. EXPORT_SYMBOL(__delay);
  142. /**
  143. * octeon_io_clk_delay - wait for a given number of io clock cycles to pass.
  144. *
  145. * We scale the wait by the clock ratio, and then wait for the
  146. * corresponding number of core clocks.
  147. *
  148. * @count: The number of clocks to wait.
  149. */
  150. void octeon_io_clk_delay(unsigned long count)
  151. {
  152. u64 cur, end;
  153. cur = read_c0_cvmcount();
  154. if (rdiv != 0) {
  155. end = count * rdiv;
  156. if (f != 0) {
  157. asm("dmultu\t%[cnt],%[f]\n\t"
  158. "mfhi\t%[cnt]"
  159. : [cnt] "+r" (end)
  160. : [f] "r" (f)
  161. : "hi", "lo");
  162. }
  163. end = cur + end;
  164. } else {
  165. end = cur + count;
  166. }
  167. while (end > cur)
  168. cur = read_c0_cvmcount();
  169. }
  170. EXPORT_SYMBOL(octeon_io_clk_delay);