source: rtems/c/src/lib/libbsp/sparc/shared/pci/gr_rasta_tmtc.c @ fc76056e

4.115
Last change on this file since fc76056e was fc76056e, checked in by Daniel Hellstrom <daniel@…>, on 12/20/13 at 13:01:12

GR-RASTA-TMTC: updated for new version

From this driver's point of view the major new thing is that the
GRPCI peripheral PCI bridge has been updated to GRPCI2, the second
version. This means that both Big and Little Endian systems are now
supported and autodetected on runtime.

The PCI frequency is used as AMBA frequency of the GR-RASTA-TMTC.

  • Property mode set to 100644
File size: 24.5 KB
Line 
1/*  GR-RASTA-TMTC PCI Target driver.
2 *
3 *  COPYRIGHT (c) 2008.
4 *  Cobham Gaisler AB.
5 *
6 *  Configures the GR-RASTA-TMTC interface PCI board.
7 *  This driver provides a AMBA PnP bus by using the general part
8 *  of the AMBA PnP bus driver (ambapp_bus.c).
9 *
10 *  Driver resources for the AMBA PnP bus provided can be set by overriding
11 *  the defaults by declaring gr_rasta_tmtc_resources[].
12 *
13 *  The license and distribution terms for this file may be
14 *  found in found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23
24#include <bsp.h>
25#include <rtems/bspIo.h>
26#include <pci.h>
27
28#include <ambapp.h>
29#include <grlib.h>
30#include <drvmgr/drvmgr.h>
31#include <drvmgr/ambapp_bus.h>
32#include <drvmgr/pci_bus.h>
33#include <genirq.h>
34
35#include <gr_rasta_tmtc.h>
36
37/* Determines which PCI address the AHB masters will access, it should be
38 * set so that the masters can access the CPU RAM. Default is base of CPU RAM,
39 * CPU RAM is mapped 1:1 to PCI space.
40 */
41extern unsigned int _RAM_START;
42#define AHBMST2PCIADR (((unsigned int)&_RAM_START) & 0xf0000000)
43
44#define GAISLER_GPIO         0x01a
45#define AHB1_BASE_ADDR 0x80000000
46#define AHB1_IOAREA_BASE_ADDR 0x80200000
47#define AHB1_IOAREA_OFS (AHB1_IOAREA_BASE_ADDR - AHB1_BASE_ADDR)
48
49/* Second revision constants (GRPCI2) */
50#define GRPCI2_BAR0_TO_AHB_MAP 0x04  /* Fixme */
51#define GRPCI2_BAR1_TO_AHB_MAP 0x08  /* Fixme */
52#define GRPCI2_PCI_CONFIG      0x20  /* Fixme */
53
54/* #define DEBUG 1 */
55
56#ifdef DEBUG
57#define DBG(x...) printk(x)
58#else
59#define DBG(x...)
60#endif
61
62int gr_rasta_tmtc_init1(struct drvmgr_dev *dev);
63int gr_rasta_tmtc_init2(struct drvmgr_dev *dev);
64
65struct grpci_regs {
66        volatile unsigned int cfg_stat;
67        volatile unsigned int bar0;
68        volatile unsigned int page0;
69        volatile unsigned int bar1;
70        volatile unsigned int page1;
71        volatile unsigned int iomap;
72        volatile unsigned int stat_cmd;
73};
74
75struct grpci2_regs {
76        volatile unsigned int ctrl;
77        volatile unsigned int statcap;
78        volatile unsigned int pcimstprefetch;
79        volatile unsigned int ahbtopciiomap;
80        volatile unsigned int dmactrl;
81        volatile unsigned int dmadesc;
82        volatile unsigned int dmachanact;
83        volatile unsigned int reserved;
84        volatile unsigned int pcibartoahb[6];
85        volatile unsigned int reserved2[2];
86        volatile unsigned int ahbtopcimemmap[16];
87        volatile unsigned int trcctrl;
88        volatile unsigned int trccntmode;
89        volatile unsigned int trcadpat;
90        volatile unsigned int trcadmask;
91        volatile unsigned int trcctrlsigpat;
92        volatile unsigned int trcctrlsigmask;
93        volatile unsigned int trcadstate;
94        volatile unsigned int trcctrlsigstate;
95};
96
97struct gr_rasta_tmtc_ver {
98        const unsigned int      amba_freq_hz;   /* The frequency */
99        const unsigned int      amba_ioarea;    /* The address where the PnP IOAREA starts at */
100};
101
102/* Private data structure for driver */
103struct gr_rasta_tmtc_priv {
104        /* Driver management */
105        struct drvmgr_dev       *dev;
106        char                            prefix[20];
107
108        /* PCI */
109        pci_dev_t                       pcidev;
110        struct pci_dev_info             *devinfo;
111        uint32_t                        ahbmst2pci_map;
112
113        /* IRQ */
114        genirq_t                        genirq;
115
116        /* GR-RASTA-TMTC */
117        struct gr_rasta_tmtc_ver        *version;
118        struct irqmp_regs               *irq;
119        struct grpci_regs               *grpci;
120        struct grpci2_regs              *grpci2;
121        struct grgpio_regs              *gpio;
122        struct drvmgr_map_entry         bus_maps_down[3];
123        struct drvmgr_map_entry         bus_maps_up[2];
124
125        /* AMBA Plug&Play information on GR-RASTA-TMTC */
126        struct ambapp_bus               abus;
127        struct ambapp_mmap              amba_maps[4];
128        struct ambapp_config            config;
129};
130
131struct gr_rasta_tmtc_ver gr_rasta_tmtc_ver0 = {
132        .amba_freq_hz           = 30000000,
133        .amba_ioarea            = AHB1_IOAREA_BASE_ADDR,
134};
135
136int ambapp_rasta_tmtc_int_register(
137        struct drvmgr_dev *dev,
138        int irq,
139        const char *info,
140        drvmgr_isr handler,
141        void *arg);
142int ambapp_rasta_tmtc_int_unregister(
143        struct drvmgr_dev *dev,
144        int irq,
145        drvmgr_isr handler,
146        void *arg);
147int ambapp_rasta_tmtc_int_unmask(
148        struct drvmgr_dev *dev,
149        int irq);
150int ambapp_rasta_tmtc_int_mask(
151        struct drvmgr_dev *dev,
152        int irq);
153int ambapp_rasta_tmtc_int_clear(
154        struct drvmgr_dev *dev,
155        int irq);
156int ambapp_rasta_tmtc_get_params(
157        struct drvmgr_dev *dev,
158        struct drvmgr_bus_params *params);
159
160struct ambapp_ops ambapp_rasta_tmtc_ops = {
161        .int_register = ambapp_rasta_tmtc_int_register,
162        .int_unregister = ambapp_rasta_tmtc_int_unregister,
163        .int_unmask = ambapp_rasta_tmtc_int_unmask,
164        .int_mask = ambapp_rasta_tmtc_int_mask,
165        .int_clear = ambapp_rasta_tmtc_int_clear,
166        .get_params = ambapp_rasta_tmtc_get_params
167};
168
169struct drvmgr_drv_ops gr_rasta_tmtc_ops =
170{
171        .init = {gr_rasta_tmtc_init1, gr_rasta_tmtc_init2, NULL, NULL},
172        .remove = NULL,
173        .info = NULL,
174};
175
176struct pci_dev_id_match gr_rasta_tmtc_ids[] =
177{
178        PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_RASTA_TMTC),
179        PCIID_END_TABLE /* Mark end of table */
180};
181
182struct pci_drv_info gr_rasta_tmtc_info =
183{
184        {
185                DRVMGR_OBJ_DRV,                 /* Driver */
186                NULL,                           /* Next driver */
187                NULL,                           /* Device list */
188                DRIVER_PCI_GAISLER_RASTATMTC_ID,/* Driver ID */
189                "GR-RASTA-TMTC_DRV",            /* Driver Name */
190                DRVMGR_BUS_TYPE_PCI,            /* Bus Type */
191                &gr_rasta_tmtc_ops,
192                NULL,                           /* Funcs */
193                0,                              /* No devices yet */
194                sizeof(struct gr_rasta_tmtc_priv) /* Let drvmgr alloc private */
195        },
196        &gr_rasta_tmtc_ids[0]
197};
198
199/* Driver resources configuration for the AMBA bus on the GR-RASTA-TMTC board.
200 * It is declared weak so that the user may override it from the project file,
201 * if the default settings are not enough.
202 *
203 * The configuration consists of an array of configuration pointers, each
204 * pointer determine the configuration of one GR-RASTA-TMTC board. Pointer
205 * zero is for board0, pointer 1 for board1 and so on.
206 *
207 * The array must end with a NULL pointer.
208 */
209struct drvmgr_bus_res *gr_rasta_tmtc_resources[] __attribute__((weak)) =
210{
211        NULL,
212};
213int gr_rasta_tmtc_resources_cnt = 0;
214
215void gr_rasta_tmtc_register_drv(void)
216{
217        DBG("Registering GR-RASTA-TMTC PCI driver\n");
218        drvmgr_drv_register(&gr_rasta_tmtc_info.general);
219}
220
221void gr_rasta_tmtc_isr (void *arg)
222{
223        struct gr_rasta_tmtc_priv *priv = arg;
224        unsigned int status, tmp;
225        int irq;
226        tmp = status = priv->irq->ipend;
227
228        /* printk("GR-RASTA-TMTC: IRQ 0x%x\n",status); */
229
230        for(irq=0; irq<32; irq++) {
231                if ( status & (1<<irq) ) {
232                        genirq_doirq(priv->genirq, irq);
233                        priv->irq->iclear = (1<<irq);
234                        status &= ~(1<<irq);
235                        if ( status == 0 )
236                                break;
237                }
238        }
239
240        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
241        if ( tmp )
242                drvmgr_interrupt_clear(priv->dev, 0);
243
244        DBG("RASTA-TMTC-IRQ: 0x%x\n", tmp);
245}
246
247/* PCI Hardware (Revision 0) initialization */
248int gr_rasta_tmtc_hw_init(struct gr_rasta_tmtc_priv *priv)
249{
250        unsigned int *page0 = NULL;
251        struct ambapp_dev *tmp;
252        struct ambapp_ahb_info *ahb;
253        unsigned int pci_freq_hz;
254        pci_dev_t pcidev = priv->pcidev;
255        struct pci_dev_info *devinfo = priv->devinfo;
256        uint32_t bar0, bar0_size;
257
258        /* Select version of GR-RASTA-TMTC board */
259        switch (devinfo->rev) {
260                case 0:
261                        priv->version = &gr_rasta_tmtc_ver0;
262                        break;
263                default:
264                        return -2;
265        }
266
267        bar0 = devinfo->resources[0].address;
268        bar0_size = devinfo->resources[0].size;
269        page0 = (unsigned int *)(bar0 + bar0_size/2);
270
271        /* Point PAGE0 to start of Plug and Play information */
272        *page0 = priv->version->amba_ioarea & 0xf0000000;
273
274#if 0
275        {
276                uint32_t data;
277                /* set parity error response */
278                pci_cfg_r32(pcidev, PCI_COMMAND, &data);
279                pci_cfg_w32(pcidev, PCI_COMMAND, (data|PCI_COMMAND_PARITY));
280        }
281#endif
282
283        /* Setup cache line size. Default cache line size will result in
284         * poor performance (256 word fetches), 0xff will set it according
285         * to the max size of the PCI FIFO.
286         */
287        pci_cfg_w8(pcidev, PCI_CACHE_LINE_SIZE, 0xff);
288
289        /* Scan AMBA Plug&Play */
290
291        /* AMBA MAP bar0 (in CPU) ==> 0x80000000(remote amba address) */
292        priv->amba_maps[0].size = 0x10000000;
293        priv->amba_maps[0].local_adr = bar0;
294        priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
295
296        /* AMBA MAP bar1 (in CPU) ==> 0x40000000(remote amba address) */
297        priv->amba_maps[1].size = devinfo->resources[1].size;
298        priv->amba_maps[1].local_adr = devinfo->resources[1].address;
299        priv->amba_maps[1].remote_adr = 0x40000000;
300
301        /* Addresses not matching with map be untouched */
302        priv->amba_maps[2].size = 0xfffffff0;
303        priv->amba_maps[2].local_adr = 0;
304        priv->amba_maps[2].remote_adr = 0;
305
306        /* Mark end of table */
307        priv->amba_maps[3].size=0;
308        priv->amba_maps[3].local_adr = 0;
309        priv->amba_maps[3].remote_adr = 0;
310
311        /* Start AMBA PnP scan at first AHB bus */
312        ambapp_scan(&priv->abus,
313                bar0 + (priv->version->amba_ioarea & ~0xf0000000),
314                NULL, &priv->amba_maps[0]);
315
316        /* Frequency is the same as the PCI bus frequency */
317        drvmgr_freq_get(priv->dev, 0, &pci_freq_hz);
318
319        /* Initialize Frequency of AMBA bus */
320        ambapp_freq_init(&priv->abus, NULL, pci_freq_hz);
321
322        /* Point PAGE0 to start of APB area */
323        *page0 = AHB1_BASE_ADDR;
324
325        /* Find GRPCI controller */
326        tmp = (void *)ambapp_for_each(&priv->abus,
327                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
328                                        VENDOR_GAISLER, GAISLER_PCIFBRG,
329                                        ambapp_find_by_idx, NULL);
330        if ( !tmp ) {
331                return -3;
332        }
333        priv->grpci = (struct grpci_regs *)((struct ambapp_apb_info *)tmp->devinfo)->start;
334
335        /* Set GRPCI mmap so that AMBA masters can access CPU-RAM over
336         * the PCI window.
337         */
338        priv->grpci->cfg_stat = (priv->grpci->cfg_stat & 0x0fffffff) |
339                                (priv->ahbmst2pci_map & 0xf0000000);
340        priv->grpci->page1 = 0x40000000;
341
342        /* Find IRQ controller, Clear all current IRQs */
343        tmp = (void *)ambapp_for_each(&priv->abus,
344                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
345                                        VENDOR_GAISLER, GAISLER_IRQMP,
346                                        ambapp_find_by_idx, NULL);
347        if ( !tmp ) {
348                return -4;
349        }
350        priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
351        /* Set up GR-RASTA-TMTC irq controller */
352        priv->irq->mask[0] = 0;
353        priv->irq->iclear = 0xffffffff;
354        priv->irq->ilevel = 0;
355
356        /* Find First GPIO controller */
357        tmp = (void *)ambapp_for_each(&priv->abus,
358                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
359                                        VENDOR_GAISLER, GAISLER_GPIO,
360                                        ambapp_find_by_idx, NULL);
361        if ( !tmp ) {
362                return -5;
363        }
364        priv->gpio = (struct grgpio_regs *) (((struct ambapp_apb_info *)tmp->devinfo)->start);
365        /* Clear GR-RASTA-TMTC GPIO controller */
366        priv->gpio->imask = 0;
367        priv->gpio->ipol = 0;
368        priv->gpio->iedge = 0;
369        priv->gpio->bypass = 0;
370        /* Set up GR-RASTA-TMTC GPIO controller to select GRTM and GRTC */
371        priv->gpio->output = (GR_TMTC_GPIO_GRTM_SEL|GR_TMTC_GPIO_TRANSP_CLK) | (GR_TMTC_GPIO_TC_BIT_LOCK|GR_TMTC_GPIO_TC_RF_AVAIL|GR_TMTC_GPIO_TC_ACTIVE_HIGH|GR_TMTC_GPIO_TC_RISING_CLK);
372        priv->gpio->dir = 0xffffffff;
373        DBG("GR-TMTC GPIO: 0x%x\n", (unsigned int)priv->gpio);
374
375        /* Enable DMA by enabling PCI target as master */
376        pci_master_enable(pcidev);
377
378        /* DOWN streams translation table */
379        priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
380        priv->bus_maps_down[0].size = priv->amba_maps[0].size;
381        priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
382        priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
383
384        priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
385        priv->bus_maps_down[1].size = priv->amba_maps[1].size;
386        priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
387        priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
388
389        /* Mark end of translation table */
390        priv->bus_maps_down[2].size = 0;
391
392        /* Find GRPCI controller AHB Slave interface */
393        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
394                                (OPTIONS_ALL|OPTIONS_AHB_SLVS),
395                                VENDOR_GAISLER, GAISLER_PCIFBRG,
396                                ambapp_find_by_idx, NULL);
397        if ( !tmp ) {
398                return -6;
399        }
400        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
401
402        /* UP streams translation table */
403        priv->bus_maps_up[0].name = "AMBA GRPCI Window";
404        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-TMTC board */
405        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
406        priv->bus_maps_up[0].to_adr = (void *)
407                                        (priv->ahbmst2pci_map & 0xf0000000);
408
409        /* Mark end of translation table */
410        priv->bus_maps_up[1].size = 0;
411
412        /* Successfully registered the RASTA board */
413        return 0;
414}
415
416/* PCI Hardware (Revision 1) initialization */
417int gr_rasta_tmtc1_hw_init(struct gr_rasta_tmtc_priv *priv)
418{
419        int i;
420        uint32_t data;
421        unsigned int ctrl;
422        uint8_t tmp2;
423        struct ambapp_dev *tmp;
424        int status;
425        struct ambapp_ahb_info *ahb;
426        uint8_t cap_ptr;
427        pci_dev_t pcidev = priv->pcidev;
428        struct pci_dev_info *devinfo = priv->devinfo;
429        unsigned int pci_freq_hz;
430
431        /* Check capabilities list bit */
432        pci_cfg_r8(pcidev, PCI_STATUS, &tmp2);
433
434        if (!((tmp2 >> 4) & 1)) {
435                /* Capabilities list not available which it should be in the
436                 * GRPCI2
437                 */
438                return -3;
439        }
440
441        /* Read capabilities pointer */
442        pci_cfg_r8(pcidev, PCI_CAP_PTR, &cap_ptr);
443
444        /* Set AHB address mappings for target PCI bars
445         * BAR0: 16MB  : Mapped to I/O at 0x80000000
446         * BAR1: 256MB : Mapped to MEM at 0x40000000
447         */
448        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, AHB1_BASE_ADDR);
449        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR1_TO_AHB_MAP, 0x40000000);
450
451        /* Set PCI bus to be same endianess as PCI system */
452        pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data);
453        if (pci_endian == PCI_BIG_ENDIAN)
454                data = data & 0xFFFFFFFE;
455        else
456                data = data | 0x00000001;
457        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data);
458
459#if 0
460        /* set parity error response */
461        pci_cfg_r32(pcidev, PCI_COMMAND, &data);
462        pci_cfg_w32(pcidev, PCI_COMMAND, (data|PCI_COMMAND_PARITY));
463#endif
464
465        /* Scan AMBA Plug&Play */
466
467        /* AMBA MAP bar0 (in PCI) ==> 0x40000000 (remote amba address) */
468        priv->amba_maps[0].size = devinfo->resources[0].size;
469        priv->amba_maps[0].local_adr = devinfo->resources[0].address;
470        priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
471
472        /* AMBA MAP bar0 (in PCI) ==> 0x80000000 (remote amba address) */
473        priv->amba_maps[1].size = devinfo->resources[1].size;
474        priv->amba_maps[1].local_adr = devinfo->resources[1].address;
475        priv->amba_maps[1].remote_adr = 0x40000000;
476
477        /* Addresses not matching with map be untouched */
478        priv->amba_maps[2].size = 0xfffffff0;
479        priv->amba_maps[2].local_adr = 0;
480        priv->amba_maps[2].remote_adr = 0;
481
482        /* Mark end of table */
483        priv->amba_maps[3].size=0;
484
485        /* Start AMBA PnP scan at first AHB bus */
486        ambapp_scan(
487                &priv->abus,
488                devinfo->resources[0].address + AHB1_IOAREA_OFS,
489                NULL,
490                &priv->amba_maps[0]);
491
492        /* Initialize Frequency of AMBA bus. The AMBA bus runs at same
493         * frequency as PCI bus
494         */
495        drvmgr_freq_get(priv->dev, 0, &pci_freq_hz);
496        ambapp_freq_init(&priv->abus, NULL, pci_freq_hz);
497
498        /* Find IRQ controller, Clear all current IRQs */
499        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
500                                (OPTIONS_ALL|OPTIONS_APB_SLVS),
501                                VENDOR_GAISLER, GAISLER_IRQMP,
502                                ambapp_find_by_idx, NULL);
503        if ( !tmp ) {
504                return -4;
505        }
506        priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
507        /* Set up GR-RASTA-SPW-ROUTER irq controller */
508        priv->irq->mask[0] = 0;
509        priv->irq->iclear = 0xffff;
510        priv->irq->ilevel = 0;
511
512        priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
513        priv->bus_maps_down[0].size = priv->amba_maps[0].size;
514        priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
515        priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
516        priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
517        priv->bus_maps_down[1].size = priv->amba_maps[1].size;
518        priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
519        priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
520        priv->bus_maps_down[2].size = 0;
521
522        /* Find GRPCI2 controller AHB Slave interface */
523        tmp = (void *)ambapp_for_each(&priv->abus,
524                                        (OPTIONS_ALL|OPTIONS_AHB_SLVS),
525                                        VENDOR_GAISLER, GAISLER_GRPCI2,
526                                        ambapp_find_by_idx, NULL);
527        if ( !tmp ) {
528                return -5;
529        }
530        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
531        priv->bus_maps_up[0].name = "AMBA GRPCI2 Window";
532        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-SPW-ROUTER board */
533        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
534        priv->bus_maps_up[0].to_adr = (void *)
535                                (priv->ahbmst2pci_map & ~(ahb->mask[0]-1));
536        priv->bus_maps_up[1].size = 0;
537
538        /* Find GRPCI2 controller APB Slave interface */
539        tmp = (void *)ambapp_for_each(&priv->abus,
540                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
541                                        VENDOR_GAISLER, GAISLER_GRPCI2,
542                                        ambapp_find_by_idx, NULL);
543        if ( !tmp ) {
544                return -6;
545        }
546        priv->grpci2 = (struct grpci2_regs *)
547                ((struct ambapp_apb_info *)tmp->devinfo)->start;
548
549        /* Set AHB to PCI mapping for all AMBA AHB masters */
550        for(i = 0; i < 16; i++) {
551                priv->grpci2->ahbtopcimemmap[i] = priv->ahbmst2pci_map &
552                                                        ~(ahb->mask[0]-1);
553        }
554
555        /* Make sure dirq(0) sampling is enabled */
556        ctrl = priv->grpci2->ctrl;
557        ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4);
558        priv->grpci2->ctrl = ctrl;
559
560        /* Successfully registered the RASTA-SPW-ROUTER board */
561        return 0;
562}
563
564void gr_rasta_tmtc_hw_init2(struct gr_rasta_tmtc_priv *priv)
565{
566        /* Enable DMA by enabling PCI target as master */
567        pci_master_enable(priv->pcidev);
568}
569
570/* Called when a PCI target is found with the PCI device and vendor ID
571 * given in gr_rasta_tmtc_ids[].
572 */
573int gr_rasta_tmtc_init1(struct drvmgr_dev *dev)
574{
575        struct gr_rasta_tmtc_priv *priv;
576        struct pci_dev_info *devinfo;
577        int status;
578        uint32_t bar0, bar1, bar0_size, bar1_size;
579        union drvmgr_key_value *value;
580
581        priv = dev->priv;
582        if (!priv)
583                return DRVMGR_NOMEM;
584        priv->dev = dev;
585
586        /* Determine number of configurations */
587        if ( gr_rasta_tmtc_resources_cnt == 0 ) {
588                while ( gr_rasta_tmtc_resources[gr_rasta_tmtc_resources_cnt] )
589                        gr_rasta_tmtc_resources_cnt++;
590        }
591
592        /* Generate Device prefix */
593
594        strcpy(priv->prefix, "/dev/rastatmtc0");
595        priv->prefix[14] += dev->minor_drv;
596        mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
597        priv->prefix[15] = '/';
598        priv->prefix[16] = '\0';
599
600        priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
601        priv->pcidev = devinfo->pcidev;
602        bar0 = devinfo->resources[0].address;
603        bar0_size = devinfo->resources[0].size;
604        bar1 = devinfo->resources[1].address;
605        bar1_size = devinfo->resources[1].size;
606        printf("\n\n--- GR-RASTA-TMTC[%d] ---\n", dev->minor_drv);
607        printf(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
608                PCI_DEV_EXPAND(priv->pcidev));
609        printf(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
610                devinfo->id.vendor, devinfo->id.device);
611        printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
612        printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
613        printf(" IRQ: %d\n\n\n", devinfo->irq);
614
615        /* all neccessary space assigned to GR-RASTA-IO target? */
616        if ((bar0_size == 0) || (bar1_size == 0))
617                return DRVMGR_ENORES;
618
619        /* Let user override which PCI address the AHB masters of the
620         * GR-RASTA-TMTC board access when doing DMA to CPU RAM. The AHB masters
621         * access the PCI Window of the AMBA bus, the MSB 4-bits of that address
622         * is translated according this config option before the address
623         * goes out on the PCI bus.
624         * Only the 4 MSB bits have an effect;
625         */
626        value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", KEY_TYPE_INT);
627        if (value)
628                priv->ahbmst2pci_map = value->i;
629        else
630                priv->ahbmst2pci_map = AHBMST2PCIADR; /* default */     
631
632        priv->genirq = genirq_init(32);
633        if ( priv->genirq == NULL )
634                return DRVMGR_FAIL;
635
636        /* Select version of GR-RASTA-IO board */
637        switch (devinfo->rev) {
638                case 0:
639                        puts("GR-RASTA-TMTC: REVISION 0");
640                        status = gr_rasta_tmtc_hw_init(priv);
641                        break;
642                case 1:
643                        puts("GR-RASTA-TMTC: REVISION 1");
644                        status = gr_rasta_tmtc1_hw_init(priv);
645                        break;
646                default:
647                        return DRVMGR_ENOSYS; /* HW not supported */
648        }
649
650        if ( status != 0 ) {
651                genirq_destroy(priv->genirq);
652                printf(" Failed to initialize GR-RASTA-TMTC HW: %d\n", status);
653                return DRVMGR_FAIL;
654        }
655
656        /* Init amba bus */
657        priv->config.abus = &priv->abus;
658        priv->config.ops = &ambapp_rasta_tmtc_ops;
659        priv->config.maps_up = &priv->bus_maps_up[0];
660        priv->config.maps_down = &priv->bus_maps_down[0];
661        if ( priv->dev->minor_drv < gr_rasta_tmtc_resources_cnt ) {
662                priv->config.resources = gr_rasta_tmtc_resources[priv->dev->minor_drv];
663        } else {
664                priv->config.resources = NULL;
665        }
666
667        return ambapp_bus_register(dev, &priv->config);
668}
669
670int gr_rasta_tmtc_init2(struct drvmgr_dev *dev)
671{
672        struct gr_rasta_tmtc_priv *priv = dev->priv;
673
674        /* Clear any old interrupt requests */
675        drvmgr_interrupt_clear(priv->dev, 0);
676
677        /* Enable System IRQ so that GR-RASTA-TMTC PCI target interrupt goes
678         * through.
679         *
680         * It is important to enable it in stage init2. If interrupts were
681         * enabled in init1 this might hang the system when more than one
682         * PCI target is connected, this is because PCI interrupts might
683         * be shared and PCI board 2 have not initialized and
684         * might therefore drive interrupt already when entering init1().
685         */
686        drvmgr_interrupt_register(
687                priv->dev,
688                0,
689                "gr_rasta_tmtc",
690                gr_rasta_tmtc_isr,
691                (void *)priv);
692
693        gr_rasta_tmtc_hw_init2(priv);
694
695        return DRVMGR_OK;
696}
697
698int ambapp_rasta_tmtc_int_register(
699        struct drvmgr_dev *dev,
700        int irq,
701        const char *info,
702        drvmgr_isr handler,
703        void *arg)
704{
705        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
706        rtems_interrupt_level level;
707        int status;
708
709        rtems_interrupt_disable(level);
710
711        status = genirq_register(priv->genirq, irq, handler, arg);
712        if ( status == 0 ) {
713                /* Disable and clear IRQ for first registered handler */
714                priv->irq->iclear = (1<<irq);
715        } else if ( status == 1 )
716                status = 0;
717
718        if (status != 0) {
719                rtems_interrupt_enable(level);
720                return DRVMGR_FAIL;
721        }
722
723        status = genirq_enable(priv->genirq, irq, handler, arg);
724        if ( status == 0 ) {
725                /* Enable IRQ for first enabled handler only */
726                priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
727        } else if ( status == 1 )
728                status = 0;
729
730        rtems_interrupt_enable(level);
731
732        return status;
733}
734
735int ambapp_rasta_tmtc_int_unregister(
736        struct drvmgr_dev *dev,
737        int irq,
738        drvmgr_isr isr,
739        void *arg)
740{
741        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
742        rtems_interrupt_level level;
743        int status;
744
745        rtems_interrupt_disable(level);
746
747        status = genirq_disable(priv->genirq, irq, isr, arg);
748        if ( status == 0 ) {
749                /* Disable IRQ only when no enabled handler exists */
750                priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
751        } else if ( status == 1 )
752                status = 0;
753
754        status = genirq_unregister(priv->genirq, irq, isr, arg);
755        if ( status != 0 )
756                status = DRVMGR_FAIL;
757
758        rtems_interrupt_enable(level);
759
760        return status;
761}
762
763int ambapp_rasta_tmtc_int_unmask(
764        struct drvmgr_dev *dev,
765        int irq)
766{
767        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
768        rtems_interrupt_level level;
769
770        DBG("RASTA-TMTC IRQ %d: unmask\n", irq);
771
772        if ( genirq_check(priv->genirq, irq) )
773                return DRVMGR_EINVAL;
774
775        rtems_interrupt_disable(level);
776
777        /* Enable IRQ */
778        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
779
780        rtems_interrupt_enable(level);
781
782        return DRVMGR_OK;
783}
784
785int ambapp_rasta_tmtc_int_mask(
786        struct drvmgr_dev *dev,
787        int irq)
788{
789        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
790        rtems_interrupt_level level;
791
792        DBG("RASTA-TMTC IRQ %d: mask\n", irq);
793
794        if ( genirq_check(priv->genirq, irq) )
795                return DRVMGR_EINVAL;
796
797        rtems_interrupt_disable(level);
798
799        /* Disable IRQ */
800        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
801
802        rtems_interrupt_enable(level);
803
804        return DRVMGR_OK;
805}
806
807int ambapp_rasta_tmtc_int_clear(
808        struct drvmgr_dev *dev,
809        int irq)
810{
811        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
812
813        if ( genirq_check(priv->genirq, irq) )
814                return DRVMGR_FAIL;
815
816        priv->irq->iclear = (1<<irq);
817
818        return DRVMGR_OK;
819}
820
821int ambapp_rasta_tmtc_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
822{
823        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
824
825        /* Device name prefix pointer, skip /dev */
826        params->dev_prefix = &priv->prefix[5];
827
828        return 0;
829}
830
831void gr_rasta_tmtc_print_dev(struct drvmgr_dev *dev, int options)
832{
833        struct gr_rasta_tmtc_priv *priv = dev->priv;
834        struct pci_dev_info *devinfo = priv->devinfo;
835        uint32_t bar0, bar1, bar0_size, bar1_size;
836
837        /* Print */
838        printf("--- GR-RASTA-TMTC [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
839                PCI_DEV_EXPAND(priv->pcidev));
840
841        bar0 = devinfo->resources[0].address;
842        bar0_size = devinfo->resources[0].size;
843        bar1 = devinfo->resources[1].address;
844        bar1_size = devinfo->resources[1].size;
845
846        printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
847        printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
848        printf(" IRQ:             %d\n", devinfo->irq);
849        printf(" PCI REVISION:    %d\n", devinfo->rev);
850        printf(" FREQ:            %d Hz\n", priv->version->amba_freq_hz);
851        printf(" IMASK:           0x%08x\n", priv->irq->mask[0]);
852        printf(" IPEND:           0x%08x\n", priv->irq->ipend);
853
854        /* Print amba config */
855        if ( options & RASTA_TMTC_OPTIONS_AMBA ) {
856                ambapp_print(&priv->abus, 10);
857        }
858
859#if 0
860        /* Print IRQ handlers and their arguments */
861        if ( options & RASTA_TMTC_OPTIONS_IRQ ) {
862                int i;
863                for(i=0; i<16; i++) {
864                        printf(" IRQ[%02d]:         0x%x, arg: 0x%x\n",
865                                i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
866                }
867        }
868#endif
869}
870
871void gr_rasta_tmtc_print(int options)
872{
873        struct pci_drv_info *drv = &gr_rasta_tmtc_info;
874        struct drvmgr_dev *dev;
875
876        dev = drv->general.dev;
877        while(dev) {
878                gr_rasta_tmtc_print_dev(dev, options);
879                dev = dev->next_in_drv;
880        }
881}
Note: See TracBrowser for help on using the repository browser.