source: rtems/c/src/lib/libbsp/sparc/shared/time/grctm.c @ 5823bae8

4.11
Last change on this file since 5823bae8 was 5823bae8, checked in by Daniel Hellstrom <daniel@…>, on Feb 27, 2015 at 1:03:15 PM

LEON: move driver headers to bsp/ directory

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*  GRCTM - CCSDS Time Manager - register driver interface.
2 *
3 *  COPYRIGHT (c) 2009.
4 *  Cobham Gaisler AB.
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 */
10
11#include <drvmgr/drvmgr.h>
12#include <drvmgr/ambapp_bus.h>
13#include <stdlib.h>
14
15#include <bsp/grctm.h>
16
17/* Private structure of GRCTM driver */
18struct grctm_priv {
19        struct drvmgr_dev *dev;
20        struct grctm_regs *regs;
21        int open;
22
23        grctm_isr_t user_isr;
24        void *user_isr_arg;
25
26        struct grctm_stats stats;
27};
28
29void grctm_isr(void *data);
30
31struct amba_drv_info grctm_drv_info;
32
33void *grctm_open(int minor)
34{
35        struct grctm_priv *priv;
36        struct drvmgr_dev *dev;
37
38        /* Get Device from Minor */
39        if ( drvmgr_get_dev(&grctm_drv_info.general, minor, &dev) ) {
40                return NULL;
41        }
42
43        priv = dev->priv;
44        if ( (priv == NULL) || priv->open )
45                return NULL;
46
47        /* Set initial state of software */
48        priv->open = 1;
49
50        /* Clear Statistics */
51        grctm_clr_stats(priv);
52        priv->user_isr = NULL;
53        priv->user_isr_arg = NULL;
54
55        return priv;
56}
57
58void grctm_close(void *grctm)
59{
60        struct grctm_priv *priv = (struct grctm_priv *)grctm;
61
62        if ( priv->open == 0 )
63                return;
64
65        /* Reset Hardware */
66        grctm_reset(priv);
67
68        priv->open = 0;
69}
70
71/* Hardware Reset of GRCTM */
72int grctm_reset(void *grctm)
73{
74        struct grctm_priv *priv = grctm;
75        struct grctm_regs *r = priv->regs;
76
77        r->grr = 0x55000001;
78
79        int i = 1000;
80        while ((r->grr & 1) && i > 0) {
81                i--;
82        }
83
84        return i ? 0 : -1;
85}
86
87void grctm_int_enable(void *grctm)
88{
89        struct grctm_priv *priv = (struct grctm_priv *)grctm;
90
91        /* Register and Enable Interrupt at Interrupt controller */
92        drvmgr_interrupt_register(priv->dev, 0, "grctm", grctm_isr, priv);
93}
94
95void grctm_int_disable(void *grctm)
96{
97        struct grctm_priv *priv = (struct grctm_priv *)grctm;
98
99        /* Enable Interrupt at Interrupt controller */
100        drvmgr_interrupt_unregister(priv->dev, 0, grctm_isr, priv);
101}
102
103void grctm_clr_stats(void *grctm)
104{
105        struct grctm_priv *priv = (struct grctm_priv *)grctm;
106
107        memset(&priv->stats, 0, sizeof(priv->stats));
108}
109
110void grctm_get_stats(void *grctm, struct grctm_stats *stats)
111{
112        struct grctm_priv *priv = (struct grctm_priv *)grctm;
113
114        memcpy(stats, &priv->stats, sizeof(priv->stats));
115}
116
117/* Enable external synchronisation (from grctm) */
118void grctm_enable_ext_sync(void *grctm)
119{
120        struct grctm_priv *priv = grctm;
121
122        priv->regs->gcr |= 0x55<<24 | 1<<9;
123}
124
125/* Disable external synchronisation (from grctm) */
126void grctm_disable_ext_sync(void *grctm)
127{
128        struct grctm_priv *priv = grctm;
129
130        priv->regs->gcr &= ~((0xAA<<24) | 1<<9);
131}
132
133/* Enable TimeWire synchronisation */
134void grctm_enable_tw_sync(void *grctm)
135{
136        struct grctm_priv *priv = grctm;
137
138        priv->regs->gcr |= 0x55<<24 | 1<<8;
139}
140
141/* Disable TimeWire synchronisation */
142void grctm_disable_tw_sync(void *grctm)
143{
144        struct grctm_priv *priv = grctm;
145
146        priv->regs->gcr &= ~((0xAA<<24) | 1<<8);
147}
148
149/* Disable frequency synthesizer from driving ET */
150void grctm_disable_fs(void *grctm)
151{
152        struct grctm_priv *priv = grctm;
153
154        priv->regs->gcr |= 0x55<<24 | 1<<7;
155}
156
157/* Enable frequency synthesizer to drive ET */
158void grctm_enable_fs(void *grctm)
159{
160        struct grctm_priv *priv = grctm;
161
162        priv->regs->gcr &= ~((0xAA<<24) | 1<<7);
163}
164
165/* Return elapsed coarse time */
166unsigned int grctm_get_et_coarse(void *grctm)
167{
168        struct grctm_priv *priv = grctm;
169
170        return priv->regs->etcr;
171}
172
173/* Return elapsed fine time */
174unsigned int grctm_get_et_fine(void *grctm)
175{
176        struct grctm_priv *priv = grctm;
177
178        return (priv->regs->etfr & 0xffffff00) >> 8;
179}
180
181/* Return elapsed time (coarse and fine) */
182unsigned long long grctm_get_et(void *grctm)
183{
184        return (((unsigned long)grctm_get_et_coarse(grctm)) << 24) | grctm_get_et_fine(grctm);
185}
186
187
188/* Return 1 if specified datation has been latched */
189int grctm_is_dat_latched(void *grctm, int dat)
190{
191        struct grctm_priv *priv = grctm;
192
193        return (priv->regs->gsr >> dat) & 1;
194}
195
196/* Set triggering edge of datation input */
197void grctm_set_dat_edge(void *grctm, int dat, int edge)
198{
199        struct grctm_priv *priv = grctm;
200
201        priv->regs->gcr &= ~((0xAA<<24) | 1 << (10+dat));
202        priv->regs->gcr |= 0x55<<24 | (edge&1) << (10+dat);
203}
204
205/* Return latched datation coarse time */
206unsigned int grctm_get_dat_coarse(void *grctm, int dat)
207{
208        struct grctm_priv *priv = grctm;
209
210        switch (dat) {
211        case 0 : return priv->regs->dcr0; 
212        case 1 : return priv->regs->dcr1;
213        case 2 : return priv->regs->dcr2;
214        default: return -1;
215        }
216}
217
218/* Return latched datation fine time */
219unsigned int grctm_get_dat_fine(void *grctm, int dat)
220{
221        struct grctm_priv *priv = grctm;
222
223        switch (dat) {
224        case 0 : return (priv->regs->dfr0 & 0xffffff00) >> 8; 
225        case 1 : return (priv->regs->dfr1 & 0xffffff00) >> 8;
226        case 2 : return (priv->regs->dfr2 & 0xffffff00) >> 8;
227        default: return -1;
228        }
229}
230
231
232/* Return latched datation ET */
233unsigned long long grctm_get_dat_et(void *grctm, int dat)
234{
235        return (((unsigned long)grctm_get_dat_coarse(grctm, dat)) << 24) | 
236                grctm_get_dat_fine(grctm, dat);
237}
238
239
240/* Return current pulse configuration */
241unsigned int grctm_get_pulse_reg(void *grctm, int pulse)
242{
243        struct grctm_priv *priv = grctm;
244
245        return priv->regs->pdr[pulse];
246}
247
248/* Set pulse register */
249void grctm_set_pulse_reg(void *grctm, int pulse, unsigned int val)
250{
251        struct grctm_priv *priv = grctm;
252
253        priv->regs->pdr[pulse] = val;
254}
255
256/* Configure pulse: pp = period, pw = width, pl = level, en = enable */
257void grctm_cfg_pulse(void *grctm, int pulse, int pp, int pw, int pl, int en)
258{
259        grctm_set_pulse_reg(grctm, pulse, (pp&0xf)<<20 | (pw&0xf)<<16 | (pl&1)<<10 | (en&1)<<1);
260}
261
262/* Enable pulse output */
263void grctm_enable_pulse(void *grctm, int pulse)
264{
265        struct grctm_priv *priv = grctm;
266
267        priv->regs->pdr[pulse] |= 0x2;
268}
269
270/* Disable pulse output */
271void grctm_disable_pulse(void *grctm, int pulse)
272{
273        struct grctm_priv *priv = grctm;
274
275        priv->regs->pdr[pulse] &= ~0x2;
276}
277
278/* Clear interrupts */
279void grctm_clear_irqs(void *grctm, int irqs)
280{
281        struct grctm_priv *priv = grctm;
282
283        priv->regs->picr = irqs;
284}
285
286/* Enable interrupts */
287void grctm_enable_irqs(void *grctm, int irqs)
288{
289        struct grctm_priv *priv = grctm;
290
291        priv->regs->imr  = irqs;
292}
293
294/* Set Frequency synthesizer increment */
295void grctm_set_fs_incr(void *grctm, int incr)
296{
297        struct grctm_priv *priv = grctm;
298
299        priv->regs->fsir  = incr;
300}
301
302/* Set ET increment */
303void grctm_set_et_incr(void *grctm, int incr)
304{
305        struct grctm_priv *priv = grctm;
306
307        priv->regs->etir  = incr;
308}
309
310
311void grctm_isr(void *data)
312{
313        struct grctm_priv *priv = data;
314        struct grctm_stats *stats = &priv->stats;
315        unsigned int pimr = priv->regs->pimr;
316
317        if ( pimr == 0 )
318                return;
319
320        stats->nirqs++;
321        if (pimr & PULSE0_IRQ )
322                stats->pulse++;
323
324        /* Let user Handle Interrupt */
325        if ( priv->user_isr )
326                priv->user_isr(pimr, priv->user_isr_arg);
327}
328
329struct grctm_regs *grctm_get_regs(void *grctm)
330{
331        struct grctm_priv *priv = (struct grctm_priv *)grctm;
332
333        return priv->regs;
334}
335
336void grctm_int_register(void *grctm, grctm_isr_t func, void *data)
337{
338        struct grctm_priv *priv = (struct grctm_priv *)grctm;
339
340        priv->user_isr = func;
341        priv->user_isr_arg = data;
342}
343
344/*** INTERFACE TO DRIVER MANAGER ***/
345
346static int grctm_init2(struct drvmgr_dev *dev)
347{
348        struct amba_dev_info *ambadev;
349        struct ambapp_core *pnpinfo;
350        struct grctm_priv *priv;
351        struct grctm_regs *regs;
352
353        priv = (struct grctm_priv *)malloc(sizeof(*priv));
354        if ( priv == NULL )
355                return -1;
356        memset(priv, 0, sizeof(*priv));
357        priv->dev = dev;
358        dev->priv = priv;
359
360        /* Get device information from AMBA PnP information */
361        ambadev = (struct amba_dev_info *)dev->businfo;
362        if ( ambadev == NULL ) {
363                return -1;
364        }
365        pnpinfo = &ambadev->info;
366        regs = (struct grctm_regs *)pnpinfo->ahb_slv->start[0];
367
368        priv->regs = regs;
369
370        grctm_reset(priv);
371
372        return 0;
373}
374
375struct drvmgr_drv_ops grctm_ops =
376{
377        {NULL, grctm_init2, NULL, NULL},
378        NULL,
379        NULL
380};
381
382struct amba_dev_id grctm_ids[] =
383{
384        {VENDOR_GAISLER, GAISLER_GRCTM},
385        {0, 0}  /* Mark end of table */
386};
387
388struct amba_drv_info grctm_drv_info =
389{
390        {
391                DRVMGR_OBJ_DRV,                 /* Driver */
392                NULL,                           /* Next driver */
393                NULL,                           /* Device list */
394                DRIVER_AMBAPP_GAISLER_GRCTM_ID, /* Driver ID */
395                "GRCTM_DRV",                    /* Driver Name */
396                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
397                &grctm_ops,
398                NULL,                           /* Funcs */
399                0,                              /* No devices yet */
400                0,
401        },
402        &grctm_ids[0]
403};
404
405/* Register the grctm Driver */
406void grctm_register(void)
407{
408        drvmgr_drv_register(&grctm_drv_info.general);
409}
Note: See TracBrowser for help on using the repository browser.