File indexing completed on 2025-05-11 08:24:06
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 #include <inttypes.h>
0038 #include <stdio.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041 #include <sys/types.h>
0042 #include <sys/stat.h>
0043
0044 #include <bsp.h>
0045 #include <rtems/bspIo.h>
0046 #include <pci.h>
0047 #include <pci/access.h>
0048
0049 #include <grlib/ambapp.h>
0050 #include <grlib/grlib.h>
0051 #include <drvmgr/drvmgr.h>
0052 #include <grlib/ambapp_bus.h>
0053 #include <drvmgr/pci_bus.h>
0054 #include <grlib/bspcommon.h>
0055 #include <grlib/genirq.h>
0056
0057 #include <grlib/gr_tmtc_1553.h>
0058
0059 #include <grlib/grlib_impl.h>
0060
0061
0062
0063 #ifdef DEBUG
0064 #define DBG(x...) printk(x)
0065 #else
0066 #define DBG(x...)
0067 #endif
0068
0069
0070 #define PCIID_VENDOR_GAISLER 0x1AC8
0071
0072 int gr_tmtc_1553_init1(struct drvmgr_dev *dev);
0073 int gr_tmtc_1553_init2(struct drvmgr_dev *dev);
0074 void gr_tmtc_1553_isr (void *arg);
0075
0076 struct gr_tmtc_1553_ver {
0077 const unsigned int amba_freq_hz;
0078 const unsigned int amba_ioarea;
0079 };
0080
0081
0082 struct gr_tmtc_1553_priv {
0083
0084 struct drvmgr_dev *dev;
0085 char prefix[32];
0086 SPIN_DECLARE(devlock);
0087
0088
0089 pci_dev_t pcidev;
0090 struct pci_dev_info *devinfo;
0091
0092
0093 genirq_t genirq;
0094
0095 struct gr_tmtc_1553_ver *version;
0096 struct irqmp_regs *irq;
0097 struct drvmgr_map_entry bus_maps_down[2];
0098
0099 struct ambapp_bus abus;
0100 struct ambapp_mmap amba_maps[4];
0101 struct ambapp_config config;
0102 };
0103
0104 struct gr_tmtc_1553_ver gr_tmtc_1553_ver0 = {
0105 .amba_freq_hz = 33333333,
0106 .amba_ioarea = 0xfff00000,
0107 };
0108
0109
0110 int ambapp_tmtc_1553_int_register(
0111 struct drvmgr_dev *dev,
0112 int irq,
0113 const char *info,
0114 drvmgr_isr handler,
0115 void *arg);
0116 int ambapp_tmtc_1553_int_unregister(
0117 struct drvmgr_dev *dev,
0118 int irq,
0119 drvmgr_isr handler,
0120 void *arg);
0121 int ambapp_tmtc_1553_int_unmask(
0122 struct drvmgr_dev *dev,
0123 int irq);
0124 int ambapp_tmtc_1553_int_mask(
0125 struct drvmgr_dev *dev,
0126 int irq);
0127 int ambapp_tmtc_1553_int_clear(
0128 struct drvmgr_dev *dev,
0129 int irq);
0130 int ambapp_tmtc_1553_get_params(
0131 struct drvmgr_dev *dev,
0132 struct drvmgr_bus_params *params);
0133
0134 struct ambapp_ops ambapp_tmtc_1553_ops = {
0135 .int_register = ambapp_tmtc_1553_int_register,
0136 .int_unregister = ambapp_tmtc_1553_int_unregister,
0137 .int_unmask = ambapp_tmtc_1553_int_unmask,
0138 .int_mask = ambapp_tmtc_1553_int_mask,
0139 .int_clear = ambapp_tmtc_1553_int_clear,
0140 .get_params = ambapp_tmtc_1553_get_params
0141 };
0142
0143 struct drvmgr_drv_ops gr_tmtc_1553_ops =
0144 {
0145 {gr_tmtc_1553_init1, gr_tmtc_1553_init2, NULL, NULL},
0146 NULL,
0147 NULL
0148 };
0149
0150 struct pci_dev_id_match gr_tmtc_1553_ids[] =
0151 {
0152 PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_TMTC_1553),
0153 PCIID_END_TABLE
0154 };
0155
0156 struct pci_drv_info gr_tmtc_1553_info =
0157 {
0158 {
0159 DRVMGR_OBJ_DRV,
0160 NULL,
0161 NULL,
0162 DRIVER_PCI_GAISLER_TMTC_1553_ID,
0163 "GR-TMTC-1553_DRV",
0164 DRVMGR_BUS_TYPE_PCI,
0165 &gr_tmtc_1553_ops,
0166 NULL,
0167 0,
0168 0,
0169 },
0170 &gr_tmtc_1553_ids[0]
0171 };
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 struct drvmgr_bus_res *gr_tmtc_1553_resources[] __attribute__((weak)) =
0184 {
0185 NULL
0186 };
0187
0188 void gr_tmtc_1553_register_drv(void)
0189 {
0190 DBG("Registering GR-TMTC-1553 PCI driver\n");
0191 drvmgr_drv_register(&gr_tmtc_1553_info.general);
0192 }
0193
0194 void gr_tmtc_1553_isr (void *arg)
0195 {
0196 struct gr_tmtc_1553_priv *priv = arg;
0197 unsigned int status, tmp;
0198 int irq;
0199 SPIN_ISR_IRQFLAGS(irqflags);
0200
0201 tmp = status = priv->irq->ipend;
0202
0203
0204
0205 SPIN_LOCK(&priv->devlock, irqflags);
0206 for(irq=0; irq<16; irq++) {
0207 if ( status & (1<<irq) ) {
0208 genirq_doirq(priv->genirq, irq);
0209 priv->irq->iclear = (1<<irq);
0210 status &= ~(1<<irq);
0211 if ( status == 0 )
0212 break;
0213 }
0214 }
0215 SPIN_UNLOCK(&priv->devlock, irqflags);
0216
0217
0218 if ( tmp )
0219 drvmgr_interrupt_clear(priv->dev, 0);
0220
0221 DBG("GR-TMTC-1553-IRQ: 0x%x\n", tmp);
0222 }
0223
0224 static int gr_tmtc_1553_hw_init(struct gr_tmtc_1553_priv *priv)
0225 {
0226 unsigned int *page0 = NULL;
0227 struct ambapp_dev *tmp;
0228 unsigned int pci_freq_hz;
0229 struct pci_dev_info *devinfo = priv->devinfo;
0230 uint32_t bar0, bar0_size;
0231
0232
0233 switch (devinfo->rev) {
0234 case 0:
0235 priv->version = &gr_tmtc_1553_ver0;
0236 break;
0237 default:
0238 return -2;
0239 }
0240
0241 bar0 = devinfo->resources[0].address;
0242 bar0_size = devinfo->resources[0].size;
0243 page0 = (unsigned int *)(bar0 + bar0_size/2);
0244
0245
0246
0247 *page0 = 0x010000ff;
0248
0249
0250
0251
0252 priv->amba_maps[0].size = 0x1000000;
0253 priv->amba_maps[0].local_adr = bar0;
0254 priv->amba_maps[0].remote_adr = 0xff000000;
0255
0256
0257 priv->amba_maps[2].size = 0xfffffff0;
0258 priv->amba_maps[2].local_adr = 0;
0259 priv->amba_maps[2].remote_adr = 0;
0260
0261
0262 priv->amba_maps[3].size=0;
0263 priv->amba_maps[3].local_adr = 0;
0264 priv->amba_maps[3].remote_adr = 0;
0265
0266
0267 ambapp_scan(&priv->abus,
0268 bar0 + (priv->version->amba_ioarea & ~0xff000000),
0269 NULL, &priv->amba_maps[0]);
0270
0271
0272 drvmgr_freq_get(priv->dev, 0, &pci_freq_hz);
0273
0274 ambapp_freq_init(&priv->abus, NULL, pci_freq_hz);
0275
0276
0277 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0278 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0279 VENDOR_GAISLER, GAISLER_IRQMP,
0280 ambapp_find_by_idx, NULL);
0281 if ( !tmp ) {
0282 return -4;
0283 }
0284 priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
0285
0286 priv->irq->mask[0] = 0;
0287 priv->irq->iclear = 0xffff;
0288 priv->irq->ilevel = 0;
0289
0290
0291 priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
0292 priv->bus_maps_down[0].size = priv->amba_maps[0].size;
0293 priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
0294 priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
0295
0296 priv->bus_maps_down[1].size = 0;
0297
0298
0299 return 0;
0300 }
0301
0302
0303
0304
0305
0306 int gr_tmtc_1553_init1(struct drvmgr_dev *dev)
0307 {
0308 struct gr_tmtc_1553_priv *priv;
0309 struct pci_dev_info *devinfo;
0310 int status;
0311 uint32_t bar0, bar0_size;
0312 int resources_cnt;
0313 int sc;
0314
0315
0316
0317
0318
0319
0320
0321 ((struct pci_dev_info *)dev->businfo)->irq = ((struct amba_dev_info *)dev->parent->dev->businfo)->info.irq;
0322
0323 priv = grlib_calloc(1, sizeof(*priv));
0324 if ( !priv )
0325 return DRVMGR_NOMEM;
0326
0327 dev->priv = priv;
0328 priv->dev = dev;
0329
0330
0331 resources_cnt = get_resarray_count(gr_tmtc_1553_resources);
0332
0333
0334
0335 strcpy(priv->prefix, "/dev/tmtc1553_0");
0336 priv->prefix[14] += dev->minor_drv;
0337 sc = mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
0338 _Assert_Unused_variable_equals(sc, 0);
0339 priv->prefix[15] = '/';
0340 priv->prefix[16] = '\0';
0341
0342 priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
0343 priv->pcidev = devinfo->pcidev;
0344 bar0 = devinfo->resources[0].address;
0345 bar0_size = devinfo->resources[0].size;
0346 printk("\n\n--- GR-TMTC-1553[%d] ---\n", dev->minor_drv);
0347 printk(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
0348 PCI_DEV_EXPAND(priv->pcidev));
0349 printk(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
0350 devinfo->id.vendor, devinfo->id.device);
0351 printk(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0352 bar0, bar0 + bar0_size - 1);
0353 printk(" IRQ: %d\n\n\n", devinfo->irq);
0354
0355
0356 if (bar0_size == 0)
0357 return DRVMGR_ENORES;
0358
0359
0360
0361
0362
0363 SPIN_INIT(&priv->devlock, priv->prefix);
0364
0365 priv->genirq = genirq_init(16);
0366 if ( priv->genirq == NULL ) {
0367 free(priv);
0368 dev->priv = NULL;
0369 return DRVMGR_FAIL;
0370 }
0371
0372 status = gr_tmtc_1553_hw_init(priv);
0373 if ( status != 0 ) {
0374 genirq_destroy(priv->genirq);
0375 free(priv);
0376 dev->priv = NULL;
0377 printk(" Failed to initialize GR-TMTC-1553 HW: %d\n", status);
0378 return DRVMGR_FAIL;
0379 }
0380
0381
0382 priv->config.abus = &priv->abus;
0383 priv->config.ops = &ambapp_tmtc_1553_ops;
0384 priv->config.maps_down = &priv->bus_maps_down[0];
0385
0386
0387
0388 priv->config.maps_up = DRVMGR_TRANSLATE_NO_BRIDGE;
0389 if ( priv->dev->minor_drv < resources_cnt ) {
0390 priv->config.resources = gr_tmtc_1553_resources[priv->dev->minor_drv];
0391 } else {
0392 priv->config.resources = NULL;
0393 }
0394
0395
0396 return ambapp_bus_register(dev, &priv->config);
0397 }
0398
0399 int gr_tmtc_1553_init2(struct drvmgr_dev *dev)
0400 {
0401 struct gr_tmtc_1553_priv *priv = dev->priv;
0402
0403
0404 drvmgr_interrupt_clear(dev, 0);
0405
0406
0407
0408
0409
0410
0411
0412
0413 drvmgr_interrupt_register(
0414 dev,
0415 0,
0416 "gr_tmtc_1553",
0417 gr_tmtc_1553_isr,
0418 (void *)priv);
0419
0420 return DRVMGR_OK;
0421 }
0422
0423 int ambapp_tmtc_1553_int_register(
0424 struct drvmgr_dev *dev,
0425 int irq,
0426 const char *info,
0427 drvmgr_isr handler,
0428 void *arg)
0429 {
0430 struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
0431 SPIN_IRQFLAGS(irqflags);
0432 int status;
0433 void *h;
0434
0435 h = genirq_alloc_handler(handler, arg);
0436 if ( h == NULL )
0437 return DRVMGR_FAIL;
0438
0439 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0440
0441 status = genirq_register(priv->genirq, irq, h);
0442 if ( status == 0 ) {
0443
0444 priv->irq->iclear = (1<<irq);
0445 priv->irq->mask[0] &= ~(1<<irq);
0446 } else if ( status == 1 )
0447 status = 0;
0448
0449 if (status != 0) {
0450 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0451 genirq_free_handler(h);
0452 return DRVMGR_FAIL;
0453 }
0454
0455 status = genirq_enable(priv->genirq, irq, handler, arg);
0456 if ( status == 0 ) {
0457
0458 priv->irq->mask[0] |= (1<<irq);
0459 } else if ( status == 1 )
0460 status = 0;
0461
0462 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0463
0464 return status;
0465 }
0466
0467 int ambapp_tmtc_1553_int_unregister(
0468 struct drvmgr_dev *dev,
0469 int irq,
0470 drvmgr_isr isr,
0471 void *arg)
0472 {
0473 struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
0474 SPIN_IRQFLAGS(irqflags);
0475 int status;
0476 void *handler;
0477
0478 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0479
0480 status = genirq_disable(priv->genirq, irq, isr, arg);
0481 if ( status == 0 ) {
0482
0483 priv->irq->mask[0] &= ~(1<<irq);
0484 } else if ( status == 1 )
0485 status = 0;
0486
0487 handler = genirq_unregister(priv->genirq, irq, isr, arg);
0488 if ( handler == NULL )
0489 status = DRVMGR_FAIL;
0490 else
0491 status = DRVMGR_OK;
0492
0493 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0494
0495 if (handler)
0496 genirq_free_handler(handler);
0497
0498 return status;
0499 }
0500
0501 int ambapp_tmtc_1553_int_unmask(
0502 struct drvmgr_dev *dev,
0503 int irq)
0504 {
0505 struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
0506 SPIN_IRQFLAGS(irqflags);
0507
0508 DBG("TMTC-1553 IRQ %d: enable\n", irq);
0509
0510 if ( genirq_check(priv->genirq, irq) )
0511 return DRVMGR_FAIL;
0512
0513 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0514
0515
0516 priv->irq->mask[0] |= (1<<irq);
0517
0518 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0519
0520 return DRVMGR_OK;
0521 }
0522
0523 int ambapp_tmtc_1553_int_mask(
0524 struct drvmgr_dev *dev,
0525 int irq)
0526 {
0527 struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
0528 SPIN_IRQFLAGS(irqflags);
0529
0530 DBG("TMTC-1553 IRQ %d: disable\n", irq);
0531
0532 if ( genirq_check(priv->genirq, irq) )
0533 return DRVMGR_FAIL;
0534
0535 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0536
0537
0538 priv->irq->mask[0] &= ~(1<<irq);
0539
0540 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0541
0542 return DRVMGR_OK;
0543 }
0544
0545 int ambapp_tmtc_1553_int_clear(
0546 struct drvmgr_dev *dev,
0547 int irq)
0548 {
0549 struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
0550
0551 if ( genirq_check(priv->genirq, irq) )
0552 return DRVMGR_FAIL;
0553
0554 priv->irq->iclear = (1<<irq);
0555
0556 return DRVMGR_OK;
0557 }
0558
0559 int ambapp_tmtc_1553_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
0560 {
0561 struct gr_tmtc_1553_priv *priv = dev->parent->dev->priv;
0562
0563
0564 params->dev_prefix = &priv->prefix[5];
0565
0566 return 0;
0567 }
0568
0569 void gr_tmtc_1553_print_dev(struct drvmgr_dev *dev, int options)
0570 {
0571 struct gr_tmtc_1553_priv *priv = dev->priv;
0572 struct pci_dev_info *devinfo = priv->devinfo;
0573 uint32_t bar0, bar0_size;
0574
0575
0576 printf("--- GR-TMTC-1553 [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
0577 PCI_DEV_EXPAND(priv->pcidev));
0578
0579 bar0 = devinfo->resources[0].address;
0580 bar0_size = devinfo->resources[0].size;
0581
0582 printf(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0583 bar0, bar0 + bar0_size - 1);
0584 printf(" IRQ REGS: 0x%" PRIxPTR "\n", (uintptr_t)priv->irq);
0585 printf(" IRQ: %d\n", devinfo->irq);
0586 printf(" FREQ: %d Hz\n", priv->version->amba_freq_hz);
0587 printf(" IMASK: 0x%08x\n", priv->irq->mask[0]);
0588 printf(" IPEND: 0x%08x\n", priv->irq->ipend);
0589
0590
0591 if ( options & TMTC_1553_OPTIONS_AMBA ) {
0592 ambapp_print(&priv->abus, 10);
0593 }
0594 #if 0
0595
0596 if ( options & TMTC_1553_OPTIONS_IRQ ) {
0597 int i;
0598 for(i=0; i<16; i++) {
0599 printf(" IRQ[%02d]: 0x%x, arg: 0x%x\n",
0600 i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
0601 }
0602 }
0603 #endif
0604 }
0605
0606 void gr_tmtc_1553_print(int options)
0607 {
0608 struct pci_drv_info *drv = &gr_tmtc_1553_info;
0609 struct drvmgr_dev *dev;
0610
0611 dev = drv->general.dev;
0612 while(dev) {
0613 gr_tmtc_1553_print_dev(dev, options);
0614 dev = dev->next_in_drv;
0615 }
0616 }