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

4.115
Last change on this file since 5823bae8 was 5823bae8, checked in by Daniel Hellstrom <daniel@…>, on 02/27/15 at 13:03:15

LEON: move driver headers to bsp/ directory

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