summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2013-07-01 15:00:21 +0200
committerDaniel Hellstrom <daniel@gaisler.com>2015-04-17 01:10:20 +0200
commit51347053b8fa490f2e5a20ce0693ef32dc6a3018 (patch)
tree6cf4488afc5343efac529f61483c86352ac1a4a9 /c/src/lib/libbsp/sparc/shared
parentAPBUART: debug bit was cleared incorrectly (diff)
downloadrtems-51347053b8fa490f2e5a20ce0693ef32dc6a3018.tar.bz2
LEON PCI: host bridge driver support for probing dev0=AD16
Before the LIBPCI didn't probe device0 (AD16), the host bridge drivers used bus=dev=func=0 to internally probe the host bridge's target interface. Now that LIBPCI uses bus=dev=func=0 to access device0, bus=0xff is introduced internally to identify the host bridge target configuration space.
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared')
-rw-r--r--c/src/lib/libbsp/sparc/shared/pci/grpci.c30
-rw-r--r--c/src/lib/libbsp/sparc/shared/pci/grpci2.c13
-rw-r--r--c/src/lib/libbsp/sparc/shared/pci/pcif.c33
3 files changed, 64 insertions, 12 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/pci/grpci.c b/c/src/lib/libbsp/sparc/shared/pci/grpci.c
index eb188bbae1..63e08ad92a 100644
--- a/c/src/lib/libbsp/sparc/shared/pci/grpci.c
+++ b/c/src/lib/libbsp/sparc/shared/pci/grpci.c
@@ -85,6 +85,8 @@ struct grpci_regs {
volatile unsigned int irq;
};
+#define HOST_TGT PCI_DEV(0xff, 0, 0)
+
struct grpci_priv *grpcipriv = NULL;
static int grpci_minor = 0;
static unsigned int *pcidma = (unsigned int *)DMAPCI_ADDR;
@@ -168,18 +170,28 @@ int grpci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *val)
{
struct grpci_priv *priv = grpcipriv;
volatile uint32_t *pci_conf;
- unsigned int devfn = PCI_DEV_DEVFUNC(dev);
+ uint32_t devfn;
int retval;
int bus = PCI_DEV_BUS(dev);
if (ofs & 3)
return PCISTS_EINVAL;
- if (PCI_DEV_SLOT(dev) > 21) {
+ if (PCI_DEV_SLOT(dev) > 15) {
*val = 0xffffffff;
return PCISTS_OK;
}
+ /* GRPCI can access "non-standard" devices on bus0 (on AD11.AD16),
+ * but we skip them.
+ */
+ if (dev == HOST_TGT)
+ bus = devfn = 0;
+ if (bus == 0)
+ devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
+ else
+ devfn = PCI_DEV_DEVFUNC(dev);
+
/* Select bus */
priv->regs->cfg_stat = (priv->regs->cfg_stat & ~(0xf<<23)) | (bus<<23);
@@ -240,9 +252,19 @@ int grpci_cfg_w32(pci_dev_t dev, int ofs, uint32_t val)
if (ofs & 0x3)
return PCISTS_EINVAL;
- if (PCI_DEV_SLOT(dev) > 21)
+ if (PCI_DEV_SLOT(dev) > 15)
return PCISTS_MSTABRT;
+ /* GRPCI can access "non-standard" devices on bus0 (on AD11.AD16),
+ * but we skip them.
+ */
+ if (dev == HOST_TGT)
+ bus = devfn = 0;
+ if (bus == 0)
+ devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
+ else
+ devfn = PCI_DEV_DEVFUNC(dev);
+
/* Select bus */
priv->regs->cfg_stat = (priv->regs->cfg_stat & ~(0xf<<23)) | (bus<<23);
@@ -409,7 +431,7 @@ int grpci_hw_init(struct grpci_priv *priv)
{
volatile unsigned int *mbar0, *page0;
uint32_t data, addr, mbar0size;
- pci_dev_t host = PCI_DEV(0, 0, 0);
+ pci_dev_t host = HOST_TGT;
mbar0 = (volatile unsigned int *)priv->pci_area;
diff --git a/c/src/lib/libbsp/sparc/shared/pci/grpci2.c b/c/src/lib/libbsp/sparc/shared/pci/grpci2.c
index 5886336982..29af4ab756 100644
--- a/c/src/lib/libbsp/sparc/shared/pci/grpci2.c
+++ b/c/src/lib/libbsp/sparc/shared/pci/grpci2.c
@@ -196,6 +196,9 @@ struct grpci2_cap_first {
#define CAP9_BARSIZE_OFS 0x24
#define CAP9_AHBPREF_OFS 0x3C
+/* Used internally for accessing the PCI bridge's configuration space itself */
+#define HOST_TGT PCI_DEV(0xff, 0, 0)
+
struct grpci2_priv *grpci2priv = NULL;
/* PCI Interrupt assignment. Connects an PCI interrupt pin (INTA#..INTD#)
@@ -310,7 +313,9 @@ int grpci2_cfg_r32(pci_dev_t dev, int ofs, uint32_t *val)
/* GRPCI2 can access "non-standard" devices on bus0 (on AD11.AD16),
* we skip them.
*/
- if (bus == 0 && PCI_DEV_SLOT(dev) != 0)
+ if (dev == HOST_TGT)
+ bus = devfn = 0;
+ else if (bus == 0)
devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
else
devfn = PCI_DEV_DEVFUNC(dev);
@@ -398,7 +403,9 @@ int grpci2_cfg_w32(pci_dev_t dev, int ofs, uint32_t val)
/* GRPCI2 can access "non-standard" devices on bus0 (on AD11.AD16),
* we skip them.
*/
- if (bus == 0 && PCI_DEV_SLOT(dev) != 0)
+ if (dev == HOST_TGT)
+ bus = devfn = 0;
+ if (bus == 0)
devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
else
devfn = PCI_DEV_DEVFUNC(dev);
@@ -627,7 +634,7 @@ int grpci2_hw_init(struct grpci2_priv *priv)
int i;
uint8_t capptr;
uint32_t data, io_map, ahbadr, pciadr, size;
- pci_dev_t host = PCI_DEV(0, 0, 0);
+ pci_dev_t host = HOST_TGT;
struct grpci2_pcibar_cfg *barcfg = priv->barcfg;
/* Reset any earlier setup */
diff --git a/c/src/lib/libbsp/sparc/shared/pci/pcif.c b/c/src/lib/libbsp/sparc/shared/pci/pcif.c
index c69282d4f5..2dc46a8ad1 100644
--- a/c/src/lib/libbsp/sparc/shared/pci/pcif.c
+++ b/c/src/lib/libbsp/sparc/shared/pci/pcif.c
@@ -73,6 +73,9 @@ struct pcif_regs {
volatile unsigned int maps[(0x80-0x40)/4]; /* 0x40-0x80*/
};
+/* Used internally for accessing the PCI bridge's configuration space itself */
+#define HOST_TGT PCI_DEV(0xff, 0, 0)
+
struct pcif_priv *pcifpriv = NULL;
static int pcif_minor = 0;
@@ -154,18 +157,28 @@ int pcif_cfg_r32(pci_dev_t dev, int ofs, uint32_t *val)
{
struct pcif_priv *priv = pcifpriv;
volatile uint32_t *pci_conf;
- unsigned int devfn = PCI_DEV_DEVFUNC(dev);
+ uint32_t devfn;
int retval;
int bus = PCI_DEV_BUS(dev);
if (ofs & 3)
return PCISTS_EINVAL;
- if (PCI_DEV_SLOT(dev) > 21) {
+ if (PCI_DEV_SLOT(dev) > 15) {
*val = 0xffffffff;
return PCISTS_OK;
}
+ /* PCIF can access "non-standard" devices on bus0 (on AD11.AD16),
+ * but we skip them.
+ */
+ if (dev == HOST_TGT)
+ bus = devfn = 0;
+ if (bus == 0)
+ devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
+ else
+ devfn = PCI_DEV_DEVFUNC(dev);
+
/* Select bus */
priv->regs->bus = bus << 16;
@@ -214,15 +227,25 @@ int pcif_cfg_w32(pci_dev_t dev, int ofs, uint32_t val)
{
struct pcif_priv *priv = pcifpriv;
volatile uint32_t *pci_conf;
- uint32_t devfn = PCI_DEV_DEVFUNC(dev);
+ uint32_t devfn;
int bus = PCI_DEV_BUS(dev);
if (ofs & ~0xfc)
return PCISTS_EINVAL;
- if (PCI_DEV_SLOT(dev) > 21)
+ if (PCI_DEV_SLOT(dev) > 15)
return PCISTS_MSTABRT;
+ /* PCIF can access "non-standard" devices on bus0 (on AD11.AD16),
+ * but we skip them.
+ */
+ if (dev == HOST_TGT)
+ bus = devfn = 0;
+ if (bus == 0)
+ devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
+ else
+ devfn = PCI_DEV_DEVFUNC(dev);
+
/* Select bus */
priv->regs->bus = bus << 16;
@@ -332,7 +355,7 @@ int pcif_hw_init(struct pcif_priv *priv)
struct pcif_regs *regs;
uint32_t data, size;
int mst;
- pci_dev_t host = PCI_DEV(0, 0, 0);
+ pci_dev_t host = HOST_TGT;
regs = priv->regs;