* Add support for SK98xx driver
[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 /*
77         Event queue and dispatcher
78 */
79 static const char SysKonnectFileId[] =
80         "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.13 1999/11/22 13:31:12 cgoos Exp $" ;
81
82 #include "h/skdrv1st.h"         /* Driver Specific Definitions */
83 #include "h/skdrv2nd.h"         /* Adapter Control- and Driver specific Def. */
84
85 #ifdef __C2MAN__
86 /*
87         Hardware Timer function queue management.
88
89         General Description:
90
91  */
92 intro()
93 {}
94 #endif
95
96 /*
97  * Prototypes of local functions.
98  */
99 #define SK_HWT_MAX      (65000)
100
101 /* correction factor */
102 #define SK_HWT_FAC      (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
103
104 /*
105  * Initialize hardware timer.
106  *
107  * Must be called during init level 1.
108  */
109 void    SkHwtInit(
110 SK_AC   *pAC,   /* Adapters context */
111 SK_IOC  Ioc)    /* IoContext */
112 {
113         pAC->Hwt.TStart = 0 ;
114         pAC->Hwt.TStop  = 0 ;
115         pAC->Hwt.TActive = SK_FALSE ;
116
117         SkHwtStop(pAC,Ioc) ;
118 }
119
120 /*
121  *
122  * Start hardware timer (clock ticks are 16us).
123  *
124  */
125 void    SkHwtStart(
126 SK_AC   *pAC,   /* Adapters context */
127 SK_IOC  Ioc,    /* IoContext */
128 SK_U32  Time)   /* Time in units of 16us to load the timer with. */
129 {
130         SK_U32  Cnt ;
131
132         if (Time > SK_HWT_MAX)
133                 Time = SK_HWT_MAX ;
134
135         pAC->Hwt.TStart = Time ;
136         pAC->Hwt.TStop = 0L ;
137
138         Cnt = Time ;
139
140         /*
141          * if time < 16 us
142          *      time = 16 us
143          */
144         if (!Cnt) {
145                 Cnt++ ;
146         }
147
148         SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC) ;
149         SK_OUT16(Ioc, B2_TI_CRTL, TIM_START) ;  /* Start timer. */
150
151         pAC->Hwt.TActive = SK_TRUE ;
152 }
153
154 /*
155  * Stop hardware timer.
156  * and clear the timer IRQ
157  */
158 void    SkHwtStop(
159 SK_AC   *pAC,   /* Adapters context */
160 SK_IOC  Ioc)    /* IoContext */
161 {
162         SK_OUT16(Ioc, B2_TI_CRTL, TIM_STOP) ;
163         SK_OUT16(Ioc, B2_TI_CRTL, TIM_CLR_IRQ) ;
164
165         pAC->Hwt.TActive = SK_FALSE ;
166 }
167
168
169 /*
170  *      Stop hardware timer and read time elapsed since last start.
171  *
172  * returns
173  *      The elapsed time since last start in units of 16us.
174  *
175  */
176 SK_U32  SkHwtRead(
177 SK_AC   *pAC,   /* Adapters context */
178 SK_IOC  Ioc)    /* IoContext */
179 {
180         SK_U32  TRead ;
181         SK_U32  IStatus ;
182
183         if (pAC->Hwt.TActive) {
184                 SkHwtStop(pAC,Ioc) ;
185
186                 SK_IN32(Ioc, B2_TI_VAL, &TRead);
187                 TRead /= SK_HWT_FAC;
188
189                 SK_IN32(Ioc, B0_ISRC, &IStatus);
190
191                 /* Check if timer expired (or wraparound). */
192                 if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
193                         SkHwtStop(pAC,Ioc) ;
194                         pAC->Hwt.TStop = pAC->Hwt.TStart ;
195                 } else {
196                         pAC->Hwt.TStop = pAC->Hwt.TStart - TRead ;
197                 }
198         }
199         return (pAC->Hwt.TStop) ;
200 }
201
202 /*
203  * interrupt source= timer
204  */
205 void    SkHwtIsr(
206 SK_AC   *pAC,   /* Adapters context */
207 SK_IOC  Ioc)    /* IoContext */
208 {
209         SkHwtStop(pAC,Ioc);
210         pAC->Hwt.TStop = pAC->Hwt.TStart;
211         SkTimerDone(pAC,Ioc) ;
212 }
213
214 /* End of file */