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
0048 #include <grlib/ambapp.h>
0049 #include <grlib/grlib.h>
0050 #include <drvmgr/drvmgr.h>
0051 #include <grlib/ambapp_bus.h>
0052 #include <drvmgr/pci_bus.h>
0053 #include <grlib/bspcommon.h>
0054 #include <grlib/genirq.h>
0055
0056 #include <grlib/gr_rasta_io.h>
0057
0058 #include <grlib/grlib_impl.h>
0059
0060
0061
0062
0063
0064 extern unsigned int _RAM_START;
0065 #define AHBMST2PCIADR (((unsigned int)&_RAM_START) & 0xf0000000)
0066
0067
0068 #define AHB1_BASE_ADDR 0x80000000
0069 #define AHB1_IOAREA_BASE_ADDR 0x80100000
0070 #define AHB1_IOAREA_OFS (AHB1_IOAREA_BASE_ADDR - AHB1_BASE_ADDR)
0071
0072
0073 #define GRPCI2_BAR0_TO_AHB_MAP 0x04
0074 #define GRPCI2_BAR1_TO_AHB_MAP 0x08
0075 #define GRPCI2_PCI_CONFIG 0x20
0076
0077
0078
0079
0080 #ifdef DEBUG
0081 #define DBG(x...) printk(x)
0082 #else
0083 #define DBG(x...)
0084 #endif
0085
0086
0087 #define PCIID_VENDOR_GAISLER 0x1AC8
0088
0089 int gr_rasta_io_init1(struct drvmgr_dev *dev);
0090 int gr_rasta_io_init2(struct drvmgr_dev *dev);
0091 void gr_rasta_io_isr (void *arg);
0092
0093 struct grpci_regs {
0094 volatile unsigned int cfg_stat;
0095 volatile unsigned int bar0;
0096 volatile unsigned int page0;
0097 volatile unsigned int bar1;
0098 volatile unsigned int page1;
0099 volatile unsigned int iomap;
0100 volatile unsigned int stat_cmd;
0101 };
0102
0103 struct grpci2_regs {
0104 volatile unsigned int ctrl;
0105 volatile unsigned int statcap;
0106 volatile unsigned int pcimstprefetch;
0107 volatile unsigned int ahbtopciiomap;
0108 volatile unsigned int dmactrl;
0109 volatile unsigned int dmadesc;
0110 volatile unsigned int dmachanact;
0111 volatile unsigned int reserved;
0112 volatile unsigned int pcibartoahb[6];
0113 volatile unsigned int reserved2[2];
0114 volatile unsigned int ahbtopcimemmap[16];
0115 volatile unsigned int trcctrl;
0116 volatile unsigned int trccntmode;
0117 volatile unsigned int trcadpat;
0118 volatile unsigned int trcadmask;
0119 volatile unsigned int trcctrlsigpat;
0120 volatile unsigned int trcctrlsigmask;
0121 volatile unsigned int trcadstate;
0122 volatile unsigned int trcctrlsigstate;
0123 };
0124
0125 struct gr_rasta_io_ver {
0126 const unsigned int amba_freq_hz;
0127 const unsigned int amba_ioarea;
0128 };
0129
0130
0131 struct gr_rasta_io_priv {
0132
0133 struct drvmgr_dev *dev;
0134 char prefix[16];
0135 SPIN_DECLARE(devlock);
0136
0137
0138 pci_dev_t pcidev;
0139 struct pci_dev_info *devinfo;
0140 uint32_t ahbmst2pci_map;
0141
0142
0143 genirq_t genirq;
0144
0145
0146 struct gr_rasta_io_ver *version;
0147 struct irqmp_regs *irq;
0148 struct grpci_regs *grpci;
0149 struct grpci2_regs *grpci2;
0150 struct drvmgr_map_entry bus_maps_down[3];
0151 struct drvmgr_map_entry bus_maps_up[2];
0152
0153
0154 struct ambapp_bus abus;
0155 struct ambapp_mmap amba_maps[4];
0156 struct ambapp_config config;
0157 };
0158
0159 struct gr_rasta_io_ver gr_rasta_io_ver0 = {
0160 .amba_freq_hz = 30000000,
0161 .amba_ioarea = 0x80100000,
0162 };
0163
0164 struct gr_rasta_io_ver gr_rasta_io_ver1 = {
0165 .amba_freq_hz = 50000000,
0166 .amba_ioarea = 0x80100000,
0167 };
0168
0169 int ambapp_rasta_io_int_register(
0170 struct drvmgr_dev *dev,
0171 int irq,
0172 const char *info,
0173 drvmgr_isr handler,
0174 void *arg);
0175 int ambapp_rasta_io_int_unregister(
0176 struct drvmgr_dev *dev,
0177 int irq,
0178 drvmgr_isr handler,
0179 void *arg);
0180 int ambapp_rasta_io_int_unmask(
0181 struct drvmgr_dev *dev,
0182 int irq);
0183 int ambapp_rasta_io_int_mask(
0184 struct drvmgr_dev *dev,
0185 int irq);
0186 int ambapp_rasta_io_int_clear(
0187 struct drvmgr_dev *dev,
0188 int irq);
0189 int ambapp_rasta_io_get_params(
0190 struct drvmgr_dev *dev,
0191 struct drvmgr_bus_params *params);
0192
0193 struct ambapp_ops ambapp_rasta_io_ops = {
0194 .int_register = ambapp_rasta_io_int_register,
0195 .int_unregister = ambapp_rasta_io_int_unregister,
0196 .int_unmask = ambapp_rasta_io_int_unmask,
0197 .int_mask = ambapp_rasta_io_int_mask,
0198 .int_clear = ambapp_rasta_io_int_clear,
0199 .get_params = ambapp_rasta_io_get_params
0200 };
0201
0202 struct drvmgr_drv_ops gr_rasta_io_ops =
0203 {
0204 .init = {gr_rasta_io_init1, gr_rasta_io_init2, NULL, NULL},
0205 .remove = NULL,
0206 .info = NULL
0207 };
0208
0209 struct pci_dev_id_match gr_rasta_io_ids[] =
0210 {
0211 PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_RASTA_IO),
0212 PCIID_DEVVEND(PCIID_VENDOR_GAISLER_OLD, PCIID_DEVICE_GR_RASTA_IO_OLD),
0213 PCIID_END_TABLE
0214 };
0215
0216 struct pci_drv_info gr_rasta_io_info =
0217 {
0218 {
0219 DRVMGR_OBJ_DRV,
0220 NULL,
0221 NULL,
0222 DRIVER_PCI_GAISLER_RASTAIO_ID,
0223 "GR-RASTA-IO_DRV",
0224 DRVMGR_BUS_TYPE_PCI,
0225 &gr_rasta_io_ops,
0226 NULL,
0227 0,
0228 0,
0229 },
0230 &gr_rasta_io_ids[0]
0231 };
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 struct drvmgr_bus_res *gr_rasta_io_resources[] __attribute__((weak)) =
0244 {
0245 NULL
0246 };
0247
0248 void gr_rasta_io_register_drv(void)
0249 {
0250 DBG("Registering GR-RASTA-IO PCI driver\n");
0251 drvmgr_drv_register(&gr_rasta_io_info.general);
0252 }
0253
0254 void gr_rasta_io_isr (void *arg)
0255 {
0256 struct gr_rasta_io_priv *priv = arg;
0257 unsigned int status, tmp;
0258 int irq;
0259 SPIN_ISR_IRQFLAGS(irqflags);
0260
0261 tmp = status = priv->irq->ipend;
0262
0263
0264
0265 SPIN_LOCK(&priv->devlock, irqflags);
0266 for(irq=0; irq<16; irq++) {
0267 if ( status & (1<<irq) ) {
0268 genirq_doirq(priv->genirq, irq);
0269 priv->irq->iclear = (1<<irq);
0270 status &= ~(1<<irq);
0271 if ( status == 0 )
0272 break;
0273 }
0274 }
0275 SPIN_UNLOCK(&priv->devlock, irqflags);
0276
0277
0278 if ( tmp )
0279 drvmgr_interrupt_clear(priv->dev, 0);
0280
0281 DBG("RASTA-IO-IRQ: 0x%x\n", tmp);
0282 }
0283
0284
0285 static int gr_rasta_io_hw_init(struct gr_rasta_io_priv *priv)
0286 {
0287 unsigned int *page0 = NULL;
0288 struct ambapp_dev *tmp;
0289 struct ambapp_ahb_info *ahb;
0290 struct pci_dev_info *devinfo = priv->devinfo;
0291 uint32_t bar0, bar0_size;
0292
0293 bar0 = devinfo->resources[0].address;
0294 bar0_size = devinfo->resources[0].size;
0295 page0 = (unsigned int *)(bar0 + bar0_size/2);
0296
0297
0298 *page0 = priv->version->amba_ioarea & 0xff000000;
0299
0300 #if 0
0301 {
0302 uint32_t data;
0303
0304 pci_cfg_r32(priv->pcidev, PCIR_COMMAND, &data);
0305 pci_cfg_w32(priv->pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN));
0306 }
0307 #endif
0308
0309
0310
0311
0312
0313 pci_cfg_w8(priv->pcidev, PCIR_CACHELNSZ, 0xff);
0314
0315
0316
0317
0318 priv->amba_maps[0].size = bar0_size/2;
0319 priv->amba_maps[0].local_adr = bar0;
0320 priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
0321
0322
0323 priv->amba_maps[1].size = devinfo->resources[1].size;
0324 priv->amba_maps[1].local_adr = devinfo->resources[1].address;
0325 priv->amba_maps[1].remote_adr = 0x40000000;
0326
0327
0328 priv->amba_maps[2].size = 0xfffffff0;
0329 priv->amba_maps[2].local_adr = 0;
0330 priv->amba_maps[2].remote_adr = 0;
0331
0332
0333 priv->amba_maps[3].size=0;
0334 priv->amba_maps[3].local_adr = 0;
0335 priv->amba_maps[3].remote_adr = 0;
0336
0337
0338 ambapp_scan(&priv->abus,
0339 bar0 + (priv->version->amba_ioarea & ~0xff000000),
0340 NULL, &priv->amba_maps[0]);
0341
0342
0343 ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
0344
0345
0346 *page0 = AHB1_BASE_ADDR;
0347
0348
0349 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0350 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0351 VENDOR_GAISLER, GAISLER_PCIFBRG,
0352 ambapp_find_by_idx, NULL);
0353 if ( !tmp ) {
0354 return -3;
0355 }
0356 priv->grpci = (struct grpci_regs *)((struct ambapp_apb_info *)tmp->devinfo)->start;
0357
0358
0359
0360
0361 priv->grpci->cfg_stat = (priv->grpci->cfg_stat & 0x0fffffff) |
0362 (priv->ahbmst2pci_map & 0xf0000000);
0363 priv->grpci->page1 = 0x40000000;
0364
0365
0366 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0367 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0368 VENDOR_GAISLER, GAISLER_IRQMP,
0369 ambapp_find_by_idx, NULL);
0370 if ( !tmp ) {
0371 return -4;
0372 }
0373 priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
0374
0375 priv->irq->mask[0] = 0;
0376 priv->irq->iclear = 0xffff;
0377 priv->irq->ilevel = 0;
0378
0379
0380 priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
0381 priv->bus_maps_down[0].size = priv->amba_maps[0].size;
0382 priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
0383 priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
0384
0385 priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
0386 priv->bus_maps_down[1].size = priv->amba_maps[1].size;
0387 priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
0388 priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
0389
0390
0391 priv->bus_maps_down[2].size = 0;
0392
0393
0394 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0395 (OPTIONS_ALL|OPTIONS_AHB_SLVS),
0396 VENDOR_GAISLER, GAISLER_PCIFBRG,
0397 ambapp_find_by_idx, NULL);
0398 if ( !tmp ) {
0399 return -5;
0400 }
0401 ahb = (struct ambapp_ahb_info *)tmp->devinfo;
0402
0403
0404 priv->bus_maps_up[0].name = "AMBA GRPCI Window";
0405 priv->bus_maps_up[0].size = ahb->mask[0];
0406 priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
0407 priv->bus_maps_up[0].to_adr = (void *)
0408 (priv->ahbmst2pci_map & 0xf0000000);
0409
0410
0411 priv->bus_maps_up[1].size = 0;
0412
0413
0414 return 0;
0415 }
0416
0417
0418 static int gr_rasta_io2_hw_init(struct gr_rasta_io_priv *priv)
0419 {
0420 int i;
0421 uint32_t data;
0422 unsigned int ctrl;
0423 uint8_t tmp2;
0424 struct ambapp_dev *tmp;
0425 struct ambapp_ahb_info *ahb;
0426 uint8_t cap_ptr;
0427 pci_dev_t pcidev = priv->pcidev;
0428 struct pci_dev_info *devinfo = priv->devinfo;
0429
0430
0431 pci_cfg_r8(pcidev, PCIR_STATUS, &tmp2);
0432
0433 if (!((tmp2 >> 4) & 1)) {
0434
0435
0436
0437 return -3;
0438 }
0439
0440
0441 pci_cfg_r8(pcidev, PCIR_CAP_PTR, &cap_ptr);
0442
0443
0444
0445
0446
0447 pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, AHB1_BASE_ADDR);
0448 pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR1_TO_AHB_MAP, 0x40000000);
0449
0450
0451 pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data);
0452 if (pci_endian == PCI_BIG_ENDIAN)
0453 data = data & 0xFFFFFFFE;
0454 else
0455 data = data | 0x00000001;
0456 pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data);
0457
0458 #if 0
0459
0460 pci_cfg_r32(pcidev, PCIR_COMMAND, &data);
0461 pci_cfg_w32(pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN));
0462 #endif
0463
0464
0465
0466
0467 priv->amba_maps[0].size = devinfo->resources[0].size;
0468 priv->amba_maps[0].local_adr = devinfo->resources[0].address;
0469 priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
0470
0471
0472 priv->amba_maps[1].size = devinfo->resources[1].size;
0473 priv->amba_maps[1].local_adr = devinfo->resources[1].address;
0474 priv->amba_maps[1].remote_adr = 0x40000000;
0475
0476
0477 priv->amba_maps[2].size = 0xfffffff0;
0478 priv->amba_maps[2].local_adr = 0;
0479 priv->amba_maps[2].remote_adr = 0;
0480
0481
0482 priv->amba_maps[3].size=0;
0483
0484
0485 ambapp_scan(
0486 &priv->abus,
0487 devinfo->resources[0].address + AHB1_IOAREA_OFS,
0488 NULL,
0489 &priv->amba_maps[0]);
0490
0491
0492
0493
0494 ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
0495
0496
0497 tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0498 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0499 VENDOR_GAISLER, GAISLER_IRQMP,
0500 ambapp_find_by_idx, NULL);
0501 if ( !tmp ) {
0502 return -4;
0503 }
0504 priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
0505
0506 priv->irq->mask[0] = 0;
0507 priv->irq->iclear = 0xffff;
0508 priv->irq->ilevel = 0;
0509
0510 priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
0511 priv->bus_maps_down[0].size = priv->amba_maps[0].size;
0512 priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
0513 priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
0514 priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
0515 priv->bus_maps_down[1].size = priv->amba_maps[1].size;
0516 priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
0517 priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
0518 priv->bus_maps_down[2].size = 0;
0519
0520
0521 tmp = (void *)ambapp_for_each(&priv->abus,
0522 (OPTIONS_ALL|OPTIONS_AHB_SLVS),
0523 VENDOR_GAISLER, GAISLER_GRPCI2,
0524 ambapp_find_by_idx, NULL);
0525 if ( !tmp ) {
0526 return -5;
0527 }
0528 ahb = (struct ambapp_ahb_info *)tmp->devinfo;
0529 priv->bus_maps_up[0].name = "AMBA GRPCI2 Window";
0530 priv->bus_maps_up[0].size = ahb->mask[0];
0531 priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
0532 priv->bus_maps_up[0].to_adr = (void *)
0533 (priv->ahbmst2pci_map & ~(ahb->mask[0]-1));
0534 priv->bus_maps_up[1].size = 0;
0535
0536
0537 tmp = (void *)ambapp_for_each(&priv->abus,
0538 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0539 VENDOR_GAISLER, GAISLER_GRPCI2,
0540 ambapp_find_by_idx, NULL);
0541 if ( !tmp ) {
0542 return -6;
0543 }
0544 priv->grpci2 = (struct grpci2_regs *)
0545 ((struct ambapp_apb_info *)tmp->devinfo)->start;
0546
0547
0548 for(i = 0; i < 16; i++) {
0549 priv->grpci2->ahbtopcimemmap[i] = priv->ahbmst2pci_map &
0550 ~(ahb->mask[0]-1);
0551 }
0552
0553
0554 ctrl = priv->grpci2->ctrl;
0555 ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4);
0556 priv->grpci2->ctrl = ctrl;
0557
0558
0559 return 0;
0560 }
0561
0562 static int gr_rasta_io_hw_init2(struct gr_rasta_io_priv *priv)
0563 {
0564
0565 pci_master_enable(priv->pcidev);
0566
0567 return DRVMGR_OK;
0568 }
0569
0570
0571
0572
0573 int gr_rasta_io_init1(struct drvmgr_dev *dev)
0574 {
0575 struct gr_rasta_io_priv *priv;
0576 struct pci_dev_info *devinfo;
0577 int status;
0578 uint32_t bar0, bar1, bar0_size, bar1_size;
0579 union drvmgr_key_value *value;
0580 int resources_cnt;
0581 int sc;
0582
0583 priv = grlib_calloc(1, sizeof(*priv));
0584 if ( !priv )
0585 return DRVMGR_NOMEM;
0586
0587 dev->priv = priv;
0588 priv->dev = dev;
0589
0590
0591 resources_cnt = get_resarray_count(gr_rasta_io_resources);
0592
0593
0594
0595 strcpy(priv->prefix, "/dev/rastaio0");
0596 priv->prefix[12] += dev->minor_drv;
0597 sc = mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
0598 _Assert_Unused_variable_equals(sc, 0);
0599 priv->prefix[13] = '/';
0600 priv->prefix[14] = '\0';
0601
0602 priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
0603 priv->pcidev = devinfo->pcidev;
0604 bar0 = devinfo->resources[0].address;
0605 bar0_size = devinfo->resources[0].size;
0606 bar1 = devinfo->resources[1].address;
0607 bar1_size = devinfo->resources[1].size;
0608 printk("\n\n--- GR-RASTA-IO[%d] ---\n", dev->minor_drv);
0609 printk(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
0610 PCI_DEV_EXPAND(priv->pcidev));
0611 printk(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
0612 devinfo->id.vendor, devinfo->id.device);
0613 printk(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0614 bar0, bar0 + bar0_size - 1);
0615 printk(" PCI BAR[1]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0616 bar1, bar1 + bar1_size - 1);
0617 printk(" IRQ: %d\n\n\n", devinfo->irq);
0618
0619
0620 if ((bar0_size == 0) || (bar1_size == 0))
0621 return DRVMGR_ENORES;
0622
0623
0624
0625
0626
0627 SPIN_INIT(&priv->devlock, priv->prefix);
0628
0629
0630
0631
0632
0633
0634
0635
0636 value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", DRVMGR_KT_INT);
0637 if (value)
0638 priv->ahbmst2pci_map = value->i;
0639 else
0640 priv->ahbmst2pci_map = AHBMST2PCIADR;
0641
0642 priv->genirq = genirq_init(16);
0643 if ( priv->genirq == NULL ) {
0644 free(priv);
0645 dev->priv = NULL;
0646 return DRVMGR_FAIL;
0647 }
0648
0649
0650 switch (devinfo->rev) {
0651 case 0:
0652 priv->version = &gr_rasta_io_ver0;
0653 status = gr_rasta_io_hw_init(priv);
0654 break;
0655 case 1:
0656 priv->version = &gr_rasta_io_ver1;
0657 status = gr_rasta_io_hw_init(priv);
0658 break;
0659 case 2:
0660 priv->version = &gr_rasta_io_ver1;
0661 status = gr_rasta_io2_hw_init(priv);
0662 break;
0663 default:
0664 return -2;
0665 }
0666
0667 if ( status != 0 ) {
0668 genirq_destroy(priv->genirq);
0669 free(priv);
0670 dev->priv = NULL;
0671 printk(" Failed to initialize GR-RASTA-IO HW: %d\n", status);
0672 return DRVMGR_FAIL;
0673 }
0674
0675
0676 priv->config.abus = &priv->abus;
0677 priv->config.ops = &ambapp_rasta_io_ops;
0678 priv->config.maps_up = &priv->bus_maps_up[0];
0679 priv->config.maps_down = &priv->bus_maps_down[0];
0680 if ( priv->dev->minor_drv < resources_cnt ) {
0681 priv->config.resources = gr_rasta_io_resources[priv->dev->minor_drv];
0682 } else {
0683 priv->config.resources = NULL;
0684 }
0685
0686
0687 return ambapp_bus_register(dev, &priv->config);
0688 }
0689
0690 int gr_rasta_io_init2(struct drvmgr_dev *dev)
0691 {
0692 struct gr_rasta_io_priv *priv = dev->priv;
0693
0694
0695 drvmgr_interrupt_clear(dev, 0);
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706 drvmgr_interrupt_register(
0707 dev,
0708 0,
0709 "gr_rasta_io",
0710 gr_rasta_io_isr,
0711 (void *)priv);
0712
0713 return gr_rasta_io_hw_init2(priv);
0714 }
0715
0716 int ambapp_rasta_io_int_register(
0717 struct drvmgr_dev *dev,
0718 int irq,
0719 const char *info,
0720 drvmgr_isr handler,
0721 void *arg)
0722 {
0723 struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0724 SPIN_IRQFLAGS(irqflags);
0725 int status;
0726 void *h;
0727
0728 h = genirq_alloc_handler(handler, arg);
0729 if ( h == NULL )
0730 return DRVMGR_FAIL;
0731
0732 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0733
0734 status = genirq_register(priv->genirq, irq, h);
0735 if ( status == 0 ) {
0736
0737 priv->irq->iclear = (1<<irq);
0738 } else if ( status == 1 )
0739 status = 0;
0740
0741 if (status != 0) {
0742 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0743 genirq_free_handler(h);
0744 return DRVMGR_FAIL;
0745 }
0746
0747 status = genirq_enable(priv->genirq, irq, handler, arg);
0748 if ( status == 0 ) {
0749
0750 priv->irq->mask[0] |= (1<<irq);
0751 } else if ( status == 1 )
0752 status = 0;
0753
0754 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0755
0756 return status;
0757 }
0758
0759 int ambapp_rasta_io_int_unregister(
0760 struct drvmgr_dev *dev,
0761 int irq,
0762 drvmgr_isr isr,
0763 void *arg)
0764 {
0765 struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0766 SPIN_IRQFLAGS(irqflags);
0767 int status;
0768 void *handler;
0769
0770 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0771
0772 status = genirq_disable(priv->genirq, irq, isr, arg);
0773 if ( status == 0 ) {
0774
0775 priv->irq->mask[0] &= ~(1<<irq);
0776 }
0777
0778 handler = genirq_unregister(priv->genirq, irq, isr, arg);
0779 if ( handler == NULL )
0780 status = DRVMGR_FAIL;
0781 else
0782 status = DRVMGR_OK;
0783
0784 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0785
0786 if (handler)
0787 genirq_free_handler(handler);
0788
0789 return status;
0790 }
0791
0792 int ambapp_rasta_io_int_unmask(
0793 struct drvmgr_dev *dev,
0794 int irq)
0795 {
0796 struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0797 SPIN_IRQFLAGS(irqflags);
0798
0799 DBG("RASTA-IO IRQ %d: unmask\n", irq);
0800
0801 if ( genirq_check(priv->genirq, irq) )
0802 return DRVMGR_EINVAL;
0803
0804 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0805
0806
0807 priv->irq->mask[0] |= (1<<irq);
0808
0809 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0810
0811 return DRVMGR_OK;
0812 }
0813
0814 int ambapp_rasta_io_int_mask(
0815 struct drvmgr_dev *dev,
0816 int irq)
0817 {
0818 struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0819 SPIN_IRQFLAGS(irqflags);
0820
0821 DBG("RASTA-IO IRQ %d: mask\n", irq);
0822
0823 if ( genirq_check(priv->genirq, irq) )
0824 return DRVMGR_EINVAL;
0825
0826 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0827
0828
0829 priv->irq->mask[0] &= ~(1<<irq);
0830
0831 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0832
0833 return DRVMGR_OK;
0834 }
0835
0836 int ambapp_rasta_io_int_clear(
0837 struct drvmgr_dev *dev,
0838 int irq)
0839 {
0840 struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0841
0842 if ( genirq_check(priv->genirq, irq) )
0843 return DRVMGR_EINVAL;
0844
0845 priv->irq->iclear = (1<<irq);
0846
0847 return DRVMGR_OK;
0848 }
0849
0850 int ambapp_rasta_io_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
0851 {
0852 struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0853
0854
0855 params->dev_prefix = &priv->prefix[5];
0856
0857 return 0;
0858 }
0859
0860 void gr_rasta_io_print_dev(struct drvmgr_dev *dev, int options)
0861 {
0862 struct gr_rasta_io_priv *priv = dev->priv;
0863 struct pci_dev_info *devinfo = priv->devinfo;
0864 uint32_t bar0, bar1, bar0_size, bar1_size;
0865
0866
0867 printf("--- GR-RASTA-IO [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
0868 PCI_DEV_EXPAND(priv->pcidev));
0869
0870 bar0 = devinfo->resources[0].address;
0871 bar0_size = devinfo->resources[0].size;
0872 bar1 = devinfo->resources[1].address;
0873 bar1_size = devinfo->resources[1].size;
0874
0875 printf(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0876 bar0, bar0 + bar0_size - 1);
0877 printf(" PCI BAR[1]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0878 bar1, bar1 + bar1_size - 1);
0879 printf(" IRQ REGS: 0x%" PRIxPTR "\n", (uintptr_t)priv->irq);
0880 printf(" IRQ: %d\n", devinfo->irq);
0881 printf(" PCI REVISION: %d\n", devinfo->rev);
0882 printf(" FREQ: %d Hz\n", priv->version->amba_freq_hz);
0883 printf(" IMASK: 0x%08x\n", priv->irq->mask[0]);
0884 printf(" IPEND: 0x%08x\n", priv->irq->ipend);
0885
0886
0887 if ( options & RASTA_IO_OPTIONS_AMBA ) {
0888 ambapp_print(&priv->abus, 10);
0889 }
0890
0891 #if 0
0892
0893 if ( options & RASTA_IO_OPTIONS_IRQ ) {
0894 int i;
0895 for(i=0; i<16; i++) {
0896 printf(" IRQ[%02d]: 0x%x, arg: 0x%x\n",
0897 i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
0898 }
0899 }
0900 #endif
0901 }
0902
0903 void gr_rasta_io_print(int options)
0904 {
0905 struct pci_drv_info *drv = &gr_rasta_io_info;
0906 struct drvmgr_dev *dev;
0907
0908 dev = drv->general.dev;
0909 while(dev) {
0910 gr_rasta_io_print_dev(dev, options);
0911 dev = dev->next_in_drv;
0912 }
0913 }