From 51347053b8fa490f2e5a20ce0693ef32dc6a3018 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Mon, 1 Jul 2013 15:00:21 +0200 Subject: 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. --- c/src/lib/libbsp/sparc/leon2/pci/at697_pci.c | 8 ++----- c/src/lib/libbsp/sparc/shared/pci/grpci.c | 30 +++++++++++++++++++++---- c/src/lib/libbsp/sparc/shared/pci/grpci2.c | 13 ++++++++--- c/src/lib/libbsp/sparc/shared/pci/pcif.c | 33 +++++++++++++++++++++++----- 4 files changed, 66 insertions(+), 18 deletions(-) (limited to 'c/src/lib/libbsp/sparc') diff --git a/c/src/lib/libbsp/sparc/leon2/pci/at697_pci.c b/c/src/lib/libbsp/sparc/leon2/pci/at697_pci.c index 2387cc0bf7..76b9c4d943 100644 --- a/c/src/lib/libbsp/sparc/leon2/pci/at697_pci.c +++ b/c/src/lib/libbsp/sparc/leon2/pci/at697_pci.c @@ -161,7 +161,6 @@ struct at697pci_priv { struct at697pci_regs *regs; int minor; - uint32_t devVend; /* PCI Device and Vendor ID of Host */ uint32_t bar1_pci_adr; uint32_t bar2_pci_adr; @@ -228,7 +227,7 @@ int at697pci_cfg_r32(pci_dev_t dev, int offset, uint32_t *val) int func = PCI_DEV_FUNC(dev); int retval; - if (slot > 21 || (offset & ~0xfc)) { + if (slot > 15 || (offset & ~0xfc)) { *val = 0xffffffff; return PCISTS_EINVAL; } @@ -239,7 +238,7 @@ int at697pci_cfg_r32(pci_dev_t dev, int offset, uint32_t *val) if ( bus == 0 ) { /* PCI Access - TYPE 0 */ - address = (1<<(11+slot)) | (func << 8) | offset; + address = (1<<(16+slot)) | (func << 8) | offset; } else { /* PCI access - TYPE 1 */ address = ((bus & 0xff) << 16) | ((slot & 0x1f) << 11) | @@ -462,9 +461,6 @@ int at697pci_hw_init(struct at697pci_priv *priv) /* Set Inititator configuration so that AHB slave accesses generate memory read/write commands */ regs->pciic = 0x41; - /* Get the AT697PCI Host PCI ID */ - at697pci_cfg_r32(host, PCI_VENDOR_ID, &priv->devVend); - return 0; } 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; -- cgit v1.2.3