delay.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Precise Delay Loops for i386
  3. *
  4. * Copyright (C) 1993 Linus Torvalds
  5. * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  6. *
  7. * The __delay function must _NOT_ be inlined as its execution time
  8. * depends wildly on alignment on many x86 processors. The additional
  9. * jump magic is needed to get the timing stable on all the CPU's
  10. * we have to worry about.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/config.h>
  14. #include <linux/sched.h>
  15. #include <linux/delay.h>
  16. #include <asm/processor.h>
  17. #include <asm/delay.h>
  18. #include <asm/timer.h>
  19. #ifdef CONFIG_SMP
  20. # include <asm/smp.h>
  21. #endif
  22. /* simple loop based delay: */
  23. static void delay_loop(unsigned long loops)
  24. {
  25. int d0;
  26. __asm__ __volatile__(
  27. "\tjmp 1f\n"
  28. ".align 16\n"
  29. "1:\tjmp 2f\n"
  30. ".align 16\n"
  31. "2:\tdecl %0\n\tjns 2b"
  32. :"=&a" (d0)
  33. :"0" (loops));
  34. }
  35. /* TSC based delay: */
  36. static void delay_tsc(unsigned long loops)
  37. {
  38. unsigned long bclock, now;
  39. rdtscl(bclock);
  40. do {
  41. rep_nop();
  42. rdtscl(now);
  43. } while ((now-bclock) < loops);
  44. }
  45. /*
  46. * Since we calibrate only once at boot, this
  47. * function should be set once at boot and not changed
  48. */
  49. static void (*delay_fn)(unsigned long) = delay_loop;
  50. void use_tsc_delay(void)
  51. {
  52. delay_fn = delay_tsc;
  53. }
  54. int read_current_timer(unsigned long *timer_val)
  55. {
  56. if (delay_fn == delay_tsc) {
  57. rdtscl(*timer_val);
  58. return 0;
  59. }
  60. return -1;
  61. }
  62. void __delay(unsigned long loops)
  63. {
  64. delay_fn(loops);
  65. }
  66. inline void __const_udelay(unsigned long xloops)
  67. {
  68. int d0;
  69. xloops *= 4;
  70. __asm__("mull %0"
  71. :"=d" (xloops), "=&a" (d0)
  72. :"1" (xloops), "0"
  73. (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)));
  74. __delay(++xloops);
  75. }
  76. void __udelay(unsigned long usecs)
  77. {
  78. __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
  79. }
  80. void __ndelay(unsigned long nsecs)
  81. {
  82. __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
  83. }
  84. EXPORT_SYMBOL(__delay);
  85. EXPORT_SYMBOL(__const_udelay);
  86. EXPORT_SYMBOL(__udelay);
  87. EXPORT_SYMBOL(__ndelay);