File indexing completed on 2025-05-11 08:24:07
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 <stdio.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041 #include <libcpu/byteorder.h>
0042 #include <libcpu/access.h>
0043 #include <rtems/bspIo.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/pcif.h>
0052
0053
0054
0055 #define SYSTEM_MAINMEM_START 0x40000000
0056
0057
0058
0059
0060 #ifndef PCIF_INTA_SYSIRQ
0061 #define PCIF_INTA_SYSIRQ 0xff
0062 #endif
0063 #ifndef PCIF_INTB_SYSIRQ
0064 #define PCIF_INTB_SYSIRQ 0xff
0065 #endif
0066 #ifndef PCIF_INTC_SYSIRQ
0067 #define PCIF_INTC_SYSIRQ 0xff
0068 #endif
0069 #ifndef PCIF_INTD_SYSIRQ
0070 #define PCIF_INTD_SYSIRQ 0xff
0071 #endif
0072
0073
0074
0075 #ifdef DEBUG
0076 #define DBG(x...) printk(x)
0077 #else
0078 #define DBG(x...)
0079 #endif
0080
0081
0082
0083
0084 struct pcif_regs {
0085 volatile unsigned int bars[4];
0086 volatile unsigned int bus;
0087 volatile unsigned int map_io;
0088 volatile unsigned int status;
0089 volatile unsigned int intr;
0090 int unused[(0x40-0x20)/4];
0091 volatile unsigned int maps[(0x80-0x40)/4];
0092 };
0093
0094
0095 #define HOST_TGT PCI_DEV(0xff, 0, 0)
0096
0097 struct pcif_priv *pcifpriv = NULL;
0098 static int pcif_minor = 0;
0099
0100
0101
0102
0103 unsigned char pcif_pci_irq_table[4] =
0104 {
0105 PCIF_INTA_SYSIRQ,
0106 PCIF_INTB_SYSIRQ,
0107 PCIF_INTC_SYSIRQ,
0108 PCIF_INTD_SYSIRQ
0109 };
0110
0111
0112 struct pcif_priv {
0113 struct drvmgr_dev *dev;
0114 struct pcif_regs *regs;
0115 int irq;
0116 int minor;
0117 int irq_mask;
0118
0119 unsigned int pci_area;
0120 unsigned int pci_area_end;
0121 unsigned int pci_io;
0122 unsigned int pci_conf;
0123 unsigned int pci_conf_end;
0124
0125 uint32_t devVend;
0126 uint32_t bar1_size;
0127
0128 struct drvmgr_map_entry maps_up[2];
0129 struct drvmgr_map_entry maps_down[2];
0130 struct pcibus_config config;
0131 };
0132
0133 int pcif_init1(struct drvmgr_dev *dev);
0134 int pcif_init3(struct drvmgr_dev *dev);
0135
0136
0137
0138 struct drvmgr_drv_ops pcif_ops =
0139 {
0140 .init = {pcif_init1, NULL, pcif_init3, NULL},
0141 .remove = NULL,
0142 .info = NULL
0143 };
0144
0145 struct amba_dev_id pcif_ids[] =
0146 {
0147 {VENDOR_GAISLER, GAISLER_PCIF},
0148 {0, 0}
0149 };
0150
0151 struct amba_drv_info pcif_info =
0152 {
0153 {
0154 DRVMGR_OBJ_DRV,
0155 NULL,
0156 NULL,
0157 DRIVER_AMBAPP_GAISLER_PCIF_ID,
0158 "PCIF_DRV",
0159 DRVMGR_BUS_TYPE_AMBAPP,
0160 &pcif_ops,
0161 NULL,
0162 0,
0163 sizeof(struct pcif_priv),
0164 },
0165 &pcif_ids[0]
0166 };
0167
0168 void pcif_register_drv(void)
0169 {
0170 DBG("Registering PCIF driver\n");
0171 drvmgr_drv_register(&pcif_info.general);
0172 }
0173
0174 static int pcif_cfg_r32(pci_dev_t dev, int ofs, uint32_t *val)
0175 {
0176 struct pcif_priv *priv = pcifpriv;
0177 volatile uint32_t *pci_conf;
0178 uint32_t devfn;
0179 int retval;
0180 int bus = PCI_DEV_BUS(dev);
0181
0182 if (ofs & 3)
0183 return PCISTS_EINVAL;
0184
0185 if (PCI_DEV_SLOT(dev) > 15) {
0186 *val = 0xffffffff;
0187 return PCISTS_OK;
0188 }
0189
0190
0191
0192
0193 if (dev == HOST_TGT)
0194 bus = devfn = 0;
0195 else if (bus == 0)
0196 devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
0197 else
0198 devfn = PCI_DEV_DEVFUNC(dev);
0199
0200
0201 priv->regs->bus = bus << 16;
0202
0203 pci_conf = (volatile uint32_t *)(priv->pci_conf | (devfn << 8) | ofs);
0204
0205 *val = *pci_conf;
0206
0207 if (priv->regs->status & 0x30000000) {
0208 *val = 0xffffffff;
0209 retval = PCISTS_MSTABRT;
0210 } else
0211 retval = PCISTS_OK;
0212
0213 DBG("pci_read: [%x:%x:%x] reg: 0x%x => addr: 0x%x, val: 0x%x\n",
0214 PCI_DEV_EXPAND(dev), ofs, pci_conf, *val);
0215
0216 return retval;
0217 }
0218
0219 static int pcif_cfg_r16(pci_dev_t dev, int ofs, uint16_t *val)
0220 {
0221 uint32_t v;
0222 int retval;
0223
0224 if (ofs & 1)
0225 return PCISTS_EINVAL;
0226
0227 retval = pcif_cfg_r32(dev, ofs & ~0x3, &v);
0228 *val = 0xffff & (v >> (8*(ofs & 0x3)));
0229
0230 return retval;
0231 }
0232
0233 static int pcif_cfg_r8(pci_dev_t dev, int ofs, uint8_t *val)
0234 {
0235 uint32_t v;
0236 int retval;
0237
0238 retval = pcif_cfg_r32(dev, ofs & ~0x3, &v);
0239
0240 *val = 0xff & (v >> (8*(ofs & 3)));
0241
0242 return retval;
0243 }
0244
0245 static int pcif_cfg_w32(pci_dev_t dev, int ofs, uint32_t val)
0246 {
0247 struct pcif_priv *priv = pcifpriv;
0248 volatile uint32_t *pci_conf;
0249 uint32_t devfn;
0250 int bus = PCI_DEV_BUS(dev);
0251
0252 if (ofs & ~0xfc)
0253 return PCISTS_EINVAL;
0254
0255 if (PCI_DEV_SLOT(dev) > 15)
0256 return PCISTS_MSTABRT;
0257
0258
0259
0260
0261 if (dev == HOST_TGT)
0262 bus = devfn = 0;
0263 else if (bus == 0)
0264 devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
0265 else
0266 devfn = PCI_DEV_DEVFUNC(dev);
0267
0268
0269 priv->regs->bus = bus << 16;
0270
0271 pci_conf = (volatile uint32_t *)(priv->pci_conf | (devfn << 8) | ofs);
0272
0273 *pci_conf = val;
0274
0275 DBG("pci_write - [%x:%x:%x] reg: 0x%x => addr: 0x%x, val: 0x%x\n",
0276 PCI_DEV_EXPAND(dev), ofs, pci_conf, value);
0277
0278 return PCISTS_OK;
0279 }
0280
0281 static int pcif_cfg_w16(pci_dev_t dev, int ofs, uint16_t val)
0282 {
0283 uint32_t v;
0284 int retval;
0285
0286 if (ofs & 1)
0287 return PCISTS_EINVAL;
0288
0289 retval = pcif_cfg_r32(dev, ofs & ~0x3, &v);
0290 if (retval != PCISTS_OK)
0291 return retval;
0292
0293 v = (v & ~(0xffff << (8*(ofs&3)))) | ((0xffff&val) << (8*(ofs&3)));
0294
0295 return pcif_cfg_w32(dev, ofs & ~0x3, v);
0296 }
0297
0298 static int pcif_cfg_w8(pci_dev_t dev, int ofs, uint8_t val)
0299 {
0300 uint32_t v;
0301 int retval;
0302
0303 retval = pcif_cfg_r32(dev, ofs & ~0x3, &v);
0304 if (retval != PCISTS_OK)
0305 return retval;
0306
0307 v = (v & ~(0xff << (8*(ofs&3)))) | ((0xff&val) << (8*(ofs&3)));
0308
0309 return pcif_cfg_w32(dev, ofs & ~0x3, v);
0310 }
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 static uint8_t pcif_bus0_irq_map(pci_dev_t dev, int irq_pin)
0323 {
0324 uint8_t sysIrqNr = 0;
0325 int irq_group;
0326
0327 if ( (irq_pin >= 1) && (irq_pin <= 4) ) {
0328
0329 irq_group = PCI_DEV_SLOT(dev) & 0x3;
0330 irq_pin = ((irq_pin - 1) + irq_group) & 0x3;
0331
0332 sysIrqNr = pcif_pci_irq_table[irq_pin];
0333 }
0334 return sysIrqNr;
0335 }
0336
0337 static int pcif_translate(uint32_t *address, int type, int dir)
0338 {
0339
0340 return 0;
0341 }
0342
0343 extern struct pci_memreg_ops pci_memreg_sparc_be_ops;
0344
0345
0346 struct pci_access_drv pcif_access_drv = {
0347 .cfg =
0348 {
0349 pcif_cfg_r8,
0350 pcif_cfg_r16,
0351 pcif_cfg_r32,
0352 pcif_cfg_w8,
0353 pcif_cfg_w16,
0354 pcif_cfg_w32,
0355 },
0356 .io =
0357 {
0358 _ld8,
0359 _ld_be16,
0360 _ld_be32,
0361 _st8,
0362 _st_be16,
0363 _st_be32,
0364 },
0365 .memreg = &pci_memreg_sparc_be_ops,
0366 .translate = pcif_translate,
0367 };
0368
0369
0370
0371
0372 static int pcif_hw_init(struct pcif_priv *priv)
0373 {
0374 struct pcif_regs *regs;
0375 uint32_t data, size;
0376 int mst;
0377 pci_dev_t host = HOST_TGT;
0378
0379 regs = priv->regs;
0380
0381
0382 regs->intr = 0;
0383
0384
0385 pcif_cfg_r32(host, PCIR_VENDOR, &priv->devVend);
0386
0387
0388 for ( mst=0; mst<16; mst++) {
0389 regs->maps[mst] = priv->pci_area;
0390
0391
0392 if ( regs->maps[mst] != priv->pci_area )
0393 break;
0394 }
0395
0396
0397
0398
0399 regs->bars[0] = SYSTEM_MAINMEM_START;
0400 regs->bars[1] = 0;
0401 regs->bars[2] = 0;
0402 regs->bars[3] = 0;
0403
0404
0405 pcif_cfg_w32(host, PCIR_BAR(1), 0xffffffff);
0406 pcif_cfg_r32(host, PCIR_BAR(1), &size);
0407 priv->bar1_size = (~(size & ~0xf)) + 1;
0408
0409 pcif_cfg_w32(host, PCIR_BAR(0), 0);
0410 pcif_cfg_w32(host, PCIR_BAR(1), SYSTEM_MAINMEM_START);
0411 pcif_cfg_w32(host, PCIR_BAR(2), 0);
0412 pcif_cfg_w32(host, PCIR_BAR(3), 0);
0413 pcif_cfg_w32(host, PCIR_BAR(4), 0);
0414 pcif_cfg_w32(host, PCIR_BAR(5), 0);
0415
0416
0417 pcif_cfg_r32(host, PCIR_COMMAND, &data);
0418 data |= (PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
0419 pcif_cfg_w32(host, PCIR_COMMAND, data);
0420
0421
0422 return 0;
0423 }
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434 static int pcif_init(struct pcif_priv *priv)
0435 {
0436 struct ambapp_apb_info *apb;
0437 struct ambapp_ahb_info *ahb;
0438 int pin;
0439 union drvmgr_key_value *value;
0440 char keyname[6];
0441 struct amba_dev_info *ainfo = priv->dev->businfo;
0442
0443
0444 apb = ainfo->info.apb_slv;
0445 ahb = ainfo->info.ahb_slv;
0446
0447
0448 priv->irq = apb->common.irq;
0449 priv->regs = (struct pcif_regs *)apb->start;
0450
0451
0452
0453
0454
0455
0456 priv->pci_area = ahb->start[0];
0457 priv->pci_area_end = ahb->start[0] + ahb->mask[0];
0458 priv->pci_io = ahb->start[1];
0459 priv->pci_conf = ahb->start[1] + (ahb->mask[1] >> 1);
0460 priv->pci_conf_end = ahb->start[1] + ahb->mask[1];
0461
0462
0463
0464
0465 if ( (priv->pci_io > priv->pci_area) && (priv->pci_io < (priv->pci_area_end-1)) ) {
0466 priv->pci_area_end = priv->pci_io;
0467 }
0468
0469
0470
0471
0472 strcpy(keyname, "INTX#");
0473 for (pin=1; pin<5; pin++) {
0474 if ( pcif_pci_irq_table[pin-1] == 0xff ) {
0475 pcif_pci_irq_table[pin-1] = priv->irq;
0476
0477
0478 keyname[3] = 'A' + (pin-1);
0479 value = drvmgr_dev_key_get(priv->dev, keyname, DRVMGR_KT_INT);
0480 if ( value )
0481 pcif_pci_irq_table[pin-1] = value->i;
0482 }
0483 }
0484
0485 priv->irq_mask = 0xf;
0486 value = drvmgr_dev_key_get(priv->dev, "", DRVMGR_KT_INT);
0487 if ( value )
0488 priv->irq_mask = value->i & 0xf;
0489
0490
0491 if ( priv->regs->status & 0x00000001 ) {
0492
0493 return -2;
0494 }
0495
0496
0497 if ( pcif_hw_init(priv) ) {
0498 return -3;
0499 }
0500
0501
0502 priv->maps_down[0].name = "AMBA -> PCI MEM Window";
0503 priv->maps_down[0].size = priv->pci_area_end - priv->pci_area;
0504 priv->maps_down[0].from_adr = (void *)priv->pci_area;
0505 priv->maps_down[0].to_adr = (void *)priv->pci_area;
0506
0507 priv->maps_down[1].size = 0;
0508
0509
0510 priv->maps_up[0].name = "Target BAR1 -> AMBA";
0511 priv->maps_up[0].size = priv->bar1_size;
0512 priv->maps_up[0].from_adr = (void *)SYSTEM_MAINMEM_START;
0513 priv->maps_up[0].to_adr = (void *)SYSTEM_MAINMEM_START;
0514
0515 priv->maps_up[1].size = 0;
0516
0517 return 0;
0518 }
0519
0520
0521
0522
0523 int pcif_init1(struct drvmgr_dev *dev)
0524 {
0525 struct pcif_priv *priv;
0526 struct pci_auto_setup pcif_auto_cfg;
0527
0528 DBG("PCIF[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0529
0530 if ( pcif_minor != 0 ) {
0531 printk("Driver only supports one PCI core\n");
0532 return DRVMGR_FAIL;
0533 }
0534
0535 priv = dev->priv;
0536 if ( !priv )
0537 return DRVMGR_NOMEM;
0538
0539 dev->priv = priv;
0540 priv->dev = dev;
0541 priv->minor = pcif_minor++;
0542
0543 pcifpriv = priv;
0544 if ( pcif_init(priv) ) {
0545 printk("Failed to initialize PCIF driver\n");
0546 free(priv);
0547 dev->priv = NULL;
0548 return DRVMGR_FAIL;
0549 }
0550
0551
0552 pci_endian = PCI_BIG_ENDIAN;
0553
0554
0555
0556 if (pci_access_drv_register(&pcif_access_drv)) {
0557
0558 return DRVMGR_FAIL;
0559 }
0560
0561
0562 pcif_auto_cfg.options = 0;
0563 pcif_auto_cfg.mem_start = 0;
0564 pcif_auto_cfg.mem_size = 0;
0565 pcif_auto_cfg.memio_start = priv->pci_area;
0566 pcif_auto_cfg.memio_size = priv->pci_area_end - priv->pci_area;
0567 pcif_auto_cfg.io_start = priv->pci_io;
0568 pcif_auto_cfg.io_size = priv->pci_conf - priv->pci_io;
0569 pcif_auto_cfg.irq_map = pcif_bus0_irq_map;
0570 pcif_auto_cfg.irq_route = NULL;
0571 pci_config_register(&pcif_auto_cfg);
0572
0573 if (pci_config_init()) {
0574
0575 return DRVMGR_FAIL;
0576 }
0577
0578 priv->config.maps_down = &priv->maps_down[0];
0579 priv->config.maps_up = &priv->maps_up[0];
0580 return pcibus_register(dev, &priv->config);
0581 }
0582
0583 int pcif_init3(struct drvmgr_dev *dev)
0584 {
0585 struct pcif_priv *priv = dev->priv;
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602 priv->regs->intr = priv->irq_mask;
0603
0604 return DRVMGR_OK;
0605 }