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

4.115
Last change on this file since e8f6005f was e8f6005f, checked in by Daniel Hellstrom <daniel@…>, on 08/08/14 at 08:01:41

GR-RASTA-TMTC,rev1: add GRGPIO[0] register init

  • Property mode set to 100644
File size: 23.7 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/* Init AMBA bus frequency, IRQ controller, GPIO register, bus maps and other
248 * common stuff between rev0 and rev1.
249 */
250int gr_rasta_tmtc_hw_init_common(struct gr_rasta_tmtc_priv *priv)
251{
252        struct ambapp_dev *tmp;
253        unsigned int pci_freq_hz;
254
255        /* Initialize Frequency of AMBA bus. The AMBA bus runs at same
256         * frequency as PCI bus
257         */
258        drvmgr_freq_get(priv->dev, 0, &pci_freq_hz);
259        ambapp_freq_init(&priv->abus, NULL, pci_freq_hz);
260
261        /* Find IRQ controller, Clear all current IRQs */
262        tmp = (void *)ambapp_for_each(&priv->abus,
263                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
264                                        VENDOR_GAISLER, GAISLER_IRQMP,
265                                        ambapp_find_by_idx, NULL);
266        if ( !tmp ) {
267                return -4;
268        }
269        priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
270        /* Set up GR-RASTA-TMTC irq controller */
271        priv->irq->mask[0] = 0;
272        priv->irq->iclear = 0xffffffff;
273        priv->irq->ilevel = 0;
274
275        /* Find First GPIO controller */
276        tmp = (void *)ambapp_for_each(&priv->abus,
277                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
278                                        VENDOR_GAISLER, GAISLER_GPIO,
279                                        ambapp_find_by_idx, NULL);
280        if ( !tmp ) {
281                return -5;
282        }
283        priv->gpio = (struct grgpio_regs *) (((struct ambapp_apb_info *)tmp->devinfo)->start);
284        /* Clear GR-RASTA-TMTC GPIO controller */
285        priv->gpio->imask = 0;
286        priv->gpio->ipol = 0;
287        priv->gpio->iedge = 0;
288        priv->gpio->bypass = 0;
289        /* Set up GR-RASTA-TMTC GPIO controller to select GRTM and GRTC */
290        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);
291        priv->gpio->dir = 0xffffffff;
292        DBG("GR-TMTC GPIO: 0x%x\n", (unsigned int)priv->gpio);
293
294        /* DOWN streams translation table */
295        priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
296        priv->bus_maps_down[0].size = priv->amba_maps[0].size;
297        priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
298        priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
299
300        priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
301        priv->bus_maps_down[1].size = priv->amba_maps[1].size;
302        priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
303        priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
304
305        /* Mark end of translation table */
306        priv->bus_maps_down[2].size = 0;
307
308        return 0;
309}
310
311/* PCI Hardware (Revision 0) initialization */
312int gr_rasta_tmtc0_hw_init(struct gr_rasta_tmtc_priv *priv)
313{
314        unsigned int *page0 = NULL;
315        struct ambapp_dev *tmp;
316        struct ambapp_ahb_info *ahb;
317        int status;
318        pci_dev_t pcidev = priv->pcidev;
319        struct pci_dev_info *devinfo = priv->devinfo;
320        uint32_t bar0, bar0_size;
321
322        /* Select version of GR-RASTA-TMTC board */
323        switch (devinfo->rev) {
324                case 0:
325                        priv->version = &gr_rasta_tmtc_ver0;
326                        break;
327                default:
328                        return -2;
329        }
330
331        bar0 = devinfo->resources[0].address;
332        bar0_size = devinfo->resources[0].size;
333        page0 = (unsigned int *)(bar0 + bar0_size/2);
334
335        /* Point PAGE0 to start of Plug and Play information */
336        *page0 = priv->version->amba_ioarea & 0xf0000000;
337
338#if 0
339        {
340                uint32_t data;
341                /* set parity error response */
342                pci_cfg_r32(pcidev, PCI_COMMAND, &data);
343                pci_cfg_w32(pcidev, PCI_COMMAND, (data|PCI_COMMAND_PARITY));
344        }
345#endif
346
347        /* Setup cache line size. Default cache line size will result in
348         * poor performance (256 word fetches), 0xff will set it according
349         * to the max size of the PCI FIFO.
350         */
351        pci_cfg_w8(pcidev, PCI_CACHE_LINE_SIZE, 0xff);
352
353        /* Scan AMBA Plug&Play */
354
355        /* AMBA MAP bar0 (in CPU) ==> 0x80000000(remote amba address) */
356        priv->amba_maps[0].size = 0x10000000;
357        priv->amba_maps[0].local_adr = bar0;
358        priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
359
360        /* AMBA MAP bar1 (in CPU) ==> 0x40000000(remote amba address) */
361        priv->amba_maps[1].size = devinfo->resources[1].size;
362        priv->amba_maps[1].local_adr = devinfo->resources[1].address;
363        priv->amba_maps[1].remote_adr = 0x40000000;
364
365        /* Addresses not matching with map be untouched */
366        priv->amba_maps[2].size = 0xfffffff0;
367        priv->amba_maps[2].local_adr = 0;
368        priv->amba_maps[2].remote_adr = 0;
369
370        /* Mark end of table */
371        priv->amba_maps[3].size=0;
372        priv->amba_maps[3].local_adr = 0;
373        priv->amba_maps[3].remote_adr = 0;
374
375        /* Start AMBA PnP scan at first AHB bus */
376        ambapp_scan(&priv->abus,
377                bar0 + (priv->version->amba_ioarea & ~0xf0000000),
378                NULL, &priv->amba_maps[0]);
379
380        /* Point PAGE0 to start of APB area */
381        *page0 = AHB1_BASE_ADDR;
382
383        /* Find GRPCI controller */
384        tmp = (void *)ambapp_for_each(&priv->abus,
385                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
386                                        VENDOR_GAISLER, GAISLER_PCIFBRG,
387                                        ambapp_find_by_idx, NULL);
388        if ( !tmp ) {
389                return -3;
390        }
391        priv->grpci = (struct grpci_regs *)((struct ambapp_apb_info *)tmp->devinfo)->start;
392
393        /* Set GRPCI mmap so that AMBA masters can access CPU-RAM over
394         * the PCI window.
395         */
396        priv->grpci->cfg_stat = (priv->grpci->cfg_stat & 0x0fffffff) |
397                                (priv->ahbmst2pci_map & 0xf0000000);
398        priv->grpci->page1 = 0x40000000;
399
400        /* init AMBA bus, IRQCtrl, GPIO, bus down-maps */
401        status = gr_rasta_tmtc_hw_init_common(priv);
402        if (status)
403                return status;
404
405        /* Find GRPCI controller AHB Slave interface */
406        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
407                                (OPTIONS_ALL|OPTIONS_AHB_SLVS),
408                                VENDOR_GAISLER, GAISLER_PCIFBRG,
409                                ambapp_find_by_idx, NULL);
410        if ( !tmp ) {
411                return -6;
412        }
413        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
414
415        /* UP streams translation table */
416        priv->bus_maps_up[0].name = "AMBA GRPCI Window";
417        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-TMTC board */
418        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
419        priv->bus_maps_up[0].to_adr = (void *)
420                                        (priv->ahbmst2pci_map & 0xf0000000);
421
422        /* Mark end of translation table */
423        priv->bus_maps_up[1].size = 0;
424
425        /* Successfully registered the RASTA board */
426        return 0;
427}
428
429/* PCI Hardware (Revision 1) initialization */
430int gr_rasta_tmtc1_hw_init(struct gr_rasta_tmtc_priv *priv)
431{
432        int i;
433        uint32_t data;
434        unsigned int ctrl;
435        uint8_t tmp2;
436        struct ambapp_dev *tmp;
437        int status;
438        struct ambapp_ahb_info *ahb;
439        uint8_t cap_ptr;
440        pci_dev_t pcidev = priv->pcidev;
441        struct pci_dev_info *devinfo = priv->devinfo;
442
443        /* Check capabilities list bit */
444        pci_cfg_r8(pcidev, PCI_STATUS, &tmp2);
445
446        if (!((tmp2 >> 4) & 1)) {
447                /* Capabilities list not available which it should be in the
448                 * GRPCI2
449                 */
450                return -3;
451        }
452
453        /* Read capabilities pointer */
454        pci_cfg_r8(pcidev, PCI_CAP_PTR, &cap_ptr);
455
456        /* Set AHB address mappings for target PCI bars
457         * BAR0: 16MB  : Mapped to I/O at 0x80000000
458         * BAR1: 256MB : Mapped to MEM at 0x40000000
459         */
460        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, AHB1_BASE_ADDR);
461        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR1_TO_AHB_MAP, 0x40000000);
462
463        /* Set PCI bus to be same endianess as PCI system */
464        pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data);
465        if (pci_endian == PCI_BIG_ENDIAN)
466                data = data & 0xFFFFFFFE;
467        else
468                data = data | 0x00000001;
469        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data);
470
471#if 0
472        /* set parity error response */
473        pci_cfg_r32(pcidev, PCI_COMMAND, &data);
474        pci_cfg_w32(pcidev, PCI_COMMAND, (data|PCI_COMMAND_PARITY));
475#endif
476
477        /* Scan AMBA Plug&Play */
478
479        /* AMBA MAP bar0 (in PCI) ==> 0x40000000 (remote amba address) */
480        priv->amba_maps[0].size = devinfo->resources[0].size;
481        priv->amba_maps[0].local_adr = devinfo->resources[0].address;
482        priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
483
484        /* AMBA MAP bar0 (in PCI) ==> 0x80000000 (remote amba address) */
485        priv->amba_maps[1].size = devinfo->resources[1].size;
486        priv->amba_maps[1].local_adr = devinfo->resources[1].address;
487        priv->amba_maps[1].remote_adr = 0x40000000;
488
489        /* Addresses not matching with map be untouched */
490        priv->amba_maps[2].size = 0xfffffff0;
491        priv->amba_maps[2].local_adr = 0;
492        priv->amba_maps[2].remote_adr = 0;
493
494        /* Mark end of table */
495        priv->amba_maps[3].size=0;
496
497        /* Start AMBA PnP scan at first AHB bus */
498        ambapp_scan(
499                &priv->abus,
500                devinfo->resources[0].address + AHB1_IOAREA_OFS,
501                NULL,
502                &priv->amba_maps[0]);
503
504        /* init AMBA bus, IRQCtrl, GPIO, bus down-maps */
505        status = gr_rasta_tmtc_hw_init_common(priv);
506        if (status)
507                return status;
508
509        /* Find GRPCI2 controller AHB Slave interface */
510        tmp = (void *)ambapp_for_each(&priv->abus,
511                                        (OPTIONS_ALL|OPTIONS_AHB_SLVS),
512                                        VENDOR_GAISLER, GAISLER_GRPCI2,
513                                        ambapp_find_by_idx, NULL);
514        if ( !tmp ) {
515                return -6;
516        }
517        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
518        priv->bus_maps_up[0].name = "AMBA GRPCI2 Window";
519        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-SPW-ROUTER board */
520        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
521        priv->bus_maps_up[0].to_adr = (void *)
522                                (priv->ahbmst2pci_map & ~(ahb->mask[0]-1));
523        priv->bus_maps_up[1].size = 0;
524
525        /* Find GRPCI2 controller APB Slave interface */
526        tmp = (void *)ambapp_for_each(&priv->abus,
527                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
528                                        VENDOR_GAISLER, GAISLER_GRPCI2,
529                                        ambapp_find_by_idx, NULL);
530        if ( !tmp ) {
531                return -7;
532        }
533        priv->grpci2 = (struct grpci2_regs *)
534                ((struct ambapp_apb_info *)tmp->devinfo)->start;
535
536        /* Set AHB to PCI mapping for all AMBA AHB masters */
537        for(i = 0; i < 16; i++) {
538                priv->grpci2->ahbtopcimemmap[i] = priv->ahbmst2pci_map &
539                                                        ~(ahb->mask[0]-1);
540        }
541
542        /* Make sure dirq(0) sampling is enabled */
543        ctrl = priv->grpci2->ctrl;
544        ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4);
545        priv->grpci2->ctrl = ctrl;
546
547        /* Successfully registered the RASTA-SPW-ROUTER board */
548        return 0;
549}
550
551void gr_rasta_tmtc_hw_init2(struct gr_rasta_tmtc_priv *priv)
552{
553        /* Enable DMA by enabling PCI target as master */
554        pci_master_enable(priv->pcidev);
555}
556
557/* Called when a PCI target is found with the PCI device and vendor ID
558 * given in gr_rasta_tmtc_ids[].
559 */
560int gr_rasta_tmtc_init1(struct drvmgr_dev *dev)
561{
562        struct gr_rasta_tmtc_priv *priv;
563        struct pci_dev_info *devinfo;
564        int status;
565        uint32_t bar0, bar1, bar0_size, bar1_size;
566        union drvmgr_key_value *value;
567
568        priv = dev->priv;
569        if (!priv)
570                return DRVMGR_NOMEM;
571        priv->dev = dev;
572
573        /* Determine number of configurations */
574        if ( gr_rasta_tmtc_resources_cnt == 0 ) {
575                while ( gr_rasta_tmtc_resources[gr_rasta_tmtc_resources_cnt] )
576                        gr_rasta_tmtc_resources_cnt++;
577        }
578
579        /* Generate Device prefix */
580
581        strcpy(priv->prefix, "/dev/rastatmtc0");
582        priv->prefix[14] += dev->minor_drv;
583        mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
584        priv->prefix[15] = '/';
585        priv->prefix[16] = '\0';
586
587        priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
588        priv->pcidev = devinfo->pcidev;
589        bar0 = devinfo->resources[0].address;
590        bar0_size = devinfo->resources[0].size;
591        bar1 = devinfo->resources[1].address;
592        bar1_size = devinfo->resources[1].size;
593        printf("\n\n--- GR-RASTA-TMTC[%d] ---\n", dev->minor_drv);
594        printf(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
595                PCI_DEV_EXPAND(priv->pcidev));
596        printf(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
597                devinfo->id.vendor, devinfo->id.device);
598        printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
599        printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
600        printf(" IRQ: %d\n\n\n", devinfo->irq);
601
602        /* all neccessary space assigned to GR-RASTA-IO target? */
603        if ((bar0_size == 0) || (bar1_size == 0))
604                return DRVMGR_ENORES;
605
606        /* Let user override which PCI address the AHB masters of the
607         * GR-RASTA-TMTC board access when doing DMA to CPU RAM. The AHB masters
608         * access the PCI Window of the AMBA bus, the MSB 4-bits of that address
609         * is translated according this config option before the address
610         * goes out on the PCI bus.
611         * Only the 4 MSB bits have an effect;
612         */
613        value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", KEY_TYPE_INT);
614        if (value)
615                priv->ahbmst2pci_map = value->i;
616        else
617                priv->ahbmst2pci_map = AHBMST2PCIADR; /* default */     
618
619        priv->genirq = genirq_init(32);
620        if ( priv->genirq == NULL )
621                return DRVMGR_FAIL;
622
623        /* Select version of GR-RASTA-IO board */
624        switch (devinfo->rev) {
625                case 0:
626                        puts("GR-RASTA-TMTC: REVISION 0");
627                        status = gr_rasta_tmtc0_hw_init(priv);
628                        break;
629                case 1:
630                        puts("GR-RASTA-TMTC: REVISION 1");
631                        status = gr_rasta_tmtc1_hw_init(priv);
632                        break;
633                default:
634                        return DRVMGR_ENOSYS; /* HW not supported */
635        }
636
637        if ( status != 0 ) {
638                genirq_destroy(priv->genirq);
639                printf(" Failed to initialize GR-RASTA-TMTC HW: %d\n", status);
640                return DRVMGR_FAIL;
641        }
642
643        /* Init amba bus */
644        priv->config.abus = &priv->abus;
645        priv->config.ops = &ambapp_rasta_tmtc_ops;
646        priv->config.maps_up = &priv->bus_maps_up[0];
647        priv->config.maps_down = &priv->bus_maps_down[0];
648        if ( priv->dev->minor_drv < gr_rasta_tmtc_resources_cnt ) {
649                priv->config.resources = gr_rasta_tmtc_resources[priv->dev->minor_drv];
650        } else {
651                priv->config.resources = NULL;
652        }
653
654        return ambapp_bus_register(dev, &priv->config);
655}
656
657int gr_rasta_tmtc_init2(struct drvmgr_dev *dev)
658{
659        struct gr_rasta_tmtc_priv *priv = dev->priv;
660
661        /* Clear any old interrupt requests */
662        drvmgr_interrupt_clear(priv->dev, 0);
663
664        /* Enable System IRQ so that GR-RASTA-TMTC PCI target interrupt goes
665         * through.
666         *
667         * It is important to enable it in stage init2. If interrupts were
668         * enabled in init1 this might hang the system when more than one
669         * PCI target is connected, this is because PCI interrupts might
670         * be shared and PCI board 2 have not initialized and
671         * might therefore drive interrupt already when entering init1().
672         */
673        drvmgr_interrupt_register(
674                priv->dev,
675                0,
676                "gr_rasta_tmtc",
677                gr_rasta_tmtc_isr,
678                (void *)priv);
679
680        gr_rasta_tmtc_hw_init2(priv);
681
682        return DRVMGR_OK;
683}
684
685int ambapp_rasta_tmtc_int_register(
686        struct drvmgr_dev *dev,
687        int irq,
688        const char *info,
689        drvmgr_isr handler,
690        void *arg)
691{
692        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
693        rtems_interrupt_level level;
694        int status;
695
696        rtems_interrupt_disable(level);
697
698        status = genirq_register(priv->genirq, irq, handler, arg);
699        if ( status == 0 ) {
700                /* Disable and clear IRQ for first registered handler */
701                priv->irq->iclear = (1<<irq);
702        } else if ( status == 1 )
703                status = 0;
704
705        if (status != 0) {
706                rtems_interrupt_enable(level);
707                return DRVMGR_FAIL;
708        }
709
710        status = genirq_enable(priv->genirq, irq, handler, arg);
711        if ( status == 0 ) {
712                /* Enable IRQ for first enabled handler only */
713                priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
714        } else if ( status == 1 )
715                status = 0;
716
717        rtems_interrupt_enable(level);
718
719        return status;
720}
721
722int ambapp_rasta_tmtc_int_unregister(
723        struct drvmgr_dev *dev,
724        int irq,
725        drvmgr_isr isr,
726        void *arg)
727{
728        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
729        rtems_interrupt_level level;
730        int status;
731
732        rtems_interrupt_disable(level);
733
734        status = genirq_disable(priv->genirq, irq, isr, arg);
735        if ( status == 0 ) {
736                /* Disable IRQ only when no enabled handler exists */
737                priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
738        } else if ( status == 1 )
739                status = 0;
740
741        status = genirq_unregister(priv->genirq, irq, isr, arg);
742        if ( status != 0 )
743                status = DRVMGR_FAIL;
744
745        rtems_interrupt_enable(level);
746
747        return status;
748}
749
750int ambapp_rasta_tmtc_int_unmask(
751        struct drvmgr_dev *dev,
752        int irq)
753{
754        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
755        rtems_interrupt_level level;
756
757        DBG("RASTA-TMTC IRQ %d: unmask\n", irq);
758
759        if ( genirq_check(priv->genirq, irq) )
760                return DRVMGR_EINVAL;
761
762        rtems_interrupt_disable(level);
763
764        /* Enable IRQ */
765        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
766
767        rtems_interrupt_enable(level);
768
769        return DRVMGR_OK;
770}
771
772int ambapp_rasta_tmtc_int_mask(
773        struct drvmgr_dev *dev,
774        int irq)
775{
776        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
777        rtems_interrupt_level level;
778
779        DBG("RASTA-TMTC IRQ %d: mask\n", irq);
780
781        if ( genirq_check(priv->genirq, irq) )
782                return DRVMGR_EINVAL;
783
784        rtems_interrupt_disable(level);
785
786        /* Disable IRQ */
787        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
788
789        rtems_interrupt_enable(level);
790
791        return DRVMGR_OK;
792}
793
794int ambapp_rasta_tmtc_int_clear(
795        struct drvmgr_dev *dev,
796        int irq)
797{
798        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
799
800        if ( genirq_check(priv->genirq, irq) )
801                return DRVMGR_FAIL;
802
803        priv->irq->iclear = (1<<irq);
804
805        return DRVMGR_OK;
806}
807
808int ambapp_rasta_tmtc_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
809{
810        struct gr_rasta_tmtc_priv *priv = dev->parent->dev->priv;
811
812        /* Device name prefix pointer, skip /dev */
813        params->dev_prefix = &priv->prefix[5];
814
815        return 0;
816}
817
818void gr_rasta_tmtc_print_dev(struct drvmgr_dev *dev, int options)
819{
820        struct gr_rasta_tmtc_priv *priv = dev->priv;
821        struct pci_dev_info *devinfo = priv->devinfo;
822        uint32_t bar0, bar1, bar0_size, bar1_size;
823
824        /* Print */
825        printf("--- GR-RASTA-TMTC [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
826                PCI_DEV_EXPAND(priv->pcidev));
827
828        bar0 = devinfo->resources[0].address;
829        bar0_size = devinfo->resources[0].size;
830        bar1 = devinfo->resources[1].address;
831        bar1_size = devinfo->resources[1].size;
832
833        printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
834        printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
835        printf(" IRQ:             %d\n", devinfo->irq);
836        printf(" PCI REVISION:    %d\n", devinfo->rev);
837        printf(" FREQ:            %d Hz\n", priv->version->amba_freq_hz);
838        printf(" IMASK:           0x%08x\n", priv->irq->mask[0]);
839        printf(" IPEND:           0x%08x\n", priv->irq->ipend);
840
841        /* Print amba config */
842        if ( options & RASTA_TMTC_OPTIONS_AMBA ) {
843                ambapp_print(&priv->abus, 10);
844        }
845
846#if 0
847        /* Print IRQ handlers and their arguments */
848        if ( options & RASTA_TMTC_OPTIONS_IRQ ) {
849                int i;
850                for(i=0; i<16; i++) {
851                        printf(" IRQ[%02d]:         0x%x, arg: 0x%x\n",
852                                i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
853                }
854        }
855#endif
856}
857
858void gr_rasta_tmtc_print(int options)
859{
860        struct pci_drv_info *drv = &gr_rasta_tmtc_info;
861        struct drvmgr_dev *dev;
862
863        dev = drv->general.dev;
864        while(dev) {
865                gr_rasta_tmtc_print_dev(dev, options);
866                dev = dev->next_in_drv;
867        }
868}
Note: See TracBrowser for help on using the repository browser.