Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /******************************************************************************
0003  *
0004  *  (C)Copyright 1998,1999 SysKonnect,
0005  *  a business unit of Schneider & Koch & Co. Datensysteme GmbH.
0006  *
0007  *  See the file "skfddi.c" for further information.
0008  *
0009  *  The information in this file is provided "AS IS" without warranty.
0010  *
0011  ******************************************************************************/
0012 
0013 /*
0014  * Timer Driver for FBI board (timer chip 82C54)
0015  */
0016 
0017 /*
0018  * Modifications:
0019  *
0020  *  28-Jun-1994 sw  Edit v1.6.
0021  *          MCA: Added support for the SK-NET FDDI-FM2 adapter. The
0022  *           following functions have been added(+) or modified(*):
0023  *           hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)
0024  */
0025 
0026 #include "h/types.h"
0027 #include "h/fddi.h"
0028 #include "h/smc.h"
0029 
0030 /*
0031  * Prototypes of local functions.
0032  */
0033 /* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
0034 /*static void hwt_restart() ; */
0035 
0036 /************************
0037  *
0038  *  hwt_start
0039  *
0040  *  Start hardware timer (clock ticks are 16us).
0041  *
0042  *  void hwt_start(
0043  *      struct s_smc *smc,
0044  *      u_long time) ;
0045  * In
0046  *  smc - A pointer to the SMT Context structure.
0047  *
0048  *  time - The time in units of 16us to load the timer with.
0049  * Out
0050  *  Nothing.
0051  *
0052  ************************/
0053 #define HWT_MAX (65000)
0054 
0055 void hwt_start(struct s_smc *smc, u_long time)
0056 {
0057     u_short cnt ;
0058 
0059     if (time > HWT_MAX)
0060         time = HWT_MAX ;
0061 
0062     smc->hw.t_start = time ;
0063     smc->hw.t_stop = 0L ;
0064 
0065     cnt = (u_short)time ;
0066     /*
0067      * if time < 16 us
0068      *  time = 16 us
0069      */
0070     if (!cnt)
0071         cnt++ ;
0072 
0073     outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ;    /* Load timer value. */
0074     outpw(ADDR(B2_TI_CRTL), TIM_START) ;        /* Start timer. */
0075 
0076     smc->hw.timer_activ = TRUE ;
0077 }
0078 
0079 /************************
0080  *
0081  *  hwt_stop
0082  *
0083  *  Stop hardware timer.
0084  *
0085  *  void hwt_stop(
0086  *      struct s_smc *smc) ;
0087  * In
0088  *  smc - A pointer to the SMT Context structure.
0089  * Out
0090  *  Nothing.
0091  *
0092  ************************/
0093 void hwt_stop(struct s_smc *smc)
0094 {
0095     outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
0096     outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
0097 
0098     smc->hw.timer_activ = FALSE ;
0099 }
0100 
0101 /************************
0102  *
0103  *  hwt_init
0104  *
0105  *  Initialize hardware timer.
0106  *
0107  *  void hwt_init(
0108  *      struct s_smc *smc) ;
0109  * In
0110  *  smc - A pointer to the SMT Context structure.
0111  * Out
0112  *  Nothing.
0113  *
0114  ************************/
0115 void hwt_init(struct s_smc *smc)
0116 {
0117     smc->hw.t_start = 0 ;
0118     smc->hw.t_stop  = 0 ;
0119     smc->hw.timer_activ = FALSE ;
0120 
0121     hwt_restart(smc) ;
0122 }
0123 
0124 /************************
0125  *
0126  *  hwt_restart
0127  *
0128  *  Clear timer interrupt.
0129  *
0130  *  void hwt_restart(
0131  *      struct s_smc *smc) ;
0132  * In
0133  *  smc - A pointer to the SMT Context structure.
0134  * Out
0135  *  Nothing.
0136  *
0137  ************************/
0138 void hwt_restart(struct s_smc *smc)
0139 {
0140     hwt_stop(smc) ;
0141 }
0142 
0143 /************************
0144  *
0145  *  hwt_read
0146  *
0147  *  Stop hardware timer and read time elapsed since last start.
0148  *
0149  *  u_long hwt_read(smc) ;
0150  * In
0151  *  smc - A pointer to the SMT Context structure.
0152  * Out
0153  *  The elapsed time since last start in units of 16us.
0154  *
0155  ************************/
0156 u_long hwt_read(struct s_smc *smc)
0157 {
0158     u_short tr ;
0159     u_long  is ;
0160 
0161     if (smc->hw.timer_activ) {
0162         hwt_stop(smc) ;
0163         tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
0164 
0165         is = GET_ISR() ;
0166         /* Check if timer expired (or wraparound). */
0167         if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
0168             hwt_restart(smc) ;
0169             smc->hw.t_stop = smc->hw.t_start ;
0170         }
0171         else
0172             smc->hw.t_stop = smc->hw.t_start - tr ;
0173     }
0174     return smc->hw.t_stop;
0175 }
0176 
0177 #ifdef  PCI
0178 /************************
0179  *
0180  *  hwt_quick_read
0181  *
0182  *  Stop hardware timer and read timer value and start the timer again.
0183  *
0184  *  u_long hwt_read(smc) ;
0185  * In
0186  *  smc - A pointer to the SMT Context structure.
0187  * Out
0188  *  current timer value in units of 80ns.
0189  *
0190  ************************/
0191 u_long hwt_quick_read(struct s_smc *smc)
0192 {
0193     u_long interval ;
0194     u_long time ;
0195 
0196     interval = inpd(ADDR(B2_TI_INI)) ;
0197     outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
0198     time = inpd(ADDR(B2_TI_VAL)) ;
0199     outpd(ADDR(B2_TI_INI),time) ;
0200     outpw(ADDR(B2_TI_CRTL), TIM_START) ;
0201     outpd(ADDR(B2_TI_INI),interval) ;
0202 
0203     return time;
0204 }
0205 
0206 /************************
0207  *
0208  *  hwt_wait_time(smc,start,duration)
0209  *
0210  *  This function returnes after the amount of time is elapsed
0211  *  since the start time.
0212  * 
0213  * para start       start time
0214  *  duration    time to wait
0215  *
0216  * NOTE: The function will return immediately, if the timer is not
0217  *   started
0218  ************************/
0219 void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
0220 {
0221     long    diff ;
0222     long    interval ;
0223     int wrapped ;
0224 
0225     /*
0226      * check if timer is running
0227      */
0228     if (smc->hw.timer_activ == FALSE ||
0229         hwt_quick_read(smc) == hwt_quick_read(smc)) {
0230         return ;
0231     }
0232 
0233     interval = inpd(ADDR(B2_TI_INI)) ;
0234     if (interval > duration) {
0235         do {
0236             diff = (long)(start - hwt_quick_read(smc)) ;
0237             if (diff < 0) {
0238                 diff += interval ;
0239             }
0240         } while (diff <= duration) ;
0241     }
0242     else {
0243         diff = interval ;
0244         wrapped = 0 ;
0245         do {
0246             if (!wrapped) {
0247                 if (hwt_quick_read(smc) >= start) {
0248                     diff += interval ;
0249                     wrapped = 1 ;
0250                 }
0251             }
0252             else {
0253                 if (hwt_quick_read(smc) < start) {
0254                     wrapped = 0 ;
0255                 }
0256             }
0257         } while (diff <= duration) ;
0258     }
0259 }
0260 #endif
0261