delay.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * linux/arch/m32r/lib/delay.c
  3. *
  4. * Copyright (c) 2002 Hitoshi Yamamoto, Hirokazu Takata
  5. * Copyright (c) 2004 Hirokazu Takata
  6. */
  7. #include <linux/param.h>
  8. #include <linux/module.h>
  9. #ifdef CONFIG_SMP
  10. #include <linux/sched.h>
  11. #include <asm/current.h>
  12. #include <asm/smp.h>
  13. #endif /* CONFIG_SMP */
  14. #include <asm/processor.h>
  15. void __delay(unsigned long loops)
  16. {
  17. #ifdef CONFIG_ISA_DUAL_ISSUE
  18. __asm__ __volatile__ (
  19. "beqz %0, 2f \n\t"
  20. "addi %0, #-1 \n\t"
  21. " .fillinsn \n\t"
  22. "1: \n\t"
  23. "cmpz %0 || addi %0, #-1 \n\t"
  24. "bc 2f || cmpz %0 \n\t"
  25. "bc 2f || addi %0, #-1 \n\t"
  26. "cmpz %0 || addi %0, #-1 \n\t"
  27. "bc 2f || cmpz %0 \n\t"
  28. "bnc 1b || addi %0, #-1 \n\t"
  29. " .fillinsn \n\t"
  30. "2: \n\t"
  31. : "+r" (loops)
  32. : "r" (0)
  33. : "cbit"
  34. );
  35. #else
  36. __asm__ __volatile__ (
  37. "beqz %0, 2f \n\t"
  38. " .fillinsn \n\t"
  39. "1: \n\t"
  40. "addi %0, #-1 \n\t"
  41. "blez %0, 2f \n\t"
  42. "addi %0, #-1 \n\t"
  43. "blez %0, 2f \n\t"
  44. "addi %0, #-1 \n\t"
  45. "blez %0, 2f \n\t"
  46. "addi %0, #-1 \n\t"
  47. "bgtz %0, 1b \n\t"
  48. " .fillinsn \n\t"
  49. "2: \n\t"
  50. : "+r" (loops)
  51. : "r" (0)
  52. );
  53. #endif
  54. }
  55. void __const_udelay(unsigned long xloops)
  56. {
  57. #if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
  58. /*
  59. * loops [1] = (xloops >> 32) [sec] * loops_per_jiffy [1/jiffy]
  60. * * HZ [jiffy/sec]
  61. * = (xloops >> 32) [sec] * (loops_per_jiffy * HZ) [1/sec]
  62. * = (((xloops * loops_per_jiffy) >> 32) * HZ) [1]
  63. *
  64. * NOTE:
  65. * - '[]' depicts variable's dimension in the above equation.
  66. * - "rac" instruction rounds the accumulator in word size.
  67. */
  68. __asm__ __volatile__ (
  69. "srli %0, #1 \n\t"
  70. "mulwhi %0, %1 ; a0 \n\t"
  71. "mulwu1 %0, %1 ; a1 \n\t"
  72. "sadd ; a0 += (a1 >> 16) \n\t"
  73. "rac a0, a0, #1 \n\t"
  74. "mvfacmi %0, a0 \n\t"
  75. : "+r" (xloops)
  76. : "r" (current_cpu_data.loops_per_jiffy)
  77. : "a0", "a1"
  78. );
  79. #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
  80. /*
  81. * u64 ull;
  82. * ull = (u64)xloops * (u64)current_cpu_data.loops_per_jiffy;
  83. * xloops = (ull >> 32);
  84. */
  85. __asm__ __volatile__ (
  86. "and3 r4, %0, #0xffff \n\t"
  87. "and3 r5, %1, #0xffff \n\t"
  88. "mul r4, r5 \n\t"
  89. "srl3 r6, %0, #16 \n\t"
  90. "srli r4, #16 \n\t"
  91. "mul r5, r6 \n\t"
  92. "add r4, r5 \n\t"
  93. "and3 r5, %0, #0xffff \n\t"
  94. "srl3 r6, %1, #16 \n\t"
  95. "mul r5, r6 \n\t"
  96. "add r4, r5 \n\t"
  97. "srl3 r5, %0, #16 \n\t"
  98. "srli r4, #16 \n\t"
  99. "mul r5, r6 \n\t"
  100. "add r4, r5 \n\t"
  101. "mv %0, r4 \n\t"
  102. : "+r" (xloops)
  103. : "r" (current_cpu_data.loops_per_jiffy)
  104. : "r4", "r5", "r6"
  105. );
  106. #else
  107. #error unknown isa configuration
  108. #endif
  109. __delay(xloops * HZ);
  110. }
  111. void __udelay(unsigned long usecs)
  112. {
  113. __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
  114. }
  115. void __ndelay(unsigned long nsecs)
  116. {
  117. __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
  118. }
  119. EXPORT_SYMBOL(__delay);
  120. EXPORT_SYMBOL(__const_udelay);
  121. EXPORT_SYMBOL(__udelay);
  122. EXPORT_SYMBOL(__ndelay);