source: rtems/bsps/shared/grlib/1553/gr1553b.c @ 7eb606d3

Last change on this file since 7eb606d3 was 7eb606d3, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 22, 2018 at 5:31:04 PM

grlib: Move source files

Update #3678.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*  GR1553B driver, used by BC, RT and/or BM driver
2 *
3 *  COPYRIGHT (c) 2010.
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.org/license/LICENSE.
9 */
10
11#include <stdlib.h>
12#include <grlib/ambapp_bus.h>
13
14#include <grlib/gr1553b.h>
15
16#include <grlib/grlib_impl.h>
17
18/* Driver Manager interface for BC, RT, BM, BRM, BC-BM and RT-BM */
19
20#define GR1553B_WRITE_REG(adr, val) *(volatile uint32_t *)(adr) = (val)
21#define GR1553B_READ_REG(adr) (*(volatile uint32_t *)(adr))
22
23#define FEAT_BC 0x1
24#define FEAT_RT 0x2
25#define FEAT_BM 0x4
26
27#define ALLOC_BC 0x1
28#define ALLOC_RT 0x2
29#define ALLOC_BM 0x4
30
31struct gr1553_device {
32        struct drvmgr_dev *dev;
33        int features;
34        int alloc;
35};
36
37struct gr1553_device_feature {
38        struct gr1553_device_feature *next;
39        struct gr1553_device *dev;
40        int minor;
41};
42
43/* Device lists */
44static struct gr1553_device_feature *gr1553_bm_root = NULL;
45static struct gr1553_device_feature *gr1553_rt_root = NULL;
46static struct gr1553_device_feature *gr1553_bc_root = NULL;
47
48/* Driver registered */
49static int gr1553_driver_registerd = 0;
50
51/* Add 'feat' to linked list pointed to by 'root'. A minor is also assigned. */
52static void gr1553_list_add
53        (
54        struct gr1553_device_feature **root,
55        struct gr1553_device_feature *feat
56        )
57{
58        int minor;
59        struct gr1553_device_feature *curr;
60
61        if ( *root == NULL ) {
62                *root = feat;
63                feat->next = NULL;
64                feat->minor = 0;
65                return;
66        }
67
68        minor = 0;
69retry_new_minor:
70        curr = *root;
71        while ( curr->next ) {
72                if ( curr->minor == minor ) {
73                        minor++;
74                        goto retry_new_minor;
75                }
76                curr = curr->next;
77        }
78
79        feat->next = NULL;
80        feat->minor = minor;
81        curr->next = feat;
82}
83
84static struct gr1553_device_feature *gr1553_list_find
85        (
86        struct gr1553_device_feature *root,
87        int minor
88        )
89{
90        struct gr1553_device_feature *curr = root;
91        while ( curr ) {
92                if ( curr->minor == minor ) {
93                        return curr;
94                }
95                curr = curr->next;
96        }
97        return NULL;
98}
99
100struct drvmgr_dev **gr1553_bc_open(int minor)
101{
102        struct gr1553_device_feature *feat;
103       
104        feat = gr1553_list_find(gr1553_bc_root, minor);
105        if ( feat == NULL )
106                return NULL;
107
108        /* Only possible to allocate is RT and BC is free,
109         * this is beacuse it is not possible to use the
110         * RT and the BC at the same time.
111         */
112        if ( feat->dev->alloc & (ALLOC_BC|ALLOC_RT) )
113                return NULL;
114
115        /* Alloc BC device */
116        feat->dev->alloc |= ALLOC_BC;
117
118        return &feat->dev->dev;
119}
120
121void gr1553_bc_close(struct drvmgr_dev **dev)
122{
123        struct gr1553_device *d = (struct gr1553_device *)dev;
124
125        d->alloc &= ~ALLOC_BC;
126}
127
128struct drvmgr_dev **gr1553_rt_open(int minor)
129{
130        struct gr1553_device_feature *feat;
131
132        feat = gr1553_list_find(gr1553_rt_root, minor);
133        if ( feat == NULL )
134                return NULL;
135
136        /* Only possible to allocate is RT and BC is free,
137         * this is beacuse it is not possible to use the
138         * RT and the BC at the same time.
139         */
140        if ( feat->dev->alloc & (ALLOC_BC|ALLOC_RT) )
141                return NULL;
142
143        /* Alloc RT device */
144        feat->dev->alloc |= ALLOC_RT;
145
146        return &feat->dev->dev;
147}
148
149void gr1553_rt_close(struct drvmgr_dev **dev)
150{
151        struct gr1553_device *d = (struct gr1553_device *)dev;
152
153        d->alloc &= ~ALLOC_RT;
154}
155
156struct drvmgr_dev **gr1553_bm_open(int minor)
157{
158        struct gr1553_device_feature *feat;
159       
160        feat = gr1553_list_find(gr1553_bm_root, minor);
161        if ( feat == NULL )
162                return NULL;
163
164        /* Only possible to allocate is RT and BC is free,
165         * this is beacuse it is not possible to use the
166         * RT and the BC at the same time.
167         */
168        if ( feat->dev->alloc & ALLOC_BM )
169                return NULL;
170
171        /* Alloc BM device */
172        feat->dev->alloc |= ALLOC_BM;
173
174        return &feat->dev->dev;
175}
176
177void gr1553_bm_close(struct drvmgr_dev **dev)
178{
179        struct gr1553_device *d = (struct gr1553_device *)dev;
180
181        d->alloc &= ~ALLOC_BM;
182}
183
184static int gr1553_init2(struct drvmgr_dev *dev)
185{
186        struct amba_dev_info *ambadev;
187        struct ambapp_core *pnpinfo;
188        struct gr1553b_regs *regs;
189
190        /* Get device information from AMBA PnP information */
191        ambadev = (struct amba_dev_info *)dev->businfo;
192        if ( ambadev == NULL ) {
193                return DRVMGR_FAIL;
194        }
195        pnpinfo = &ambadev->info;
196        if ( pnpinfo->apb_slv == NULL )
197                return DRVMGR_EIO;
198        regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
199
200        /* Stop IRQ */
201        GR1553B_WRITE_REG(&regs->imask, 0);
202        GR1553B_WRITE_REG(&regs->irq, 0xffffffff);
203        /* Stop BC if not already stopped (just in case) */
204        GR1553B_WRITE_REG(&regs->bc_ctrl, 0x15520204);
205        /* Stop RT rx (just in case) */
206        GR1553B_WRITE_REG(&regs->rt_cfg, 0x15530000);
207        /* Stop BM logging (just in case) */
208        GR1553B_WRITE_REG(&regs->bm_ctrl, 0);
209
210        return DRVMGR_OK;
211}
212
213/* Register the different functionalities that the
214 * core supports.
215 */
216static int gr1553_init3(struct drvmgr_dev *dev)
217{
218        struct amba_dev_info *ambadev;
219        struct ambapp_core *pnpinfo;
220        struct gr1553_device *priv;
221        struct gr1553_device_feature *feat;
222        struct gr1553b_regs *regs;
223
224        priv = grlib_malloc(sizeof(*priv));
225        if ( priv == NULL )
226                return DRVMGR_NOMEM;
227        priv->dev = dev;
228        priv->alloc = 0;
229        priv->features = 0;
230        dev->priv = NULL; /* Let higher level driver handle this */
231
232        /* Get device information from AMBA PnP information */
233        ambadev = (struct amba_dev_info *)dev->businfo;
234        pnpinfo = &ambadev->info;
235        regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
236
237        if ( GR1553B_READ_REG(&regs->bm_stat) & GR1553B_BM_STAT_BMSUP ) {
238                priv->features |= FEAT_BM;
239                feat = grlib_malloc(sizeof(*feat));
240                feat->dev = priv;
241                /* Init Minor and Next */
242                gr1553_list_add(&gr1553_bm_root, feat);
243        }
244
245        if ( GR1553B_READ_REG(&regs->bc_stat) & GR1553B_BC_STAT_BCSUP ) {
246                priv->features |= FEAT_BC;
247                feat = grlib_malloc(sizeof(*feat));
248                feat->dev = priv;
249                /* Init Minor and Next */
250                gr1553_list_add(&gr1553_bc_root, feat);
251        }
252
253        if ( GR1553B_READ_REG(&regs->rt_stat) & GR1553B_RT_STAT_RTSUP ) {
254                priv->features |= FEAT_RT;
255                feat = grlib_malloc(sizeof(*feat));
256                feat->dev = priv;
257                /* Init Minor and Next */
258                gr1553_list_add(&gr1553_rt_root, feat);
259        }
260
261        if ( priv->features == 0 ) {
262                /* no features in HW should never happen.. an I/O error? */
263                free(priv);
264                return DRVMGR_EIO;
265        }
266
267        return DRVMGR_OK;
268}
269
270struct drvmgr_drv_ops gr1553_ops =
271{
272        {NULL, gr1553_init2, gr1553_init3, NULL},
273        NULL,
274        NULL
275};
276
277struct amba_dev_id gr1553_ids[] =
278{
279        {VENDOR_GAISLER, GAISLER_GR1553B},
280        {0, 0}  /* Mark end of table */
281};
282
283struct amba_drv_info gr1553_drv_info =
284{
285        {
286                DRVMGR_OBJ_DRV,                 /* Driver */
287                NULL,                           /* Next driver */
288                NULL,                           /* Device list */
289                DRIVER_AMBAPP_GAISLER_GR1553B_ID,/* Driver ID */
290                "GR1553_DRV",                   /* Driver Name */
291                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
292                &gr1553_ops,
293                NULL,                           /* Funcs */
294                0,                              /* No devices yet */
295                0,
296        },
297        &gr1553_ids[0]
298};
299
300/* Multiple drivers may call this function. The drivers that depends on
301 * this driver:
302 *  - BM driver
303 *  - BC driver
304 *  - RT driver
305 */
306void gr1553_register(void)
307{
308        if ( gr1553_driver_registerd == 0 ) {
309                gr1553_driver_registerd = 1;
310                drvmgr_drv_register(&gr1553_drv_info.general);
311        }
312}
Note: See TracBrowser for help on using the repository browser.