source: rtems/bsps/sparc/shared/pci/gr_rasta_tmtc.c @ 75e1009f

Last change on this file since 75e1009f was a7267241, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 26, 2018 at 2:44:25 PM

bsps/sparc: Add and use <grlib_impl.h>

Reduce copy and paste.

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