hwt.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /******************************************************************************
  3. *
  4. * (C)Copyright 1998,1999 SysKonnect,
  5. * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  6. *
  7. * See the file "skfddi.c" for further information.
  8. *
  9. * The information in this file is provided "AS IS" without warranty.
  10. *
  11. ******************************************************************************/
  12. /*
  13. * Timer Driver for FBI board (timer chip 82C54)
  14. */
  15. /*
  16. * Modifications:
  17. *
  18. * 28-Jun-1994 sw Edit v1.6.
  19. * MCA: Added support for the SK-NET FDDI-FM2 adapter. The
  20. * following functions have been added(+) or modified(*):
  21. * hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)
  22. */
  23. #include "h/types.h"
  24. #include "h/fddi.h"
  25. #include "h/smc.h"
  26. /*
  27. * Prototypes of local functions.
  28. */
  29. /* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
  30. /*static void hwt_restart() ; */
  31. /************************
  32. *
  33. * hwt_start
  34. *
  35. * Start hardware timer (clock ticks are 16us).
  36. *
  37. * void hwt_start(
  38. * struct s_smc *smc,
  39. * u_long time) ;
  40. * In
  41. * smc - A pointer to the SMT Context structure.
  42. *
  43. * time - The time in units of 16us to load the timer with.
  44. * Out
  45. * Nothing.
  46. *
  47. ************************/
  48. #define HWT_MAX (65000)
  49. void hwt_start(struct s_smc *smc, u_long time)
  50. {
  51. u_short cnt ;
  52. if (time > HWT_MAX)
  53. time = HWT_MAX ;
  54. smc->hw.t_start = time ;
  55. smc->hw.t_stop = 0L ;
  56. cnt = (u_short)time ;
  57. /*
  58. * if time < 16 us
  59. * time = 16 us
  60. */
  61. if (!cnt)
  62. cnt++ ;
  63. outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ; /* Load timer value. */
  64. outpw(ADDR(B2_TI_CRTL), TIM_START) ; /* Start timer. */
  65. smc->hw.timer_activ = TRUE ;
  66. }
  67. /************************
  68. *
  69. * hwt_stop
  70. *
  71. * Stop hardware timer.
  72. *
  73. * void hwt_stop(
  74. * struct s_smc *smc) ;
  75. * In
  76. * smc - A pointer to the SMT Context structure.
  77. * Out
  78. * Nothing.
  79. *
  80. ************************/
  81. void hwt_stop(struct s_smc *smc)
  82. {
  83. outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
  84. outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
  85. smc->hw.timer_activ = FALSE ;
  86. }
  87. /************************
  88. *
  89. * hwt_init
  90. *
  91. * Initialize hardware timer.
  92. *
  93. * void hwt_init(
  94. * struct s_smc *smc) ;
  95. * In
  96. * smc - A pointer to the SMT Context structure.
  97. * Out
  98. * Nothing.
  99. *
  100. ************************/
  101. void hwt_init(struct s_smc *smc)
  102. {
  103. smc->hw.t_start = 0 ;
  104. smc->hw.t_stop = 0 ;
  105. smc->hw.timer_activ = FALSE ;
  106. hwt_restart(smc) ;
  107. }
  108. /************************
  109. *
  110. * hwt_restart
  111. *
  112. * Clear timer interrupt.
  113. *
  114. * void hwt_restart(
  115. * struct s_smc *smc) ;
  116. * In
  117. * smc - A pointer to the SMT Context structure.
  118. * Out
  119. * Nothing.
  120. *
  121. ************************/
  122. void hwt_restart(struct s_smc *smc)
  123. {
  124. hwt_stop(smc) ;
  125. }
  126. /************************
  127. *
  128. * hwt_read
  129. *
  130. * Stop hardware timer and read time elapsed since last start.
  131. *
  132. * u_long hwt_read(smc) ;
  133. * In
  134. * smc - A pointer to the SMT Context structure.
  135. * Out
  136. * The elapsed time since last start in units of 16us.
  137. *
  138. ************************/
  139. u_long hwt_read(struct s_smc *smc)
  140. {
  141. u_short tr ;
  142. u_long is ;
  143. if (smc->hw.timer_activ) {
  144. hwt_stop(smc) ;
  145. tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
  146. is = GET_ISR() ;
  147. /* Check if timer expired (or wraparound). */
  148. if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
  149. hwt_restart(smc) ;
  150. smc->hw.t_stop = smc->hw.t_start ;
  151. }
  152. else
  153. smc->hw.t_stop = smc->hw.t_start - tr ;
  154. }
  155. return smc->hw.t_stop;
  156. }
  157. #ifdef PCI
  158. /************************
  159. *
  160. * hwt_quick_read
  161. *
  162. * Stop hardware timer and read timer value and start the timer again.
  163. *
  164. * u_long hwt_read(smc) ;
  165. * In
  166. * smc - A pointer to the SMT Context structure.
  167. * Out
  168. * current timer value in units of 80ns.
  169. *
  170. ************************/
  171. u_long hwt_quick_read(struct s_smc *smc)
  172. {
  173. u_long interval ;
  174. u_long time ;
  175. interval = inpd(ADDR(B2_TI_INI)) ;
  176. outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
  177. time = inpd(ADDR(B2_TI_VAL)) ;
  178. outpd(ADDR(B2_TI_INI),time) ;
  179. outpw(ADDR(B2_TI_CRTL), TIM_START) ;
  180. outpd(ADDR(B2_TI_INI),interval) ;
  181. return time;
  182. }
  183. /************************
  184. *
  185. * hwt_wait_time(smc,start,duration)
  186. *
  187. * This function returnes after the amount of time is elapsed
  188. * since the start time.
  189. *
  190. * para start start time
  191. * duration time to wait
  192. *
  193. * NOTE: The function will return immediately, if the timer is not
  194. * started
  195. ************************/
  196. void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
  197. {
  198. long diff ;
  199. long interval ;
  200. int wrapped ;
  201. /*
  202. * check if timer is running
  203. */
  204. if (smc->hw.timer_activ == FALSE ||
  205. hwt_quick_read(smc) == hwt_quick_read(smc)) {
  206. return ;
  207. }
  208. interval = inpd(ADDR(B2_TI_INI)) ;
  209. if (interval > duration) {
  210. do {
  211. diff = (long)(start - hwt_quick_read(smc)) ;
  212. if (diff < 0) {
  213. diff += interval ;
  214. }
  215. } while (diff <= duration) ;
  216. }
  217. else {
  218. diff = interval ;
  219. wrapped = 0 ;
  220. do {
  221. if (!wrapped) {
  222. if (hwt_quick_read(smc) >= start) {
  223. diff += interval ;
  224. wrapped = 1 ;
  225. }
  226. }
  227. else {
  228. if (hwt_quick_read(smc) < start) {
  229. wrapped = 0 ;
  230. }
  231. }
  232. } while (diff <= duration) ;
  233. }
  234. }
  235. #endif