delay.c 2.8 KB

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