Merge with /home/m8/git/u-boot
[platform/kernel/u-boot.git] / drivers / sk98lin / skgehwt.c
1 /******************************************************************************
2  *
3  * Name:        skgehwt.c
4  * Project:     GEnesis, PCI Gigabit Ethernet Adapter
5  * Version:     $Revision: 1.13 $
6  * Date:        $Date: 1999/11/22 13:31:12 $
7  * Purpose:     Hardware Timer.
8  *
9  ******************************************************************************/
10
11 /******************************************************************************
12  *
13  *      (C)Copyright 1998,1999 SysKonnect,
14  *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
15  *
16  *      This program is free software; you can redistribute it and/or modify
17  *      it under the terms of the GNU General Public License as published by
18  *      the Free Software Foundation; either version 2 of the License, or
19  *      (at your option) any later version.
20  *
21  *      The information in this file is provided "AS IS" without warranty.
22  *
23  ******************************************************************************/
24
25 /******************************************************************************
26  *
27  * History:
28  *
29  *      $Log: skgehwt.c,v $
30  *      Revision 1.13  1999/11/22 13:31:12  cgoos
31  *      Changed license header to GPL.
32  *
33  *      Revision 1.12  1998/10/15 15:11:34  gklug
34  *      fix: ID_sccs to SysKonnectFileId
35  *
36  *      Revision 1.11  1998/10/08 15:27:51  gklug
37  *      chg: correction factor is host clock dependent
38  *
39  *      Revision 1.10  1998/09/15 14:18:31  cgoos
40  *      Changed more BOOLEANs to SK_xxx
41  *
42  *      Revision 1.9  1998/09/15 14:16:06  cgoos
43  *      Changed line 107: FALSE to SK_FALSE
44  *
45  *      Revision 1.8  1998/08/24 13:04:44  gklug
46  *      fix: typo
47  *
48  *      Revision 1.7  1998/08/19 09:50:49  gklug
49  *      fix: remove struct keyword from c-code (see CCC) add typedefs
50  *
51  *      Revision 1.6  1998/08/17 09:59:02  gklug
52  *      fix: typos
53  *
54  *      Revision 1.5  1998/08/14 07:09:10  gklug
55  *      fix: chg pAc -> pAC
56  *
57  *      Revision 1.4  1998/08/10 14:14:52  gklug
58  *      rmv: unneccessary SK_ADDR macro
59  *
60  *      Revision 1.3  1998/08/07 12:53:44  gklug
61  *      fix: first compiled version
62  *
63  *      Revision 1.2  1998/08/07 09:19:29  gklug
64  *      adapt functions to the C coding conventions
65  *      rmv unneccessary functions.
66  *
67  *      Revision 1.1  1998/08/05 11:28:36  gklug
68  *      first version: adapted from SMT/FDDI
69  *
70  *
71  *
72  *
73  ******************************************************************************/
74
75
76 #include <config.h>
77
78 #ifdef CONFIG_SK98
79
80 /*
81         Event queue and dispatcher
82 */
83 static const char SysKonnectFileId[] =
84         "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.13 1999/11/22 13:31:12 cgoos Exp $" ;
85
86 #include "h/skdrv1st.h"         /* Driver Specific Definitions */
87 #include "h/skdrv2nd.h"         /* Adapter Control- and Driver specific Def. */
88
89 #ifdef __C2MAN__
90 /*
91         Hardware Timer function queue management.
92
93         General Description:
94
95  */
96 intro()
97 {}
98 #endif
99
100 /*
101  * Prototypes of local functions.
102  */
103 #define SK_HWT_MAX      (65000)
104
105 /* correction factor */
106 #define SK_HWT_FAC      (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
107
108 /*
109  * Initialize hardware timer.
110  *
111  * Must be called during init level 1.
112  */
113 void    SkHwtInit(
114 SK_AC   *pAC,   /* Adapters context */
115 SK_IOC  Ioc)    /* IoContext */
116 {
117         pAC->Hwt.TStart = 0 ;
118         pAC->Hwt.TStop  = 0 ;
119         pAC->Hwt.TActive = SK_FALSE ;
120
121         SkHwtStop(pAC,Ioc) ;
122 }
123
124 /*
125  *
126  * Start hardware timer (clock ticks are 16us).
127  *
128  */
129 void    SkHwtStart(
130 SK_AC   *pAC,   /* Adapters context */
131 SK_IOC  Ioc,    /* IoContext */
132 SK_U32  Time)   /* Time in units of 16us to load the timer with. */
133 {
134         SK_U32  Cnt ;
135
136         if (Time > SK_HWT_MAX)
137                 Time = SK_HWT_MAX ;
138
139         pAC->Hwt.TStart = Time ;
140         pAC->Hwt.TStop = 0L ;
141
142         Cnt = Time ;
143
144         /*
145          * if time < 16 us
146          *      time = 16 us
147          */
148         if (!Cnt) {
149                 Cnt++ ;
150         }
151
152         SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC) ;
153         SK_OUT16(Ioc, B2_TI_CRTL, TIM_START) ;  /* Start timer. */
154
155         pAC->Hwt.TActive = SK_TRUE ;
156 }
157
158 /*
159  * Stop hardware timer.
160  * and clear the timer IRQ
161  */
162 void    SkHwtStop(
163 SK_AC   *pAC,   /* Adapters context */
164 SK_IOC  Ioc)    /* IoContext */
165 {
166         SK_OUT16(Ioc, B2_TI_CRTL, TIM_STOP) ;
167         SK_OUT16(Ioc, B2_TI_CRTL, TIM_CLR_IRQ) ;
168
169         pAC->Hwt.TActive = SK_FALSE ;
170 }
171
172
173 /*
174  *      Stop hardware timer and read time elapsed since last start.
175  *
176  * returns
177  *      The elapsed time since last start in units of 16us.
178  *
179  */
180 SK_U32  SkHwtRead(
181 SK_AC   *pAC,   /* Adapters context */
182 SK_IOC  Ioc)    /* IoContext */
183 {
184         SK_U32  TRead ;
185         SK_U32  IStatus ;
186
187         if (pAC->Hwt.TActive) {
188                 SkHwtStop(pAC,Ioc) ;
189
190                 SK_IN32(Ioc, B2_TI_VAL, &TRead);
191                 TRead /= SK_HWT_FAC;
192
193                 SK_IN32(Ioc, B0_ISRC, &IStatus);
194
195                 /* Check if timer expired (or wraparound). */
196                 if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
197                         SkHwtStop(pAC,Ioc) ;
198                         pAC->Hwt.TStop = pAC->Hwt.TStart ;
199                 } else {
200                         pAC->Hwt.TStop = pAC->Hwt.TStart - TRead ;
201                 }
202         }
203         return (pAC->Hwt.TStop) ;
204 }
205
206 /*
207  * interrupt source= timer
208  */
209 void    SkHwtIsr(
210 SK_AC   *pAC,   /* Adapters context */
211 SK_IOC  Ioc)    /* IoContext */
212 {
213         SkHwtStop(pAC,Ioc);
214         pAC->Hwt.TStop = pAC->Hwt.TStart;
215         SkTimerDone(pAC,Ioc) ;
216 }
217
218 #endif /* CONFIG_SK98 */
219
220 /* End of file */