source: rtems/bsps/shared/grlib/1553/gr1553b.c

Last change on this file was 5d5b9ee, checked in by Daniel Cederman <cederman@…>, on 11/14/22 at 09:59:08

bsps/shared/grlib: Change license to BSD-2 for files with Gaisler copyright

This patch changes the license to BSD-2 for all source files where the
copyright is held by Aeroflex Gaisler, Cobham Gaisler, or Gaisler Research.
Some files also includes copyright right statements from OAR and/or
embedded Brains in addition to Gaisler.

Updates #3053.

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*  GR1553B driver, used by BC, RT and/or BM driver
4 *
5 *  COPYRIGHT (c) 2010.
6 *  Cobham Gaisler AB.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <stdlib.h>
31#include <grlib/ambapp_bus.h>
32
33#include <grlib/gr1553b.h>
34
35#include <grlib/grlib_impl.h>
36
37/* Driver Manager interface for BC, RT, BM, BRM, BC-BM and RT-BM */
38
39#define GR1553B_WRITE_REG(adr, val) *(volatile uint32_t *)(adr) = (val)
40#define GR1553B_READ_REG(adr) (*(volatile uint32_t *)(adr))
41
42#define FEAT_BC 0x1
43#define FEAT_RT 0x2
44#define FEAT_BM 0x4
45
46#define ALLOC_BC 0x1
47#define ALLOC_RT 0x2
48#define ALLOC_BM 0x4
49
50struct gr1553_device {
51        struct drvmgr_dev *dev;
52        int features;
53        int alloc;
54};
55
56struct gr1553_device_feature {
57        struct gr1553_device_feature *next;
58        struct gr1553_device *dev;
59        int minor;
60};
61
62/* Device lists */
63static struct gr1553_device_feature *gr1553_bm_root = NULL;
64static struct gr1553_device_feature *gr1553_rt_root = NULL;
65static struct gr1553_device_feature *gr1553_bc_root = NULL;
66
67/* Driver registered */
68static int gr1553_driver_registerd = 0;
69
70/* Add 'feat' to linked list pointed to by 'root'. A minor is also assigned. */
71static void gr1553_list_add
72        (
73        struct gr1553_device_feature **root,
74        struct gr1553_device_feature *feat
75        )
76{
77        int minor;
78        struct gr1553_device_feature *curr;
79
80        if ( *root == NULL ) {
81                *root = feat;
82                feat->next = NULL;
83                feat->minor = 0;
84                return;
85        }
86
87        minor = 0;
88retry_new_minor:
89        curr = *root;
90        while ( curr->next ) {
91                if ( curr->minor == minor ) {
92                        minor++;
93                        goto retry_new_minor;
94                }
95                curr = curr->next;
96        }
97
98        feat->next = NULL;
99        feat->minor = minor;
100        curr->next = feat;
101}
102
103static struct gr1553_device_feature *gr1553_list_find
104        (
105        struct gr1553_device_feature *root,
106        int minor
107        )
108{
109        struct gr1553_device_feature *curr = root;
110        while ( curr ) {
111                if ( curr->minor == minor ) {
112                        return curr;
113                }
114                curr = curr->next;
115        }
116        return NULL;
117}
118
119struct drvmgr_dev **gr1553_bc_open(int minor)
120{
121        struct gr1553_device_feature *feat;
122       
123        feat = gr1553_list_find(gr1553_bc_root, minor);
124        if ( feat == NULL )
125                return NULL;
126
127        /* Only possible to allocate is RT and BC is free,
128         * this is beacuse it is not possible to use the
129         * RT and the BC at the same time.
130         */
131        if ( feat->dev->alloc & (ALLOC_BC|ALLOC_RT) )
132                return NULL;
133
134        /* Alloc BC device */
135        feat->dev->alloc |= ALLOC_BC;
136
137        return &feat->dev->dev;
138}
139
140void gr1553_bc_close(struct drvmgr_dev **dev)
141{
142        struct gr1553_device *d = (struct gr1553_device *)dev;
143
144        d->alloc &= ~ALLOC_BC;
145}
146
147struct drvmgr_dev **gr1553_rt_open(int minor)
148{
149        struct gr1553_device_feature *feat;
150
151        feat = gr1553_list_find(gr1553_rt_root, minor);
152        if ( feat == NULL )
153                return NULL;
154
155        /* Only possible to allocate is RT and BC is free,
156         * this is beacuse it is not possible to use the
157         * RT and the BC at the same time.
158         */
159        if ( feat->dev->alloc & (ALLOC_BC|ALLOC_RT) )
160                return NULL;
161
162        /* Alloc RT device */
163        feat->dev->alloc |= ALLOC_RT;
164
165        return &feat->dev->dev;
166}
167
168void gr1553_rt_close(struct drvmgr_dev **dev)
169{
170        struct gr1553_device *d = (struct gr1553_device *)dev;
171
172        d->alloc &= ~ALLOC_RT;
173}
174
175struct drvmgr_dev **gr1553_bm_open(int minor)
176{
177        struct gr1553_device_feature *feat;
178       
179        feat = gr1553_list_find(gr1553_bm_root, minor);
180        if ( feat == NULL )
181                return NULL;
182
183        /* Only possible to allocate is RT and BC is free,
184         * this is beacuse it is not possible to use the
185         * RT and the BC at the same time.
186         */
187        if ( feat->dev->alloc & ALLOC_BM )
188                return NULL;
189
190        /* Alloc BM device */
191        feat->dev->alloc |= ALLOC_BM;
192
193        return &feat->dev->dev;
194}
195
196void gr1553_bm_close(struct drvmgr_dev **dev)
197{
198        struct gr1553_device *d = (struct gr1553_device *)dev;
199
200        d->alloc &= ~ALLOC_BM;
201}
202
203static int gr1553_init2(struct drvmgr_dev *dev)
204{
205        struct amba_dev_info *ambadev;
206        struct ambapp_core *pnpinfo;
207        struct gr1553b_regs *regs;
208
209        /* Get device information from AMBA PnP information */
210        ambadev = (struct amba_dev_info *)dev->businfo;
211        if ( ambadev == NULL ) {
212                return DRVMGR_FAIL;
213        }
214        pnpinfo = &ambadev->info;
215        if ( pnpinfo->apb_slv == NULL )
216                return DRVMGR_EIO;
217        regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
218
219        /* Stop IRQ */
220        GR1553B_WRITE_REG(&regs->imask, 0);
221        GR1553B_WRITE_REG(&regs->irq, 0xffffffff);
222        /* Stop BC if not already stopped (just in case) */
223        GR1553B_WRITE_REG(&regs->bc_ctrl, 0x15520204);
224        /* Stop RT rx (just in case) */
225        GR1553B_WRITE_REG(&regs->rt_cfg, 0x15530000);
226        /* Stop BM logging (just in case) */
227        GR1553B_WRITE_REG(&regs->bm_ctrl, 0);
228        /* Set codec version. This is only supported by some devices, i.e. GR740.
229         * It will not have any effect on devices that does not support this bit.
230         */
231        GR1553B_WRITE_REG(&regs->hwcfg, 1<<12);
232
233        return DRVMGR_OK;
234}
235
236/* Register the different functionalities that the
237 * core supports.
238 */
239static int gr1553_init3(struct drvmgr_dev *dev)
240{
241        struct amba_dev_info *ambadev;
242        struct ambapp_core *pnpinfo;
243        struct gr1553_device *priv;
244        struct gr1553_device_feature *feat;
245        struct gr1553b_regs *regs;
246
247        priv = grlib_malloc(sizeof(*priv));
248        if ( priv == NULL )
249                return DRVMGR_NOMEM;
250        priv->dev = dev;
251        priv->alloc = 0;
252        priv->features = 0;
253        dev->priv = NULL; /* Let higher level driver handle this */
254
255        /* Get device information from AMBA PnP information */
256        ambadev = (struct amba_dev_info *)dev->businfo;
257        pnpinfo = &ambadev->info;
258        regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
259
260        if ( GR1553B_READ_REG(&regs->bm_stat) & GR1553B_BM_STAT_BMSUP ) {
261                priv->features |= FEAT_BM;
262                feat = grlib_malloc(sizeof(*feat));
263                feat->dev = priv;
264                /* Init Minor and Next */
265                gr1553_list_add(&gr1553_bm_root, feat);
266        }
267
268        if ( GR1553B_READ_REG(&regs->bc_stat) & GR1553B_BC_STAT_BCSUP ) {
269                priv->features |= FEAT_BC;
270                feat = grlib_malloc(sizeof(*feat));
271                feat->dev = priv;
272                /* Init Minor and Next */
273                gr1553_list_add(&gr1553_bc_root, feat);
274        }
275
276        if ( GR1553B_READ_REG(&regs->rt_stat) & GR1553B_RT_STAT_RTSUP ) {
277                priv->features |= FEAT_RT;
278                feat = grlib_malloc(sizeof(*feat));
279                feat->dev = priv;
280                /* Init Minor and Next */
281                gr1553_list_add(&gr1553_rt_root, feat);
282        }
283
284        if ( priv->features == 0 ) {
285                /* no features in HW should never happen.. an I/O error? */
286                free(priv);
287                return DRVMGR_EIO;
288        }
289
290        return DRVMGR_OK;
291}
292
293struct drvmgr_drv_ops gr1553_ops =
294{
295        {NULL, gr1553_init2, gr1553_init3, NULL},
296        NULL,
297        NULL
298};
299
300struct amba_dev_id gr1553_ids[] =
301{
302        {VENDOR_GAISLER, GAISLER_GR1553B},
303        {0, 0}  /* Mark end of table */
304};
305
306struct amba_drv_info gr1553_drv_info =
307{
308        {
309                DRVMGR_OBJ_DRV,                 /* Driver */
310                NULL,                           /* Next driver */
311                NULL,                           /* Device list */
312                DRIVER_AMBAPP_GAISLER_GR1553B_ID,/* Driver ID */
313                "GR1553_DRV",                   /* Driver Name */
314                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
315                &gr1553_ops,
316                NULL,                           /* Funcs */
317                0,                              /* No devices yet */
318                0,
319        },
320        &gr1553_ids[0]
321};
322
323/* Multiple drivers may call this function. The drivers that depends on
324 * this driver:
325 *  - BM driver
326 *  - BC driver
327 *  - RT driver
328 */
329void gr1553_register(void)
330{
331        if ( gr1553_driver_registerd == 0 ) {
332                gr1553_driver_registerd = 1;
333                drvmgr_drv_register(&gr1553_drv_info.general);
334        }
335}
Note: See TracBrowser for help on using the repository browser.