File indexing completed on 2025-05-11 08:24:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #include <inttypes.h>
0049 #include <stdio.h>
0050 #include <stdlib.h>
0051 #include <string.h>
0052 #include <sys/types.h>
0053 #include <sys/stat.h>
0054
0055 #include <bsp.h>
0056 #include <rtems/bspIo.h>
0057 #include <pci.h>
0058
0059 #include <grlib/ambapp.h>
0060 #include <grlib/grlib.h>
0061 #include <drvmgr/drvmgr.h>
0062 #include <grlib/ambapp_bus.h>
0063 #include <drvmgr/pci_bus.h>
0064 #include <grlib/bspcommon.h>
0065 #include <grlib/genirq.h>
0066
0067 #include <bsp/gr_leon4_n2x.h>
0068
0069 #include <grlib/grlib_impl.h>
0070
0071
0072
0073
0074
0075
0076 extern unsigned int _RAM_START;
0077 #define AHBMST2PCIADR (((unsigned int)&_RAM_START) & 0xc0000000)
0078
0079 #define GRPCI2_BAR0_TO_AHB_MAP 0x04
0080 #define GRPCI2_BAR1_TO_AHB_MAP 0x08
0081 #define GRPCI2_BAR2_TO_AHB_MAP 0x0c
0082 #define GRPCI2_PCI_CONFIG 0x20
0083 #define CAP9_AHBPREF_OFS 0x3c
0084
0085
0086
0087 #ifdef DEBUG
0088 #define DBG(x...) printk(x)
0089 #else
0090 #define DBG(x...)
0091 #endif
0092
0093 int gr_cpci_leon4_n2x_init1(struct drvmgr_dev *dev);
0094 int gr_cpci_leon4_n2x_init2(struct drvmgr_dev *dev);
0095 void gr_cpci_leon4_n2x_isr(void *arg);
0096
0097 struct grpci2_regs {
0098 volatile unsigned int ctrl;
0099 volatile unsigned int sts_cap;
0100 volatile unsigned int ppref;
0101 volatile unsigned int io_map;
0102 volatile unsigned int dma_ctrl;
0103 volatile unsigned int dma_bdbase;
0104 volatile unsigned int dma_chact;
0105 int res1;
0106 volatile unsigned int bars[6];
0107 int res2[2];
0108 volatile unsigned int ahbmst_map[16];
0109 };
0110
0111
0112 struct l4n2x_grcg_regs {
0113 volatile unsigned int unlock;
0114 volatile unsigned int enable;
0115 volatile unsigned int reset;
0116 volatile unsigned int cpu_fpu;
0117 };
0118 #define CG_MASK 0x1f
0119
0120
0121 struct gr_cpci_leon4_n2x_priv {
0122
0123 struct drvmgr_dev *dev;
0124 char prefix[20];
0125 SPIN_DECLARE(devlock);
0126
0127
0128 pci_dev_t pcidev;
0129 struct pci_dev_info *devinfo;
0130 uint32_t ahbmst2pci_map;
0131
0132
0133 int eirq;
0134 genirq_t genirq;
0135
0136
0137 unsigned int amba_freq_hz;
0138 unsigned int cg_en_mask;
0139 struct irqmp_regs *irq;
0140 struct l4n2x_grcg_regs *cg;
0141 struct grpci2_regs *grpci2;
0142 struct drvmgr_map_entry bus_maps_up[2];
0143 struct drvmgr_map_entry bus_maps_down[4];
0144
0145
0146 struct ambapp_bus abus;
0147 struct ambapp_mmap amba_maps[5];
0148 struct ambapp_config config;
0149 };
0150
0151 int ambapp_leon4_n2x_int_register(
0152 struct drvmgr_dev *dev,
0153 int irq,
0154 const char *info,
0155 drvmgr_isr handler,
0156 void *arg);
0157 int ambapp_leon4_n2x_int_unregister(
0158 struct drvmgr_dev *dev,
0159 int irq,
0160 drvmgr_isr handler,
0161 void *arg);
0162 int ambapp_leon4_n2x_int_unmask(
0163 struct drvmgr_dev *dev,
0164 int irq);
0165 int ambapp_leon4_n2x_int_mask(
0166 struct drvmgr_dev *dev,
0167 int irq);
0168 int ambapp_leon4_n2x_int_clear(
0169 struct drvmgr_dev *dev,
0170 int irq);
0171 int ambapp_leon4_n2x_get_params(
0172 struct drvmgr_dev *dev,
0173 struct drvmgr_bus_params *params);
0174
0175 static struct ambapp_ops ambapp_leon4_n2x_ops = {
0176 .int_register = ambapp_leon4_n2x_int_register,
0177 .int_unregister = ambapp_leon4_n2x_int_unregister,
0178 .int_unmask = ambapp_leon4_n2x_int_unmask,
0179 .int_mask = ambapp_leon4_n2x_int_mask,
0180 .int_clear = ambapp_leon4_n2x_int_clear,
0181 .get_params = ambapp_leon4_n2x_get_params
0182 };
0183
0184 struct drvmgr_drv_ops gr_cpci_leon4_n2x_ops =
0185 {
0186 .init = {gr_cpci_leon4_n2x_init1, gr_cpci_leon4_n2x_init2, NULL, NULL},
0187 .remove = NULL,
0188 .info = NULL
0189 };
0190
0191 struct pci_dev_id_match gr_cpci_leon4_n2x_ids[] =
0192 {
0193 PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_LEON4_N2X),
0194 PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_NGMP_PROTO),
0195 PCIID_END_TABLE
0196 };
0197
0198 struct pci_drv_info gr_cpci_leon4_n2x_info =
0199 {
0200 {
0201 DRVMGR_OBJ_DRV,
0202 NULL,
0203 NULL,
0204 DRIVER_PCI_GAISLER_LEON4_N2X_ID,
0205 "GR-CPCI-LEON4-N2X",
0206 DRVMGR_BUS_TYPE_PCI,
0207 &gr_cpci_leon4_n2x_ops,
0208 NULL,
0209 0,
0210 sizeof(struct gr_cpci_leon4_n2x_priv),
0211 },
0212 &gr_cpci_leon4_n2x_ids[0]
0213 };
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 struct drvmgr_bus_res *gr_leon4_n2x_resources[] __attribute__((weak)) =
0226 {
0227 NULL
0228 };
0229
0230 void gr_cpci_leon4_n2x_register_drv(void)
0231 {
0232 DBG("Registering GR-CPCI-LEON4-N2X PCI driver\n");
0233 drvmgr_drv_register(&gr_cpci_leon4_n2x_info.general);
0234 }
0235
0236 void gr_cpci_leon4_n2x_isr(void *arg)
0237 {
0238 struct gr_cpci_leon4_n2x_priv *priv = arg;
0239 unsigned int status, tmp;
0240 int irq, eirq;
0241 SPIN_ISR_IRQFLAGS(irqflags);
0242
0243 tmp = status = priv->irq->ipend;
0244
0245
0246
0247 SPIN_LOCK(&priv->devlock, irqflags);
0248 for(irq = 0; irq < 32; irq++) {
0249 if (status & (1 << irq)) {
0250 if (irq == priv->eirq) {
0251 while ((eirq = priv->irq->intid[0] & 0x1f)) {
0252 if ((eirq & 0x10) == 0)
0253 continue;
0254 genirq_doirq(priv->genirq, eirq);
0255 priv->irq->iclear = (1 << eirq);
0256 }
0257 } else {
0258 genirq_doirq(priv->genirq, irq);
0259 }
0260 priv->irq->iclear = (1 << irq);
0261 status &= ~(1 << irq);
0262 if ( status == 0 )
0263 break;
0264 }
0265 }
0266 SPIN_UNLOCK(&priv->devlock, irqflags);
0267
0268
0269
0270
0271 if ( tmp )
0272 drvmgr_interrupt_clear(priv->dev, 0);
0273
0274 DBG("GR-CPCI-LEON4-N2X-IRQ: 0x%x\n", tmp);
0275 }
0276
0277 static int gr_cpci_leon4_n2x_hw_init1(struct gr_cpci_leon4_n2x_priv *priv)
0278 {
0279 int i;
0280 uint32_t data;
0281 unsigned int ctrl;
0282 uint8_t tmp2;
0283 struct ambapp_dev *tmp;
0284 struct ambapp_ahb_info *ahb;
0285 uint8_t cap_ptr;
0286 pci_dev_t pcidev = priv->pcidev;
0287 struct pci_dev_info *devinfo = priv->devinfo;
0288 unsigned int cgmask, enabled;
0289
0290
0291 pci_cfg_r8(pcidev, PCIR_STATUS, &tmp2);
0292 if (!((tmp2 >> 4) & 1)) {
0293
0294 return -2;
0295 }
0296 pci_cfg_r8(pcidev, PCIR_CAP_PTR, &cap_ptr);
0297
0298
0299 switch (devinfo->rev) {
0300 case 0:
0301
0302 pci_cfg_w32(pcidev, cap_ptr+CAP9_AHBPREF_OFS, 0);
0303 default:
0304 break;
0305 }
0306
0307
0308
0309
0310
0311
0312 pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, 0x00000000);
0313 pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR1_TO_AHB_MAP, 0xf0000000);
0314 pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR2_TO_AHB_MAP, 0xff800000);
0315
0316
0317 pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data);
0318 data = data & 0xFFFFFFFE;
0319 pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data);
0320
0321 #if 0
0322
0323 pci_cfg_r32(pcidev, PCIR_COMMAND, &data);
0324 pci_cfg_w32(pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN));
0325 #endif
0326
0327
0328
0329
0330 priv->amba_maps[0].size = devinfo->resources[0].size;
0331 priv->amba_maps[0].local_adr = devinfo->resources[0].address;
0332 priv->amba_maps[0].remote_adr = 0x00000000;
0333
0334 priv->amba_maps[1].size = devinfo->resources[1].size;
0335 priv->amba_maps[1].local_adr = devinfo->resources[1].address;
0336 priv->amba_maps[1].remote_adr = 0xf0000000;
0337
0338 priv->amba_maps[2].size = devinfo->resources[2].size;
0339 priv->amba_maps[2].local_adr = devinfo->resources[2].address;
0340 priv->amba_maps[2].remote_adr = 0xff800000;
0341
0342
0343 priv->amba_maps[3].size = 0xfffffff0;
0344 priv->amba_maps[3].local_adr = 0;
0345 priv->amba_maps[3].remote_adr = 0;
0346
0347
0348 priv->amba_maps[4].size=0;
0349
0350
0351 ambapp_scan(
0352 &priv->abus,
0353 devinfo->resources[2].address + 0x00700000,
0354 NULL,
0355 &priv->amba_maps[0]);
0356
0357
0358 ambapp_freq_init(&priv->abus, NULL, priv->amba_freq_hz);
0359
0360
0361 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0362 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0363 VENDOR_GAISLER, GAISLER_IRQMP,
0364 ambapp_find_by_idx, NULL);
0365 if ( !tmp ) {
0366 return -4;
0367 }
0368 priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
0369
0370
0371
0372
0373
0374
0375 priv->irq->mask[0] = 0;
0376 priv->irq->iforce = 0;
0377 priv->irq->force[0] = 0;
0378 priv->irq->ilevel = 0;
0379 priv->irq->ipend = 0;
0380 priv->irq->iclear = 0xffffffff;
0381 priv->irq->ilevel = 0;
0382
0383 priv->eirq = (priv->irq->mpstat >> 16) & 0xf;
0384
0385
0386
0387
0388 priv->cg = NULL;
0389 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0390 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0391 VENDOR_GAISLER, GAISLER_CLKGATE,
0392 ambapp_find_by_idx, NULL);
0393 if (tmp)
0394 priv->cg = (struct l4n2x_grcg_regs *)DEV_TO_APB(tmp)->start;
0395
0396
0397 if (priv->cg && ((enabled = priv->cg->enable) != priv->cg_en_mask)) {
0398
0399 cgmask = ~priv->cg_en_mask & enabled;
0400 if (cgmask) {
0401 priv->cg->unlock = cgmask;
0402 priv->cg->enable = enabled = ~cgmask & enabled;
0403 priv->cg->unlock = 0;
0404 }
0405
0406 cgmask = priv->cg_en_mask & ~enabled;
0407 if (cgmask) {
0408 priv->cg->unlock = cgmask;
0409 priv->cg->reset |= cgmask;
0410 priv->cg->enable = cgmask | enabled;
0411 priv->cg->reset &= ~cgmask;
0412 priv->cg->unlock = 0;
0413 }
0414 }
0415
0416 priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
0417 priv->bus_maps_down[0].size = priv->amba_maps[0].size;
0418 priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
0419 priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
0420 priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
0421 priv->bus_maps_down[1].size = priv->amba_maps[1].size;
0422 priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
0423 priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
0424 priv->bus_maps_down[2].name = "PCI BAR2 -> AMBA";
0425 priv->bus_maps_down[2].size = priv->amba_maps[2].size;
0426 priv->bus_maps_down[2].from_adr = (void *)priv->amba_maps[2].local_adr;
0427 priv->bus_maps_down[2].to_adr = (void *)priv->amba_maps[2].remote_adr;
0428 priv->bus_maps_down[3].size = 0;
0429
0430
0431 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0432 (OPTIONS_ALL|OPTIONS_AHB_SLVS),
0433 VENDOR_GAISLER, GAISLER_GRPCI2,
0434 ambapp_find_by_idx, NULL);
0435 if ( !tmp ) {
0436 return -6;
0437 }
0438 ahb = (struct ambapp_ahb_info *)tmp->devinfo;
0439 priv->bus_maps_up[0].name = "AMBA GRPCI2 Window";
0440 priv->bus_maps_up[0].size = ahb->mask[0];
0441 priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
0442 priv->bus_maps_up[0].to_adr = (void *)
0443 (priv->ahbmst2pci_map & ~(ahb->mask[0]-1));
0444 priv->bus_maps_up[1].size = 0;
0445
0446
0447 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0448 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0449 VENDOR_GAISLER, GAISLER_GRPCI2,
0450 ambapp_find_by_idx, NULL);
0451 if ( !tmp ) {
0452 return -7;
0453 }
0454 priv->grpci2 = (struct grpci2_regs *)
0455 ((struct ambapp_apb_info *)tmp->devinfo)->start;
0456
0457
0458 switch (devinfo->rev) {
0459 case 0:
0460
0461
0462
0463
0464 priv->grpci2->ppref = 0xffff0000;
0465 default:
0466 break;
0467 }
0468
0469
0470 for(i = 0; i < 16; i++) {
0471 priv->grpci2->ahbmst_map[i] = priv->ahbmst2pci_map &
0472 ~(ahb->mask[0]-1);
0473 }
0474
0475
0476 ctrl = priv->grpci2->ctrl;
0477 ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4);
0478 priv->grpci2->ctrl = ctrl;
0479
0480
0481 return 0;
0482 }
0483
0484 static int gr_cpci_leon4_n2x_hw_init2(struct gr_cpci_leon4_n2x_priv *priv)
0485 {
0486
0487 pci_master_enable(priv->pcidev);
0488
0489 return DRVMGR_OK;
0490 }
0491
0492
0493
0494
0495 int gr_cpci_leon4_n2x_init1(struct drvmgr_dev *dev)
0496 {
0497 struct gr_cpci_leon4_n2x_priv *priv;
0498 struct pci_dev_info *devinfo;
0499 int status, i;
0500 union drvmgr_key_value *value;
0501 int resources_cnt;
0502 int sc;
0503
0504 priv = dev->priv;
0505 if (!priv)
0506 return DRVMGR_NOMEM;
0507
0508 memset(priv, 0, sizeof(*priv));
0509 dev->priv = priv;
0510 priv->dev = dev;
0511
0512
0513 resources_cnt = get_resarray_count(gr_leon4_n2x_resources);
0514
0515
0516
0517 strcpy(priv->prefix, "/dev/leon4n2x0");
0518 priv->prefix[13] += dev->minor_drv;
0519 sc = mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
0520 _Assert_Unused_variable_equals(sc, 0);
0521 priv->prefix[14] = '/';
0522 priv->prefix[15] = '\0';
0523
0524 priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
0525 priv->pcidev = devinfo->pcidev;
0526 printk("\n\n--- GR-CPCI-LEON4-N2X[%d] ---\n", dev->minor_drv);
0527 printk(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
0528 PCI_DEV_EXPAND(priv->pcidev));
0529 printk(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
0530 devinfo->id.vendor, devinfo->id.device);
0531 for (i = 0; i < 3; i++) {
0532 printk(" PCI BAR[%d]: 0x%08" PRIx32 " - 0x%08" PRIx32 "\n",
0533 i, devinfo->resources[i].address,
0534 devinfo->resources[i].address +
0535 (devinfo->resources[i].size - 1));
0536
0537 if (devinfo->resources[i].size == 0)
0538 return DRVMGR_ENORES;
0539 }
0540 printk(" IRQ: %d\n\n\n", devinfo->irq);
0541
0542
0543
0544
0545
0546 SPIN_INIT(&priv->devlock, priv->prefix);
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556 value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", DRVMGR_KT_INT);
0557 if (value)
0558 priv->ahbmst2pci_map = value->i;
0559 else
0560 priv->ahbmst2pci_map = AHBMST2PCIADR;
0561
0562
0563
0564
0565 value = drvmgr_dev_key_get(priv->dev, "ambaFreq", DRVMGR_KT_INT);
0566 if (value)
0567 priv->amba_freq_hz = value->i;
0568 else
0569 priv->amba_freq_hz = 200000000;
0570
0571
0572
0573
0574 value = drvmgr_dev_key_get(priv->dev, "cgEnMask", DRVMGR_KT_INT);
0575 if (value)
0576 priv->cg_en_mask = (value->i & CG_MASK) | 0x08;
0577 else
0578 priv->cg_en_mask = CG_MASK;
0579
0580 priv->genirq = genirq_init(32);
0581 if (priv->genirq == NULL)
0582 return DRVMGR_FAIL;
0583
0584 if ((status = gr_cpci_leon4_n2x_hw_init1(priv)) != 0) {
0585 genirq_destroy(priv->genirq);
0586 printk(" Failed to initialize GR-CPCI-LEON4-N2X HW: %d\n", status);
0587 return DRVMGR_FAIL;
0588 }
0589
0590
0591 priv->config.abus = &priv->abus;
0592 priv->config.ops = &ambapp_leon4_n2x_ops;
0593 priv->config.maps_up = &priv->bus_maps_up[0];
0594 priv->config.maps_down = &priv->bus_maps_down[0];
0595 if ( priv->dev->minor_drv < resources_cnt ) {
0596 priv->config.resources = gr_leon4_n2x_resources[priv->dev->minor_drv];
0597 } else {
0598 priv->config.resources = NULL;
0599 }
0600
0601
0602 return ambapp_bus_register(dev, &priv->config);
0603 }
0604
0605 int gr_cpci_leon4_n2x_init2(struct drvmgr_dev *dev)
0606 {
0607 struct gr_cpci_leon4_n2x_priv *priv = dev->priv;
0608
0609
0610 drvmgr_interrupt_clear(dev, 0);
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621 drvmgr_interrupt_register(
0622 dev,
0623 0,
0624 "gr_cpci_leon4_n2x",
0625 gr_cpci_leon4_n2x_isr,
0626 (void *)priv);
0627
0628 return gr_cpci_leon4_n2x_hw_init2(priv);
0629 }
0630
0631 int ambapp_leon4_n2x_int_register(
0632 struct drvmgr_dev *dev,
0633 int irq,
0634 const char *info,
0635 drvmgr_isr handler,
0636 void *arg)
0637 {
0638 struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
0639 SPIN_IRQFLAGS(irqflags);
0640 int status;
0641 void *h;
0642
0643 h = genirq_alloc_handler(handler, arg);
0644 if ( h == NULL )
0645 return DRVMGR_FAIL;
0646
0647 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0648
0649 status = genirq_register(priv->genirq, irq, h);
0650 if (status == 0) {
0651
0652 priv->irq->iclear = (1<<irq);
0653 } else if (status == 1)
0654 status = 0;
0655
0656 if (status != 0) {
0657 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0658 genirq_free_handler(h);
0659 return DRVMGR_FAIL;
0660 }
0661
0662 status = genirq_enable(priv->genirq, irq, handler, arg);
0663 if ( status == 0 ) {
0664
0665 priv->irq->mask[0] |= (1<<irq);
0666 } else if ( status == 1 )
0667 status = 0;
0668
0669 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0670
0671 return status;
0672 }
0673
0674 int ambapp_leon4_n2x_int_unregister(
0675 struct drvmgr_dev *dev,
0676 int irq,
0677 drvmgr_isr isr,
0678 void *arg)
0679 {
0680 struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
0681 SPIN_IRQFLAGS(irqflags);
0682 int status;
0683 void *handler;
0684
0685 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0686
0687 status = genirq_disable(priv->genirq, irq, isr, arg);
0688 if ( status == 0 ) {
0689
0690 priv->irq->mask[0] &= ~(1<<irq);
0691 }
0692
0693 handler = genirq_unregister(priv->genirq, irq, isr, arg);
0694 if ( handler == NULL )
0695 status = DRVMGR_FAIL;
0696 else
0697 status = DRVMGR_OK;
0698
0699 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0700
0701 if (handler)
0702 genirq_free_handler(handler);
0703
0704 return status;
0705 }
0706
0707 int ambapp_leon4_n2x_int_unmask(
0708 struct drvmgr_dev *dev,
0709 int irq)
0710 {
0711 struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
0712 SPIN_IRQFLAGS(irqflags);
0713
0714 DBG("LEON4-N2X IRQ %d: unmask\n", irq);
0715
0716 if ( genirq_check(priv->genirq, irq) )
0717 return DRVMGR_EINVAL;
0718
0719 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0720
0721
0722 priv->irq->mask[0] |= (1<<irq);
0723
0724 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0725
0726 return DRVMGR_OK;
0727 }
0728
0729 int ambapp_leon4_n2x_int_mask(
0730 struct drvmgr_dev *dev,
0731 int irq)
0732 {
0733 struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
0734 SPIN_IRQFLAGS(irqflags);
0735
0736 DBG("LEON4-N2X IRQ %d: mask\n", irq);
0737
0738 if ( genirq_check(priv->genirq, irq) )
0739 return DRVMGR_EINVAL;
0740
0741 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0742
0743
0744 priv->irq->mask[0] &= ~(1<<irq);
0745
0746 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0747
0748 return DRVMGR_OK;
0749 }
0750
0751 int ambapp_leon4_n2x_int_clear(
0752 struct drvmgr_dev *dev,
0753 int irq)
0754 {
0755 struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
0756
0757 if ( genirq_check(priv->genirq, irq) )
0758 return DRVMGR_EINVAL;
0759
0760 priv->irq->iclear = (1<<irq);
0761
0762 return DRVMGR_OK;
0763 }
0764
0765 int ambapp_leon4_n2x_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
0766 {
0767 struct gr_cpci_leon4_n2x_priv *priv = dev->parent->dev->priv;
0768
0769
0770 params->dev_prefix = &priv->prefix[5];
0771
0772 return 0;
0773 }
0774
0775 void gr_cpci_leon4_n2x_print_dev(struct drvmgr_dev *dev, int options)
0776 {
0777 struct gr_cpci_leon4_n2x_priv *priv = dev->priv;
0778 struct pci_dev_info *devinfo = priv->devinfo;
0779 uint32_t bar0, bar0_size;
0780
0781
0782 printf("--- GR-CPCI-LEON4-N2X [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
0783 PCI_DEV_EXPAND(priv->pcidev));
0784
0785 bar0 = devinfo->resources[0].address;
0786 bar0_size = devinfo->resources[0].size;
0787 printf(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0788 bar0, bar0 + bar0_size - 1);
0789 printf(" IRQ REGS: 0x%" PRIxPTR "\n", (uintptr_t)priv->irq);
0790 printf(" IRQ: %d\n", devinfo->irq);
0791 printf(" PCI REVISION: %d\n", devinfo->rev);
0792 printf(" FREQ: %d Hz\n", priv->amba_freq_hz);
0793 printf(" IMASK: 0x%08x\n", priv->irq->mask[0]);
0794 printf(" IPEND: 0x%08x\n", priv->irq->ipend);
0795
0796
0797 if (options & GR_LEON4_N2X_OPTIONS_AMBA)
0798 ambapp_print(&priv->abus, 10);
0799 }
0800
0801 void gr_leon4_n2x_print(int options)
0802 {
0803 struct pci_drv_info *drv = &gr_cpci_leon4_n2x_info;
0804 struct drvmgr_dev *dev;
0805
0806 dev = drv->general.dev;
0807 while(dev) {
0808 gr_cpci_leon4_n2x_print_dev(dev, options);
0809 dev = dev->next_in_drv;
0810 }
0811 }