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
0038 #include <stdlib.h>
0039 #include <stdio.h>
0040 #include <string.h>
0041 #include <rtems/bspIo.h>
0042 #include <libcpu/byteorder.h>
0043 #include <libcpu/access.h>
0044 #include <pci.h>
0045 #include <pci/cfg.h>
0046
0047 #include <drvmgr/drvmgr.h>
0048 #include <grlib/ambapp_bus.h>
0049 #include <grlib/ambapp.h>
0050 #include <drvmgr/pci_bus.h>
0051 #include <grlib/grpci.h>
0052
0053 #define DMAPCI_ADDR 0x80000500
0054
0055
0056 #define SYSTEM_MAINMEM_START 0x40000000
0057
0058
0059 #define DEFAULT_BT_ENABLED 0
0060
0061
0062
0063
0064 #ifndef GRPCI_INTA_SYSIRQ
0065 #define GRPCI_INTA_SYSIRQ 0xff
0066 #endif
0067 #ifndef GRPCI_INTB_SYSIRQ
0068 #define GRPCI_INTB_SYSIRQ 0xff
0069 #endif
0070 #ifndef GRPCI_INTC_SYSIRQ
0071 #define GRPCI_INTC_SYSIRQ 0xff
0072 #endif
0073 #ifndef GRPCI_INTD_SYSIRQ
0074 #define GRPCI_INTD_SYSIRQ 0xff
0075 #endif
0076
0077 #define PAGE0_BTEN_BIT 0
0078 #define PAGE0_BTEN (1<<PAGE0_BTEN_BIT)
0079
0080 #define CFGSTAT_HOST_BIT 13
0081 #define CFGSTAT_HOST (1<<CFGSTAT_HOST_BIT)
0082
0083
0084
0085 #ifdef DEBUG
0086 #define DBG(x...) printk(x)
0087 #else
0088 #define DBG(x...)
0089 #endif
0090
0091
0092
0093
0094 struct grpci_regs {
0095 volatile unsigned int cfg_stat;
0096 volatile unsigned int bar0;
0097 volatile unsigned int page0;
0098 volatile unsigned int bar1;
0099 volatile unsigned int page1;
0100 volatile unsigned int iomap;
0101 volatile unsigned int stat_cmd;
0102 volatile unsigned int irq;
0103 };
0104
0105 #define HOST_TGT PCI_DEV(0xff, 0, 0)
0106
0107 struct grpci_priv *grpcipriv = NULL;
0108 static int grpci_minor = 0;
0109 static unsigned int *pcidma = (unsigned int *)DMAPCI_ADDR;
0110
0111
0112
0113
0114 unsigned char grpci_pci_irq_table[4] =
0115 {
0116 GRPCI_INTA_SYSIRQ,
0117 GRPCI_INTB_SYSIRQ,
0118 GRPCI_INTC_SYSIRQ,
0119 GRPCI_INTD_SYSIRQ
0120 };
0121
0122
0123 struct grpci_priv {
0124 struct drvmgr_dev *dev;
0125 struct grpci_regs *regs;
0126 int irq;
0127 int minor;
0128
0129 uint32_t bar1_pci_adr;
0130 uint32_t bar1_size;
0131
0132 int bt_enabled;
0133 unsigned int pci_area;
0134 unsigned int pci_area_end;
0135 unsigned int pci_io;
0136 unsigned int pci_conf;
0137 unsigned int pci_conf_end;
0138
0139 uint32_t devVend;
0140
0141 struct drvmgr_map_entry maps_up[2];
0142 struct drvmgr_map_entry maps_down[2];
0143 struct pcibus_config config;
0144 };
0145
0146 int grpci_init1(struct drvmgr_dev *dev);
0147
0148
0149
0150 struct drvmgr_drv_ops grpci_ops =
0151 {
0152 .init = {grpci_init1, NULL, NULL, NULL},
0153 .remove = NULL,
0154 .info = NULL
0155 };
0156
0157 struct amba_dev_id grpci_ids[] =
0158 {
0159 {VENDOR_GAISLER, GAISLER_PCIFBRG},
0160 {0, 0}
0161 };
0162
0163 struct amba_drv_info grpci_info =
0164 {
0165 {
0166 DRVMGR_OBJ_DRV,
0167 NULL,
0168 NULL,
0169 DRIVER_AMBAPP_GAISLER_GRPCI_ID,
0170 "GRPCI_DRV",
0171 DRVMGR_BUS_TYPE_AMBAPP,
0172 &grpci_ops,
0173 NULL,
0174 0,
0175 sizeof(struct grpci_priv),
0176 },
0177 &grpci_ids[0]
0178 };
0179
0180 void grpci_register_drv(void)
0181 {
0182 DBG("Registering GRPCI driver\n");
0183 drvmgr_drv_register(&grpci_info.general);
0184 }
0185
0186 static int grpci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *val)
0187 {
0188 struct grpci_priv *priv = grpcipriv;
0189 volatile uint32_t *pci_conf;
0190 uint32_t devfn;
0191 int retval;
0192 int bus = PCI_DEV_BUS(dev);
0193
0194 if (ofs & 3)
0195 return PCISTS_EINVAL;
0196
0197 if (PCI_DEV_SLOT(dev) > 15) {
0198 *val = 0xffffffff;
0199 return PCISTS_OK;
0200 }
0201
0202
0203
0204
0205 if (dev == HOST_TGT)
0206 bus = devfn = 0;
0207 else if (bus == 0)
0208 devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
0209 else
0210 devfn = PCI_DEV_DEVFUNC(dev);
0211
0212
0213 priv->regs->cfg_stat = (priv->regs->cfg_stat & ~(0xf<<23)) | (bus<<23);
0214
0215 pci_conf = (volatile uint32_t *)(priv->pci_conf | (devfn << 8) | ofs);
0216
0217 if (priv->bt_enabled) {
0218 *val = CPU_swap_u32(*pci_conf);
0219 } else {
0220 *val = *pci_conf;
0221 }
0222
0223 if (priv->regs->cfg_stat & 0x100) {
0224 *val = 0xffffffff;
0225 retval = PCISTS_MSTABRT;
0226 } else
0227 retval = PCISTS_OK;
0228
0229 DBG("pci_read: [%x:%x:%x] reg: 0x%x => addr: 0x%x, val: 0x%x\n",
0230 PCI_DEV_EXPAND(dev), ofs, pci_conf, *val);
0231
0232 return retval;
0233 }
0234
0235
0236 static int grpci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *val)
0237 {
0238 uint32_t v;
0239 int retval;
0240
0241 if (ofs & 1)
0242 return PCISTS_EINVAL;
0243
0244 retval = grpci_cfg_r32(dev, ofs & ~0x3, &v);
0245 *val = 0xffff & (v >> (8*(ofs & 0x3)));
0246
0247 return retval;
0248 }
0249
0250 static int grpci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *val)
0251 {
0252 uint32_t v;
0253 int retval;
0254
0255 retval = grpci_cfg_r32(dev, ofs & ~0x3, &v);
0256
0257 *val = 0xff & (v >> (8*(ofs & 3)));
0258
0259 return retval;
0260 }
0261
0262 static int grpci_cfg_w32(pci_dev_t dev, int ofs, uint32_t val)
0263 {
0264 struct grpci_priv *priv = grpcipriv;
0265 volatile uint32_t *pci_conf;
0266 uint32_t value, devfn = PCI_DEV_DEVFUNC(dev);
0267 int bus = PCI_DEV_BUS(dev);
0268
0269 if (ofs & 0x3)
0270 return PCISTS_EINVAL;
0271
0272 if (PCI_DEV_SLOT(dev) > 15)
0273 return PCISTS_MSTABRT;
0274
0275
0276
0277
0278 if (dev == HOST_TGT)
0279 bus = devfn = 0;
0280 else if (bus == 0)
0281 devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
0282 else
0283 devfn = PCI_DEV_DEVFUNC(dev);
0284
0285
0286 priv->regs->cfg_stat = (priv->regs->cfg_stat & ~(0xf<<23)) | (bus<<23);
0287
0288 pci_conf = (volatile uint32_t *)(priv->pci_conf | (devfn << 8) | ofs);
0289
0290 if ( priv->bt_enabled ) {
0291 value = CPU_swap_u32(val);
0292 } else {
0293 value = val;
0294 }
0295
0296 *pci_conf = value;
0297
0298 DBG("pci_write - [%x:%x:%x] reg: 0x%x => addr: 0x%x, val: 0x%x\n",
0299 PCI_DEV_EXPAND(dev), ofs, pci_conf, value);
0300
0301 return PCISTS_OK;
0302 }
0303
0304 static int grpci_cfg_w16(pci_dev_t dev, int ofs, uint16_t val)
0305 {
0306 uint32_t v;
0307 int retval;
0308
0309 if (ofs & 1)
0310 return PCISTS_EINVAL;
0311
0312 retval = grpci_cfg_r32(dev, ofs & ~0x3, &v);
0313 if (retval != PCISTS_OK)
0314 return retval;
0315
0316 v = (v & ~(0xffff << (8*(ofs&3)))) | ((0xffff&val) << (8*(ofs&3)));
0317
0318 return grpci_cfg_w32(dev, ofs & ~0x3, v);
0319 }
0320
0321 static int grpci_cfg_w8(pci_dev_t dev, int ofs, uint8_t val)
0322 {
0323 uint32_t v;
0324 int retval;
0325
0326 retval = grpci_cfg_r32(dev, ofs & ~0x3, &v);
0327 if (retval != PCISTS_OK)
0328 return retval;
0329
0330 v = (v & ~(0xff << (8*(ofs&3)))) | ((0xff&val) << (8*(ofs&3)));
0331
0332 return grpci_cfg_w32(dev, ofs & ~0x3, v);
0333 }
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344 static uint8_t grpci_bus0_irq_map(pci_dev_t dev, int irq_pin)
0345 {
0346 uint8_t sysIrqNr = 0;
0347 int irq_group;
0348
0349 if ( (irq_pin >= 1) && (irq_pin <= 4) ) {
0350
0351 irq_group = PCI_DEV_SLOT(dev) & 0x3;
0352 irq_pin = ((irq_pin - 1) + irq_group) & 0x3;
0353
0354 sysIrqNr = grpci_pci_irq_table[irq_pin];
0355 }
0356 return sysIrqNr;
0357 }
0358
0359 static int grpci_translate(uint32_t *address, int type, int dir)
0360 {
0361 uint32_t adr;
0362 struct grpci_priv *priv = grpcipriv;
0363
0364 if (type == 1) {
0365
0366 if (dir != 0) {
0367
0368
0369
0370 return -1;
0371 }
0372
0373
0374
0375
0376
0377 adr = *(uint32_t *)address;
0378 if (adr < priv->pci_io || adr >= priv->pci_conf)
0379 return -1;
0380 } else {
0381
0382
0383
0384
0385 adr = *(uint32_t *)address;
0386 if (dir == 0) {
0387
0388
0389
0390
0391 if (adr < priv->pci_area || adr >= priv->pci_area_end)
0392 return -1;
0393 } else {
0394
0395
0396
0397
0398
0399
0400
0401 if (adr < priv->bar1_pci_adr ||
0402 adr >= (priv->bar1_pci_adr + priv->bar1_size))
0403 return -1;
0404 }
0405 }
0406
0407 return 0;
0408 }
0409
0410 extern struct pci_memreg_ops pci_memreg_sparc_le_ops;
0411 extern struct pci_memreg_ops pci_memreg_sparc_be_ops;
0412
0413
0414 struct pci_access_drv grpci_access_drv = {
0415 .cfg =
0416 {
0417 grpci_cfg_r8,
0418 grpci_cfg_r16,
0419 grpci_cfg_r32,
0420 grpci_cfg_w8,
0421 grpci_cfg_w16,
0422 grpci_cfg_w32,
0423 },
0424 .io =
0425 {
0426 _ld8,
0427 _ld_le16,
0428 _ld_le32,
0429 _st8,
0430 _st_le16,
0431 _st_le32,
0432 },
0433 .memreg = &pci_memreg_sparc_le_ops,
0434 .translate = grpci_translate,
0435 };
0436
0437 struct pci_io_ops grpci_io_ops_be =
0438 {
0439 _ld8,
0440 _ld_be16,
0441 _ld_be32,
0442 _st8,
0443 _st_be16,
0444 _st_be32,
0445 };
0446
0447 static int grpci_hw_init(struct grpci_priv *priv)
0448 {
0449 volatile unsigned int *mbar0, *page0;
0450 uint32_t data, addr, mbar0size;
0451 pci_dev_t host = HOST_TGT;
0452
0453 mbar0 = (volatile unsigned int *)priv->pci_area;
0454
0455 if ( !priv->bt_enabled && ((priv->regs->page0 & PAGE0_BTEN) == PAGE0_BTEN) ) {
0456
0457 grpci_cfg_w32(host, PCIR_BAR(0), 0xffffffff);
0458 grpci_cfg_r32(host, PCIR_BAR(0), &addr);
0459
0460 grpci_cfg_w32(host, PCIR_BAR(0),
0461 CPU_swap_u32(0x80000000));
0462
0463 addr = (~CPU_swap_u32(addr)+1)>>1;
0464 mbar0size = addr*2;
0465 DBG("GRPCI: Size of MBAR0: 0x%x, MBAR0: 0x%x(lower) 0x%x(upper)\n",mbar0size,((unsigned int)mbar0),((unsigned int)mbar0)+mbar0size/2);
0466 page0 = &mbar0[mbar0size/8];
0467 DBG("GRPCI: PAGE0 reg address: 0x%x (0x%x)\n",((unsigned int)mbar0)+mbar0size/2,page0);
0468 priv->regs->cfg_stat = (priv->regs->cfg_stat & (~0xf0000000)) | 0x80000000;
0469 *page0 = 0<<PAGE0_BTEN_BIT;
0470 }
0471
0472
0473 grpci_cfg_r32(host, PCIR_VENDOR, &priv->devVend);
0474
0475
0476 priv->regs->cfg_stat = (priv->regs->cfg_stat & 0x0fffffff) | priv->pci_area;
0477
0478
0479 grpci_cfg_w32(host, PCIR_BAR(1), 0xffffffff);
0480 grpci_cfg_r32(host, PCIR_BAR(1), &addr);
0481 priv->bar1_size = (~(addr & ~0xf)) + 1;
0482
0483
0484 priv->bar1_pci_adr &= ~(priv->bar1_size - 1);
0485 grpci_cfg_w32(host, PCIR_BAR(1), priv->bar1_pci_adr);
0486 priv->regs->page1 = priv->bar1_pci_adr;
0487
0488
0489 priv->regs->iomap = priv->pci_io & 0xffff0000;
0490
0491
0492
0493
0494
0495 grpci_cfg_w8(host, PCIR_CACHELNSZ, 0xff);
0496 grpci_cfg_w8(host, PCIR_LATTIMER, 0x40);
0497
0498
0499 grpci_cfg_r32(host, PCIR_COMMAND, &data);
0500 data |= (PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
0501 grpci_cfg_w32(host, PCIR_COMMAND, data);
0502
0503
0504
0505
0506 priv->regs->irq = 0xf0000;
0507
0508
0509 return 0;
0510 }
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521 static int grpci_init(struct grpci_priv *priv)
0522 {
0523 struct ambapp_apb_info *apb;
0524 struct ambapp_ahb_info *ahb;
0525 int pin;
0526 union drvmgr_key_value *value;
0527 char keyname[6];
0528 struct amba_dev_info *ainfo = priv->dev->businfo;
0529
0530
0531 apb = ainfo->info.apb_slv;
0532 ahb = ainfo->info.ahb_slv;
0533
0534
0535 priv->irq = apb->common.irq;
0536 priv->regs = (struct grpci_regs *)apb->start;
0537 priv->bt_enabled = DEFAULT_BT_ENABLED;
0538
0539
0540
0541
0542
0543
0544 priv->pci_area = ahb->start[0];
0545 priv->pci_area_end = ahb->start[0] + ahb->mask[0];
0546 priv->pci_io = ahb->start[1];
0547 priv->pci_conf = ahb->start[1] + (ahb->mask[1] >> 1);
0548 priv->pci_conf_end = ahb->start[1] + ahb->mask[1];
0549
0550
0551
0552
0553 if ( (priv->pci_io > priv->pci_area) && (priv->pci_io < (priv->pci_area_end-1)) ) {
0554 priv->pci_area_end = priv->pci_io;
0555 }
0556
0557
0558
0559
0560 strcpy(keyname, "INTX#");
0561 for (pin=1; pin<5; pin++) {
0562 if ( grpci_pci_irq_table[pin-1] == 0xff ) {
0563 grpci_pci_irq_table[pin-1] = priv->irq;
0564
0565
0566 keyname[3] = 'A' + (pin-1);
0567 value = drvmgr_dev_key_get(priv->dev, keyname, DRVMGR_KT_INT);
0568 if ( value )
0569 grpci_pci_irq_table[pin-1] = value->i;
0570 }
0571 }
0572
0573
0574 value = drvmgr_dev_key_get(priv->dev, "byteTwisting", DRVMGR_KT_INT);
0575 if ( value )
0576 priv->bt_enabled = value->i;
0577
0578
0579
0580
0581 value = drvmgr_dev_key_get(priv->dev, "tgtbar1", DRVMGR_KT_INT);
0582 if (value)
0583 priv->bar1_pci_adr = value->i;
0584 else
0585 priv->bar1_pci_adr = SYSTEM_MAINMEM_START;
0586
0587
0588 if ( !(priv->regs->cfg_stat & CFGSTAT_HOST) ) {
0589
0590 return -2;
0591 }
0592
0593
0594 if ( grpci_hw_init(priv) ) {
0595 return -3;
0596 }
0597
0598
0599 priv->maps_down[0].name = "AMBA -> PCI MEM Window";
0600 priv->maps_down[0].size = priv->pci_area_end - priv->pci_area;
0601 priv->maps_down[0].from_adr = (void *)priv->pci_area;
0602 priv->maps_down[0].to_adr = (void *)priv->pci_area;
0603
0604 priv->maps_down[1].size = 0;
0605
0606
0607 priv->maps_up[0].name = "Target BAR1 -> AMBA";
0608 priv->maps_up[0].size = priv->bar1_size;
0609 priv->maps_up[0].from_adr = (void *)priv->bar1_pci_adr;
0610 priv->maps_up[0].to_adr = (void *)priv->bar1_pci_adr;
0611
0612 priv->maps_up[1].size = 0;
0613
0614 return 0;
0615 }
0616
0617
0618
0619
0620 int grpci_init1(struct drvmgr_dev *dev)
0621 {
0622 int status;
0623 struct grpci_priv *priv;
0624 struct pci_auto_setup grpci_auto_cfg;
0625
0626 DBG("GRPCI[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0627
0628 if ( grpci_minor != 0 ) {
0629 DBG("Driver only supports one PCI core\n");
0630 return DRVMGR_FAIL;
0631 }
0632
0633 if ( (strcmp(dev->parent->dev->drv->name, "AMBAPP_GRLIB_DRV") != 0) &&
0634 (strcmp(dev->parent->dev->drv->name, "AMBAPP_LEON2_DRV") != 0) ) {
0635
0636 return DRVMGR_FAIL;
0637 }
0638
0639 priv = dev->priv;
0640 if ( !priv )
0641 return DRVMGR_NOMEM;
0642
0643 priv->dev = dev;
0644 priv->minor = grpci_minor++;
0645
0646 grpcipriv = priv;
0647 status = grpci_init(priv);
0648 if (status) {
0649 printk("Failed to initialize grpci driver %d\n", status);
0650 return DRVMGR_FAIL;
0651 }
0652
0653
0654
0655
0656 if (priv->bt_enabled == 0) {
0657
0658 pci_endian = PCI_BIG_ENDIAN;
0659
0660 memcpy(&grpci_access_drv.io, &grpci_io_ops_be,
0661 sizeof(grpci_io_ops_be));
0662 grpci_access_drv.memreg = &pci_memreg_sparc_be_ops;
0663 }
0664
0665 if (pci_access_drv_register(&grpci_access_drv)) {
0666
0667 return DRVMGR_FAIL;
0668 }
0669
0670
0671 grpci_auto_cfg.options = 0;
0672 grpci_auto_cfg.mem_start = 0;
0673 grpci_auto_cfg.mem_size = 0;
0674 grpci_auto_cfg.memio_start = priv->pci_area;
0675 grpci_auto_cfg.memio_size = priv->pci_area_end - priv->pci_area;
0676 grpci_auto_cfg.io_start = priv->pci_io;
0677 grpci_auto_cfg.io_size = priv->pci_conf - priv->pci_io;
0678 grpci_auto_cfg.irq_map = grpci_bus0_irq_map;
0679 grpci_auto_cfg.irq_route = NULL;
0680 pci_config_register(&grpci_auto_cfg);
0681
0682 if (pci_config_init()) {
0683
0684 return DRVMGR_FAIL;
0685 }
0686
0687 priv->config.maps_down = &priv->maps_down[0];
0688 priv->config.maps_up = &priv->maps_up[0];
0689 return pcibus_register(dev, &priv->config);
0690 }
0691
0692
0693 int grpci_dma_to_pci(
0694 unsigned int ahb_addr,
0695 unsigned int pci_addr,
0696 unsigned int len)
0697 {
0698 int ret = 0;
0699
0700 pcidma[0] = 0x82;
0701 pcidma[1] = ahb_addr;
0702 pcidma[2] = pci_addr;
0703 pcidma[3] = len;
0704 pcidma[0] = 0x83;
0705
0706 while ( (pcidma[0] & 0x4) == 0)
0707 ;
0708
0709 if (pcidma[0] & 0x8) {
0710 ret = -1;
0711 }
0712
0713 pcidma[0] |= 0xC;
0714 return ret;
0715
0716 }
0717
0718 int grpci_dma_from_pci(
0719 unsigned int ahb_addr,
0720 unsigned int pci_addr,
0721 unsigned int len)
0722 {
0723 int ret = 0;
0724
0725 pcidma[0] = 0x80;
0726 pcidma[1] = ahb_addr;
0727 pcidma[2] = pci_addr;
0728 pcidma[3] = len;
0729 pcidma[0] = 0x81;
0730
0731 while ( (pcidma[0] & 0x4) == 0)
0732 ;
0733
0734 if (pcidma[0] & 0x8) {
0735 ret = -1;
0736 }
0737
0738 pcidma[0] |= 0xC;
0739 return ret;
0740
0741 }