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

Last change on this file since c05d7a9d was c05d7a9d, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 21, 2018 at 8:43:27 PM

bsps/sparc: Fix warnings

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