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
0049
0050
0051
0052 #include <rtems/bspIo.h>
0053 #include <stdlib.h>
0054 #include <string.h>
0055 #include <stdio.h>
0056 #include <libcpu/byteorder.h>
0057 #include <libcpu/access.h>
0058 #include <pci.h>
0059 #include <pci/cfg.h>
0060
0061 #include <drvmgr/drvmgr.h>
0062 #include <drvmgr/pci_bus.h>
0063 #include <drvmgr/leon2_amba_bus.h>
0064
0065 #include <bsp/at697_pci.h>
0066 #include <leon.h>
0067
0068
0069
0070 #define SYSTEM_MAINMEM_START 0x40000000
0071 #define SYSTEM_MAINMEM_START2 0x60000000
0072
0073
0074
0075
0076 #ifndef AT697_INTA_SYSIRQ
0077 #define AT697_INTA_SYSIRQ 0xff
0078 #endif
0079 #ifndef AT697_INTB_SYSIRQ
0080 #define AT697_INTB_SYSIRQ 0xff
0081 #endif
0082 #ifndef AT697_INTC_SYSIRQ
0083 #define AT697_INTC_SYSIRQ 0xff
0084 #endif
0085 #ifndef AT697_INTD_SYSIRQ
0086 #define AT697_INTD_SYSIRQ 0xff
0087 #endif
0088
0089 #ifndef AT697_INTA_PIO
0090 #define AT697_INTA_PIO 0xff
0091 #endif
0092 #ifndef AT697_INTB_PIO
0093 #define AT697_INTB_PIO 0xff
0094 #endif
0095 #ifndef AT697_INTC_PIO
0096 #define AT697_INTC_PIO 0xff
0097 #endif
0098 #ifndef AT697_INTD_PIO
0099 #define AT697_INTD_PIO 0xff
0100 #endif
0101
0102
0103
0104 #define AT697_PCI_REG_ADR 0x80000100
0105
0106
0107 #define PCI_MEM_START 0xa0000000
0108 #define PCI_MEM_END 0xf0000000
0109 #define PCI_MEM_SIZE (PCI_MEM_END - PCI_MEM_START)
0110
0111
0112
0113 #ifdef DEBUG
0114 #define DBG(x...) printf(x)
0115 #else
0116 #define DBG(x...)
0117 #endif
0118
0119 struct at697pci_regs {
0120 volatile unsigned int pciid1;
0121 volatile unsigned int pcisc;
0122 volatile unsigned int pciid2;
0123 volatile unsigned int pcibhlc;
0124 volatile unsigned int mbar1;
0125 volatile unsigned int mbar2;
0126 volatile unsigned int iobar3;
0127 volatile unsigned int dummy1[4];
0128 volatile unsigned int pcisid;
0129 volatile unsigned int dummy2;
0130 volatile unsigned int pcicp;
0131 volatile unsigned int dummy3;
0132 volatile unsigned int pcili;
0133 volatile unsigned int pcirt;
0134 volatile unsigned int pcicw;
0135 volatile unsigned int pcisa;
0136 volatile unsigned int pciiw;
0137 volatile unsigned int pcidma;
0138 volatile unsigned int pciis;
0139 volatile unsigned int pciic;
0140 volatile unsigned int pcitpa;
0141 volatile unsigned int pcitsc;
0142 volatile unsigned int pciite;
0143 volatile unsigned int pciitp;
0144 volatile unsigned int pciitf;
0145 volatile unsigned int pcid;
0146 volatile unsigned int pcibe;
0147 volatile unsigned int pcidmaa;
0148 };
0149
0150
0151
0152
0153 unsigned char at697_pci_irq_table[4] =
0154 {
0155 AT697_INTA_SYSIRQ,
0156 AT697_INTB_SYSIRQ,
0157 AT697_INTC_SYSIRQ,
0158 AT697_INTD_SYSIRQ
0159 };
0160
0161
0162
0163
0164
0165
0166
0167 unsigned char at697_pci_irq_pio_table[4] =
0168 {
0169 AT697_INTA_PIO,
0170 AT697_INTB_PIO,
0171 AT697_INTC_PIO,
0172 AT697_INTD_PIO
0173 };
0174
0175
0176 struct at697pci_priv {
0177 struct drvmgr_dev *dev;
0178 struct at697pci_regs *regs;
0179 int minor;
0180
0181 uint32_t bar1_pci_adr;
0182 uint32_t bar2_pci_adr;
0183
0184 struct drvmgr_map_entry maps_up[3];
0185 struct drvmgr_map_entry maps_down[2];
0186 struct pcibus_config config;
0187 };
0188
0189 struct at697pci_priv *at697pcipriv = NULL;
0190 static int at697pci_minor = 0;
0191
0192 int at697pci_init1(struct drvmgr_dev *dev);
0193 int at697pci_init2(struct drvmgr_dev *dev);
0194
0195
0196
0197 struct drvmgr_drv_ops at697pci_ops =
0198 {
0199 .init = {at697pci_init1, at697pci_init2, NULL, NULL},
0200 .remove = NULL,
0201 .info = NULL
0202 };
0203
0204 struct leon2_amba_dev_id at697pci_ids[] =
0205 {
0206 {LEON2_AMBA_AT697PCI_ID},
0207 {0}
0208 };
0209
0210 struct leon2_amba_drv_info at697pci_info =
0211 {
0212 {
0213 DRVMGR_OBJ_DRV,
0214 NULL,
0215 NULL,
0216 DRIVER_LEON2_AMBA_AT697PCI,
0217 "AT697PCI_DRV",
0218 DRVMGR_BUS_TYPE_LEON2_AMBA,
0219 &at697pci_ops,
0220 NULL,
0221 0,
0222 sizeof(struct at697pci_priv),
0223 },
0224 &at697pci_ids[0]
0225 };
0226
0227 void at697pci_register_drv(void)
0228 {
0229 DBG("Registering AT697 PCI driver\n");
0230 drvmgr_drv_register(&at697pci_info.general);
0231 }
0232
0233
0234
0235
0236
0237 static int at697pci_cfg_r32(pci_dev_t dev, int offset, uint32_t *val)
0238 {
0239 struct at697pci_regs *regs;
0240 volatile unsigned int data = 0;
0241 unsigned int address;
0242 int bus = PCI_DEV_BUS(dev);
0243 int slot = PCI_DEV_SLOT(dev);
0244 int func = PCI_DEV_FUNC(dev);
0245 int retval;
0246
0247 if (slot > 15 || (offset & ~0xfc)) {
0248 *val = 0xffffffff;
0249 return PCISTS_EINVAL;
0250 }
0251
0252 regs = at697pcipriv->regs;
0253
0254 regs->pciitp = 0xff;
0255
0256 if ( bus == 0 ) {
0257
0258 address = (1<<(16+slot)) | (func << 8) | offset;
0259 } else {
0260
0261 address = ((bus & 0xff) << 16) | ((slot & 0x1f) << 11) |
0262 (func << 8) | offset | 1;
0263 }
0264 regs->pcisa = address;
0265 regs->pcidma = 0xa01;
0266 regs->pcidmaa = (unsigned int) &data;
0267
0268 while (regs->pciitp == 0)
0269 ;
0270
0271 regs->pciitp = 0xff;
0272
0273 if (regs->pcisc & 0x20000000) {
0274 regs->pcisc |= 0x20000000;
0275 *val = 0xffffffff;
0276 retval = PCISTS_MSTABRT;
0277 } else {
0278 *val = data;
0279 retval = PCISTS_OK;
0280 }
0281
0282 DBG("pci_read - bus: %d, dev: %d, fn: %d, off: %d => addr: %x, val: %x\n",
0283 bus, slot, func, offset, address, *val);
0284
0285 return retval;
0286 }
0287
0288 static int at697pci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *val)
0289 {
0290 uint32_t v;
0291 int retval;
0292
0293 if (ofs & 1)
0294 return PCISTS_EINVAL;
0295
0296 retval = at697pci_cfg_r32(dev, ofs & ~0x3, &v);
0297 *val = 0xffff & (v >> (8*(ofs & 0x3)));
0298
0299 return retval;
0300 }
0301
0302 static int at697pci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *val)
0303 {
0304 uint32_t v;
0305 int retval;
0306
0307 retval = at697pci_cfg_r32(dev, ofs & ~0x3, &v);
0308
0309 *val = 0xff & (v >> (8*(ofs & 3)));
0310
0311 return retval;
0312 }
0313
0314 static int at697pci_cfg_w32(pci_dev_t dev, int offset, uint32_t val)
0315 {
0316 struct at697pci_regs *regs;
0317 volatile unsigned int tmp_val = val;
0318 unsigned int address;
0319 int bus = PCI_DEV_BUS(dev);
0320 int slot = PCI_DEV_SLOT(dev);
0321 int func = PCI_DEV_FUNC(dev);
0322 int retval;
0323
0324 if (slot > 15 || (offset & ~0xfc))
0325 return PCISTS_EINVAL;
0326
0327 regs = at697pcipriv->regs;
0328
0329 regs->pciitp = 0xff;
0330
0331 if ( bus == 0 ) {
0332
0333 address = (1<<(16+slot)) | (func << 8) | offset;
0334 } else {
0335
0336 address = ((bus & 0xff) << 16) | ((slot & 0x1f) << 11) |
0337 (func << 8) | offset | 1;
0338 }
0339 regs->pcisa = address;
0340 regs->pcidma = 0xb01;
0341 regs->pcidmaa = (unsigned int) &tmp_val;
0342
0343 while (regs->pciitp == 0)
0344 ;
0345
0346 if (regs->pcisc & 0x20000000) {
0347 regs->pcisc |= 0x20000000;
0348 retval = PCISTS_MSTABRT;
0349 } else
0350 retval = PCISTS_OK;
0351
0352 regs->pciitp = 0xff;
0353
0354 DBG("pci_write - bus: %d, dev: %d, fn: %d, off: %d => addr: %x, val: %x\n",
0355 bus, slot, func, offset, address, val);
0356
0357 return retval;
0358 }
0359
0360 static int at697pci_cfg_w16(pci_dev_t dev, int ofs, uint16_t val)
0361 {
0362 uint32_t v;
0363 int retval;
0364
0365 if (ofs & 1)
0366 return PCISTS_EINVAL;
0367
0368 retval = at697pci_cfg_r32(dev, ofs & ~0x3, &v);
0369 if (retval != PCISTS_OK)
0370 return retval;
0371
0372 v = (v & ~(0xffff << (8*(ofs&3)))) | ((0xffff&val) << (8*(ofs&3)));
0373
0374 return at697pci_cfg_w32(dev, ofs & ~0x3, v);
0375 }
0376
0377 static int at697pci_cfg_w8(pci_dev_t dev, int ofs, uint8_t val)
0378 {
0379 uint32_t v;
0380
0381 at697pci_cfg_r32(dev, ofs & ~0x3, &v);
0382
0383 v = (v & ~(0xff << (8*(ofs&3)))) | ((0xff&val) << (8*(ofs&3)));
0384
0385 return at697pci_cfg_w32(dev, ofs & ~0x3, v);
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397 static uint8_t at697pci_bus0_irq_map(pci_dev_t dev, int irq_pin)
0398 {
0399 uint8_t sysIrqNr = 0;
0400 int irq_group;
0401
0402 if ( (irq_pin >= 1) && (irq_pin <= 4) ) {
0403
0404 irq_group = PCI_DEV_SLOT(dev) & 0x3;
0405 irq_pin = ((irq_pin - 1) + irq_group) & 0x3;
0406
0407 sysIrqNr = at697_pci_irq_table[irq_pin];
0408 }
0409 return sysIrqNr;
0410 }
0411
0412 static int at697pci_translate(uint32_t *address, int type, int dir)
0413 {
0414
0415 return 0;
0416 }
0417
0418 extern struct pci_memreg_ops pci_memreg_sparc_be_ops;
0419
0420
0421 static struct pci_access_drv at697pci_access_drv = {
0422 .cfg =
0423 {
0424 at697pci_cfg_r8,
0425 at697pci_cfg_r16,
0426 at697pci_cfg_r32,
0427 at697pci_cfg_w8,
0428 at697pci_cfg_w16,
0429 at697pci_cfg_w32,
0430 },
0431 .io =
0432 {
0433 _ld8,
0434 _ld_be16,
0435 _ld_be32,
0436 _st8,
0437 _st_be16,
0438 _st_be32,
0439
0440 },
0441 .memreg = &pci_memreg_sparc_be_ops,
0442 .translate = at697pci_translate,
0443 };
0444
0445
0446
0447
0448 static int at697pci_hw_init(struct at697pci_priv *priv)
0449 {
0450 struct at697pci_regs *regs = priv->regs;
0451 unsigned short vendor = regs->pciid1 >> 16;
0452
0453
0454 if ( !((vendor == 0x1202) || (vendor == 0x1E0F)) ) {
0455
0456 return -1;
0457 }
0458
0459
0460
0461
0462 if ((regs->pciis & 0x1000) != 0) {
0463 return -1;
0464 }
0465
0466
0467 regs->pciic = 0xffffffff;
0468
0469
0470 regs->pciite = 0;
0471
0472
0473 regs->mbar1 = priv->bar1_pci_adr;
0474 regs->mbar2 = priv->bar2_pci_adr;
0475 regs->pcitpa = (priv->bar1_pci_adr & 0xff000000) |
0476 ((priv->bar2_pci_adr>>16) & 0xff00);
0477
0478
0479 regs->pcisc |= 0x40 | 0x6;
0480
0481
0482 regs->pcibhlc = 0x00004000;
0483
0484
0485 regs->pciic = 0x41;
0486
0487 return 0;
0488 }
0489
0490
0491
0492
0493
0494
0495
0496 static int at697pci_init(struct at697pci_priv *priv)
0497 {
0498 int pin;
0499 union drvmgr_key_value *value;
0500 char keyname_sysirq[6];
0501 char keyname_pio[10];
0502
0503
0504 priv->regs = (struct at697pci_regs *) AT697_PCI_REG_ADR;
0505
0506
0507
0508
0509
0510
0511
0512 strcpy(keyname_sysirq, "INTX#");
0513 strcpy(keyname_pio, "INTX#_PIO");
0514 for (pin=1; pin<5; pin++) {
0515 if ( at697_pci_irq_table[pin-1] == 0xff ) {
0516
0517 keyname_sysirq[3] = 'A' + (pin-1);
0518 value = drvmgr_dev_key_get(priv->dev,
0519 keyname_sysirq, DRVMGR_KT_INT);
0520 if ( value )
0521 at697_pci_irq_table[pin-1] = value->i;
0522 }
0523 if ( at697_pci_irq_pio_table[pin-1] == 0xff ) {
0524
0525 keyname_pio[3] = 'A' + (pin-1);
0526 value = drvmgr_dev_key_get(priv->dev,
0527 keyname_pio, DRVMGR_KT_INT);
0528 if ( value )
0529 at697_pci_irq_pio_table[pin-1] = value->i;
0530 }
0531 }
0532
0533
0534
0535
0536
0537
0538
0539 value = drvmgr_dev_key_get(priv->dev, "tgtbar1", DRVMGR_KT_INT);
0540 if (value)
0541 priv->bar1_pci_adr = value->i;
0542 else
0543 priv->bar1_pci_adr = SYSTEM_MAINMEM_START;
0544
0545 value = drvmgr_dev_key_get(priv->dev, "tgtbar2", DRVMGR_KT_INT);
0546 if (value)
0547 priv->bar2_pci_adr = value->i;
0548 else
0549 priv->bar2_pci_adr = SYSTEM_MAINMEM_START2;
0550
0551
0552 if ( at697pci_hw_init(priv) ) {
0553 return -3;
0554 }
0555
0556
0557 priv->maps_down[0].name = "AMBA -> PCI MEM Window";
0558 priv->maps_down[0].size = 0xF0000000 - 0xA0000000;
0559 priv->maps_down[0].from_adr = (void *)0xA0000000;
0560 priv->maps_down[0].to_adr = (void *)0xA0000000;
0561
0562 priv->maps_down[1].size = 0;
0563
0564
0565 priv->maps_up[0].name = "Target BAR0 -> AMBA";
0566 priv->maps_up[0].size = 0x01000000;
0567 priv->maps_up[0].from_adr = (void *)priv->bar1_pci_adr;
0568 priv->maps_up[0].to_adr = (void *)priv->bar1_pci_adr;
0569 priv->maps_up[1].name = "Target BAR1 -> AMBA";
0570 priv->maps_up[1].size = 0x01000000;
0571 priv->maps_up[1].from_adr = (void *)priv->bar2_pci_adr;
0572 priv->maps_up[1].to_adr = (void *)priv->bar2_pci_adr;
0573
0574 priv->maps_up[2].size = 0;
0575
0576 return 0;
0577 }
0578
0579
0580
0581
0582 int at697pci_init1(struct drvmgr_dev *dev)
0583 {
0584 struct at697pci_priv *priv;
0585 struct pci_auto_setup at697pci_auto_cfg;
0586
0587 DBG("AT697PCI[%d] on bus %s\n", dev->minor_drv,
0588 dev->parent->dev->name);
0589
0590 if ( at697pci_minor != 0 ) {
0591 DBG("Driver only supports one PCI core\n");
0592 return DRVMGR_FAIL;
0593 }
0594
0595 at697pcipriv = priv = dev->priv;
0596 if ( !priv )
0597 return DRVMGR_NOMEM;
0598
0599 priv->dev = dev;
0600 priv->minor = at697pci_minor++;
0601
0602 if (at697pci_init(priv)) {
0603 DBG("Failed to initialize at697pci driver\n");
0604 return DRVMGR_EIO;
0605 }
0606
0607
0608 pci_endian = PCI_BIG_ENDIAN;
0609
0610 if (pci_access_drv_register(&at697pci_access_drv)) {
0611
0612 return DRVMGR_FAIL;
0613 }
0614
0615
0616 at697pci_auto_cfg.options = 0;
0617 at697pci_auto_cfg.mem_start = 0;
0618 at697pci_auto_cfg.mem_size = 0;
0619 at697pci_auto_cfg.memio_start = PCI_MEM_START;
0620 at697pci_auto_cfg.memio_size = PCI_MEM_SIZE;
0621 at697pci_auto_cfg.io_start = 0;
0622 at697pci_auto_cfg.io_size = 0;
0623 at697pci_auto_cfg.irq_map = at697pci_bus0_irq_map;
0624 at697pci_auto_cfg.irq_route = NULL;
0625 pci_config_register(&at697pci_auto_cfg);
0626
0627 if (pci_config_init()) {
0628
0629 return DRVMGR_FAIL;
0630 }
0631
0632 priv->config.maps_down = &priv->maps_down[0];
0633 priv->config.maps_up = &priv->maps_up[0];
0634 return pcibus_register(dev, &priv->config);
0635 }
0636
0637 int at697pci_init2(struct drvmgr_dev *dev)
0638 {
0639 #if 0
0640 struct at697pci_priv *priv = dev->priv;
0641 #endif
0642 int pin, irq, pio, ioport;
0643 LEON_Register_Map *regs = (LEON_Register_Map *)0x80000000;
0644
0645
0646
0647
0648
0649 for (pin=1; pin<5; pin++) {
0650 irq = at697_pci_irq_table[pin-1];
0651 pio = at697_pci_irq_pio_table[pin-1];
0652 if ( (pio < 16) && (irq >= 4) && (irq <= 7) ) {
0653
0654
0655
0656
0657
0658
0659
0660 ioport = irq - 4;
0661
0662
0663 regs->PIO_Interrupt &= ~(0xff << (ioport * 8));
0664
0665 regs->PIO_Direction &= ~(1 << pio);
0666
0667 regs->PIO_Interrupt |= ((0x80 | pio) << (ioport * 8));
0668 }
0669 }
0670
0671
0672
0673
0674 return DRVMGR_OK;
0675 }