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