source: rtems/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_leon2.c @ 3e3fb0d

4.11
Last change on this file since 3e3fb0d was 3e3fb0d, checked in by Daniel Hellstrom <daniel@…>, on Dec 20, 2011 at 11:28:32 AM

LEON2: added support for LEON2-GRLIB systems

In some non-standard designs GRLIB peripherals are used together
LEON2. This patch adds a GRLIB amba Plug&Play driver so that AMBA
devices can be found from Plug&Play the same way as with the LEON3
BSP.

The user is required to add an AMBA-PnP device entry into the LEON2
bus configuration, so that the driver manager unite this driver
with the "fake" device and start scanning after AMBA PnP devices.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*  LEON2 GRLIB AMBA Plug & Play bus driver.
2 *
3 *  COPYRIGHT (c) 2008.
4 *  Cobham Gaisler AB.
5 *
6 *  This is driver is a wrapper for the general AMBA Plug & Play bus
7 *  driver. This is a bus driver for LEON2-GRLIB systems providing a
8 *  AMBA Plug & Play bus, the parent bus must be a LEON2 hardcoded
9 *  Bus. All IRQs must be routed to this bus driver in order for IRQs
10 *  to work. The PnP information is used to extract IRQs and base
11 *  register addresses.
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 */
17
18#include <bsp.h>
19
20#ifdef LEON2
21#include <stdlib.h>
22#include <stdio.h>
23#include <libcpu/access.h>
24#include <drvmgr/drvmgr.h>
25#include <drvmgr/ambapp_bus.h>
26#include <drvmgr/leon2_amba_bus.h>
27
28#define DBG(args...)
29
30int ambapp_leon2_int_register(
31        struct drvmgr_dev *dev,
32        int index,
33        const char *info,
34        drvmgr_isr isr,
35        void *arg);
36int ambapp_leon2_int_unregister(
37        struct drvmgr_dev *dev,
38        int index,
39        drvmgr_isr isr,
40        void *arg);
41int ambapp_leon2_int_clear(
42        struct drvmgr_dev *dev,
43        int index);
44int ambapp_leon2_int_mask(
45        struct drvmgr_dev *dev,
46        int irq);
47int ambapp_leon2_int_unmask(
48        struct drvmgr_dev *dev,
49        int irq);
50int ambapp_leon2_get_params(
51        struct drvmgr_dev *dev,
52        struct drvmgr_bus_params *params);
53
54int ambapp_leon2_init1(struct drvmgr_dev *dev);
55int ambapp_leon2_init2(struct drvmgr_dev *dev);
56int ambapp_leon2_remove(struct drvmgr_dev *dev);
57void ambapp_leon2_register(void);
58
59/* READ/WRITE access to SpaceWire target over RMAP */
60void *ambapp_leon2_rw_arg(struct drvmgr_dev *dev);
61
62struct ambappl2_priv {
63        struct ambapp_bus abus;
64        struct ambapp_config config;
65};
66
67struct ambapp_ops ambapp_leon2_ops = {
68        .int_register = ambapp_leon2_int_register,
69        .int_unregister = ambapp_leon2_int_unregister,
70        .int_clear = ambapp_leon2_int_clear,
71        .int_mask = ambapp_leon2_int_mask,
72        .int_unmask = ambapp_leon2_int_unmask,
73        .get_params = ambapp_leon2_get_params
74};
75
76struct drvmgr_func ambapp_leon2_funcs[] = {
77        DRVMGR_FUNC(AMBAPP_RW_ARG, ambapp_leon2_rw_arg),
78
79        DRVMGR_FUNC(AMBAPP_R8,  _ld8),
80        DRVMGR_FUNC(AMBAPP_R16, _ld16),
81        DRVMGR_FUNC(AMBAPP_R32, _ld32),
82        DRVMGR_FUNC(AMBAPP_R64, _ld64),
83
84        DRVMGR_FUNC(AMBAPP_W8,  _st8),
85        DRVMGR_FUNC(AMBAPP_W16, _st16),
86        DRVMGR_FUNC(AMBAPP_W32, _st32),
87        DRVMGR_FUNC(AMBAPP_W64, _st64),
88
89        DRVMGR_FUNC(AMBAPP_RMEM, memcpy),
90        DRVMGR_FUNC(AMBAPP_WMEM, memcpy),
91
92        DRVMGR_FUNC_END
93};
94
95struct drvmgr_drv_ops ambapp_ops = {
96        .init = {ambapp_leon2_init1, ambapp_leon2_init2, NULL, NULL},
97        .remove = ambapp_leon2_remove,
98        .info = NULL,
99};
100
101struct leon2_amba_dev_id ambapp_leon2_ids[] = {
102        {LEON2_AMBA_AMBAPP_ID},
103        {0}
104};
105
106struct leon2_amba_drv_info ambapp_bus_drv_leon2 = {
107        {
108                DRVMGR_OBJ_DRV,                 /* Driver */
109                NULL,                           /* Next driver */
110                NULL,                           /* Device list */
111                DRIVER_LEON2_AMBA_AMBAPP,       /* Driver ID */
112                "AMBAPP_LEON2_DRV",             /* Driver Name */
113                DRVMGR_BUS_TYPE_LEON2_AMBA,     /* Bus Type */
114                &ambapp_ops,
115                NULL,                           /* Funcs */
116                0,
117                sizeof(struct ambappl2_priv),   /* Let DrvMgr allocate priv */
118        },
119        &ambapp_leon2_ids[0]
120};
121
122void ambapp_leon2_register(void)
123{
124        drvmgr_drv_register(&ambapp_bus_drv_leon2.general);
125}
126
127/* Function called from a hard configuration */
128int ambapp_leon2_init1(struct drvmgr_dev *dev)
129{
130        union drvmgr_key_value *value;
131        struct ambappl2_priv *priv = dev->priv;
132        struct leon2_amba_dev_info *devinfo;
133        struct ambapp_config *config;
134        unsigned int ioarea;
135        unsigned int freq_hz;
136        LEON_Register_Map *regs;
137
138        dev->name = "LEON2 AMBA PnP";
139
140        if (!priv)
141                return DRVMGR_NOMEM;
142
143        config = &priv->config;
144        config->abus = &priv->abus;
145        config->ops = &ambapp_leon2_ops;
146        config->maps_up = DRVMGR_TRANSLATE_ONE2ONE;
147        config->maps_down = DRVMGR_TRANSLATE_ONE2ONE;
148        config->funcs = ambapp_leon2_funcs;
149        config->bus_type = DRVMGR_BUS_TYPE_LEON2_AMBA;
150
151        /* Get AMBA PnP Area from REG0 */
152        devinfo = (struct leon2_amba_dev_info *)dev->businfo;
153        ioarea = devinfo->reg_base;
154
155        /* Scan AMBA PnP Bus. ABUS has already been cleared with memset() */
156        ambapp_scan(&priv->abus, ioarea, NULL, NULL);
157
158        /* Try to get Configuration from resource configuration */
159
160        value = drvmgr_dev_key_get(dev, "busFreq", KEY_TYPE_INT);
161        if (value) {
162                /* Set frequency of AMBA bus if specified by user. The frequency
163                 * must be for AHB bus which IOAREA matches (AHB bus 0).
164                 */
165                freq_hz = value->i;
166        } else {
167                /* Get Bus/LEON2 Frequency from timer prescaler,
168                 * the hardcoded address is used to get to timer
169                 */
170                regs = (LEON_Register_Map *) 0x80000000;
171                freq_hz = (regs->Scaler_Reload + 1) * 1000 * 1000;
172        }
173        /* Note that this can be overrided by a driver on the AMBA PnP bus.*/
174        ambapp_freq_init(&priv->abus, NULL, freq_hz);
175
176        value = drvmgr_dev_key_get(dev, "drvRes", KEY_TYPE_POINTER);
177        if (!value) {
178                DBG("ambapp_leon2_init1: Failed getting resource drvRes\n");
179                config->resources = NULL;
180        } else {
181                DBG("ambapp_leon2_init1: drvRes: 0x%08x\n", (unsigned int)value->ptr);
182                config->resources = (struct drvmgr_bus_res *)value->ptr;
183        }
184
185        /* Initialize the AMBA Bus */
186        return ambapp_bus_register(dev, config);
187}
188
189int ambapp_leon2_init2(struct drvmgr_dev *dev)
190{
191        return 0;
192}
193
194int ambapp_leon2_remove(struct drvmgr_dev *dev)
195{
196        return 0;
197}
198
199void *ambapp_leon2_rw_arg(struct drvmgr_dev *dev)
200{
201        return dev; /* No argument really needed, by for debug */
202}
203
204int ambapp_leon2_int_register
205        (
206        struct drvmgr_dev *dev,
207        int index,
208        const char *info,
209        drvmgr_isr isr,
210        void *arg
211        )
212{
213        /* Let LEON2 bus handle interrupt requests */
214        return drvmgr_interrupt_register(dev->parent->dev, index, info, isr, arg);
215}
216
217int ambapp_leon2_int_unregister
218        (
219        struct drvmgr_dev *dev,
220        int index,
221        drvmgr_isr isr,
222        void *arg
223        )
224{
225        /* Let LEON2 bus handle interrupt requests */
226        return drvmgr_interrupt_unregister(dev->parent->dev, index, isr, arg);
227}
228
229int ambapp_leon2_int_clear
230        (
231        struct drvmgr_dev *dev,
232        int index
233        )
234{
235        /* Let LEON2 bus handle interrupt requests */
236        return drvmgr_interrupt_clear(dev->parent->dev, index);
237}
238
239int ambapp_leon2_int_mask
240        (
241        struct drvmgr_dev *dev,
242        int index
243        )
244{
245        /* Let LEON2 bus handle interrupt requests */
246        return drvmgr_interrupt_mask(dev->parent->dev, index);
247}
248
249int ambapp_leon2_int_unmask
250        (
251        struct drvmgr_dev *dev,
252        int index
253        )
254{
255        /* Let LEON2 bus handle interrupt requests */
256        return drvmgr_interrupt_unmask(dev->parent->dev, index);
257}
258
259int ambapp_leon2_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
260{
261        params->dev_prefix = "";
262        return 0;
263}
264
265#endif
Note: See TracBrowser for help on using the repository browser.