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

5
Last change on this file since ce76b9d2 was ce76b9d2, checked in by Daniel Hellstrom <daniel@…>, on 05/08/17 at 12:58:41

leon, pci-peripherals: SMP support by spin-locks and updated genirq

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