diff mbox

[U-Boot,1/2] pci: Add function to find an extended capability

Message ID 1436270132-32301-1-git-send-email-Minghuan.Lian@freescale.com
State Superseded
Delegated to: York Sun
Headers show

Commit Message

Minghuan Lian July 7, 2015, 11:55 a.m. UTC
PCIe extends device's configuration space to 4k and provides
extended capability. The patch adds function to find them.
The code is ported from Linux PCIe driver.

Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
---
 drivers/pci/pci.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 include/pci.h     | 41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)

Comments

Bin Meng July 8, 2015, 8:14 a.m. UTC | #1
Hi Minghuan,

On Tue, Jul 7, 2015 at 7:55 PM, Minghuan Lian
<Minghuan.Lian@freescale.com> wrote:
> PCIe extends device's configuration space to 4k and provides
> extended capability. The patch adds function to find them.
> The code is ported from Linux PCIe driver.
>
> Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
>
> ---
>  drivers/pci/pci.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  include/pci.h     | 41 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 86 insertions(+)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 157491c..c9bc098 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -526,3 +526,48 @@ int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap)
>         }
>         return 0;
>  }
> +
> +int pci_find_next_ext_capability(struct pci_controller *hose, pci_dev_t dev,
> +                                int start, int cap)

I am thinking whether we should provide this API too. Maybe just
pci_hose_find_ext_capability() is enough.

> +{
> +       u32 header;
> +       int ttl, pos = PCI_CFG_SPACE_SIZE;
> +
> +       /* minimum 8 bytes per capability */
> +       ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
> +
> +       if (start)
> +               pos = start;
> +
> +       pci_hose_read_config_dword(hose, dev, pos, &header);
> +       if (header == 0xffffffff || header == 0)
> +               return 0;
> +
> +       while (ttl-- > 0) {
> +               if (PCI_EXT_CAP_ID(header) == cap && pos != start)
> +                       return pos;
> +
> +               pos = PCI_EXT_CAP_NEXT(header);
> +               if (pos < PCI_CFG_SPACE_SIZE)
> +                       break;
> +
> +               pci_hose_read_config_dword(hose, dev, pos, &header);
> +               if (header == 0xffffffff || header == 0)
> +                       break;
> +       }
> +
> +       return 0;
> +}
> +
> +/**
> + * pci_host_find_ext_capability - Find an extended capability

Typo. pci_hose

> + *
> + * Returns the address of the requested extended capability structure
> + * within the device's PCI configuration space or 0 if the device does
> + * not support it.
> + */
> +int pci_hose_find_ext_capability(struct pci_controller *hose, pci_dev_t dev,
> +                                int cap)
> +{
> +       return pci_find_next_ext_capability(hose, dev, 0, cap);
> +}
> diff --git a/include/pci.h b/include/pci.h
> index 07b1e9a..2f88714 100644
> --- a/include/pci.h
> +++ b/include/pci.h
> @@ -11,6 +11,9 @@
>  #ifndef _PCI_H
>  #define _PCI_H
>
> +#define PCI_CFG_SPACE_SIZE     256
> +#define PCI_CFG_SPACE_EXP_SIZE 4096
> +
>  /*
>   * Under PCI, each device has 256 bytes of configuration address space,
>   * of which the first 64 bytes are standardized as follows:
> @@ -413,6 +416,39 @@
>  #define PCI_FIND_CAP_TTL 0x48
>  #define CAP_START_POS 0x40
>
> +/* Extended Capabilities (PCI-X 2.0 and Express) */
> +#define PCI_EXT_CAP_ID(header)         (header & 0x0000ffff)
> +#define PCI_EXT_CAP_VER(header)                ((header >> 16) & 0xf)
> +#define PCI_EXT_CAP_NEXT(header)       ((header >> 20) & 0xffc)
> +
> +#define PCI_EXT_CAP_ID_ERR     0x01    /* Advanced Error Reporting */
> +#define PCI_EXT_CAP_ID_VC      0x02    /* Virtual Channel Capability */
> +#define PCI_EXT_CAP_ID_DSN     0x03    /* Device Serial Number */
> +#define PCI_EXT_CAP_ID_PWR     0x04    /* Power Budgeting */
> +#define PCI_EXT_CAP_ID_RCLD    0x05    /* Root Complex Link Declaration */
> +#define PCI_EXT_CAP_ID_RCILC   0x06    /* Root Complex Internal Link Control */
> +#define PCI_EXT_CAP_ID_RCEC    0x07    /* Root Complex Event Collector */
> +#define PCI_EXT_CAP_ID_MFVC    0x08    /* Multi-Function VC Capability */
> +#define PCI_EXT_CAP_ID_VC9     0x09    /* same as _VC */
> +#define PCI_EXT_CAP_ID_RCRB    0x0A    /* Root Complex RB? */
> +#define PCI_EXT_CAP_ID_VNDR    0x0B    /* Vendor-Specific */
> +#define PCI_EXT_CAP_ID_CAC     0x0C    /* Config Access - obsolete */
> +#define PCI_EXT_CAP_ID_ACS     0x0D    /* Access Control Services */
> +#define PCI_EXT_CAP_ID_ARI     0x0E    /* Alternate Routing ID */
> +#define PCI_EXT_CAP_ID_ATS     0x0F    /* Address Translation Services */
> +#define PCI_EXT_CAP_ID_SRIOV   0x10    /* Single Root I/O Virtualization */
> +#define PCI_EXT_CAP_ID_MRIOV   0x11    /* Multi Root I/O Virtualization */
> +#define PCI_EXT_CAP_ID_MCAST   0x12    /* Multicast */
> +#define PCI_EXT_CAP_ID_PRI     0x13    /* Page Request Interface */
> +#define PCI_EXT_CAP_ID_AMD_XXX 0x14    /* Reserved for AMD */
> +#define PCI_EXT_CAP_ID_REBAR   0x15    /* Resizable BAR */
> +#define PCI_EXT_CAP_ID_DPA     0x16    /* Dynamic Power Allocation */
> +#define PCI_EXT_CAP_ID_TPH     0x17    /* TPH Requester */
> +#define PCI_EXT_CAP_ID_LTR     0x18    /* Latency Tolerance Reporting */
> +#define PCI_EXT_CAP_ID_SECPCI  0x19    /* Secondary PCIe Capability */
> +#define PCI_EXT_CAP_ID_PMUX    0x1A    /* Protocol Multiplexing */
> +#define PCI_EXT_CAP_ID_PASID   0x1B    /* Process Address Space ID */
> +
>  /* Include the ID list */
>
>  #include <pci_ids.h>
> @@ -674,6 +710,11 @@ extern int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
>  extern int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos,
>                         int cap);
>
> +int pci_find_next_ext_capability(struct pci_controller *hose,
> +                                pci_dev_t dev, int start, int cap);
> +int pci_hose_find_ext_capability(struct pci_controller *hose,
> +                                pci_dev_t dev, int cap);
> +
>  #ifdef CONFIG_PCI_FIXUP_DEV
>  extern void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev,
>                                 unsigned short vendor,
> --

Regards,
Bin
Minghuan Lian July 8, 2015, 9:08 a.m. UTC | #2
Hi Bin,

Thanks for your comments.
Please see my reply inline.

> -----Original Message-----
> From: Bin Meng [mailto:bmeng.cn@gmail.com]
> Sent: Wednesday, July 08, 2015 4:14 PM
> To: Lian Minghuan-B31939
> Cc: U-Boot Mailing List; Hu Mingkai-B21284; Sun York-R58495
> Subject: Re: [U-Boot] [PATCH 1/2] pci: Add function to find an extended
> capability
> 
> Hi Minghuan,
> 
> On Tue, Jul 7, 2015 at 7:55 PM, Minghuan Lian
> <Minghuan.Lian@freescale.com> wrote:
> > PCIe extends device's configuration space to 4k and provides extended
> > capability. The patch adds function to find them.
> > The code is ported from Linux PCIe driver.
> >
> > Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
> >
> > ---
> >  drivers/pci/pci.c | 45
> +++++++++++++++++++++++++++++++++++++++++++++
> >  include/pci.h     | 41 +++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 86 insertions(+)
> >
> > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index
> > 157491c..c9bc098 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -526,3 +526,48 @@ int pci_find_cap(struct pci_controller *hose,
> pci_dev_t dev, int pos, int cap)
> >         }
> >         return 0;
> >  }
> > +
> > +int pci_find_next_ext_capability(struct pci_controller *hose, pci_dev_t
> dev,
> > +                                int start, int cap)
> 
> I am thinking whether we should provide this API too. Maybe just
> pci_hose_find_ext_capability() is enough.
> 
[Minghuan] pci_hose_find_ext_capability() only can return the pos of the first  capability query.
pci_find_next_ext_capability can return the second  third .. pos of the searched capability.
We may refer to the comment of Linux
"Some capabilities can occur several times, e.g., the
  * vendor-specific capability, and this provides a way to find them all."

> > +{
> > +       u32 header;
> > +       int ttl, pos = PCI_CFG_SPACE_SIZE;
> > +
> > +       /* minimum 8 bytes per capability */
> > +       ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
> > +
> > +       if (start)
> > +               pos = start;
> > +
> > +       pci_hose_read_config_dword(hose, dev, pos, &header);
> > +       if (header == 0xffffffff || header == 0)
> > +               return 0;
> > +
> > +       while (ttl-- > 0) {
> > +               if (PCI_EXT_CAP_ID(header) == cap && pos != start)
> > +                       return pos;
> > +
> > +               pos = PCI_EXT_CAP_NEXT(header);
> > +               if (pos < PCI_CFG_SPACE_SIZE)
> > +                       break;
> > +
> > +               pci_hose_read_config_dword(hose, dev, pos, &header);
> > +               if (header == 0xffffffff || header == 0)
> > +                       break;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * pci_host_find_ext_capability - Find an extended capability
> 
> Typo. pci_hose
[Minghuan]  Sorry, I will fix it.
> 
> > + *
> > + * Returns the address of the requested extended capability structure
> > + * within the device's PCI configuration space or 0 if the device
> > +does
> > + * not support it.
> > + */
> > +int pci_hose_find_ext_capability(struct pci_controller *hose, pci_dev_t
> dev,
> > +                                int cap) {
> > +       return pci_find_next_ext_capability(hose, dev, 0, cap); }
> > diff --git a/include/pci.h b/include/pci.h index 07b1e9a..2f88714
> > 100644
> > --- a/include/pci.h
> > +++ b/include/pci.h
> > @@ -11,6 +11,9 @@
> >  #ifndef _PCI_H
> >  #define _PCI_H
> >
> > +#define PCI_CFG_SPACE_SIZE     256
> > +#define PCI_CFG_SPACE_EXP_SIZE 4096
> > +
> >  /*
> >   * Under PCI, each device has 256 bytes of configuration address space,
> >   * of which the first 64 bytes are standardized as follows:
> > @@ -413,6 +416,39 @@
> >  #define PCI_FIND_CAP_TTL 0x48
> >  #define CAP_START_POS 0x40
> >
> > +/* Extended Capabilities (PCI-X 2.0 and Express) */
> > +#define PCI_EXT_CAP_ID(header)         (header & 0x0000ffff)
> > +#define PCI_EXT_CAP_VER(header)                ((header >> 16) & 0xf)
> > +#define PCI_EXT_CAP_NEXT(header)       ((header >> 20) & 0xffc)
> > +
> > +#define PCI_EXT_CAP_ID_ERR     0x01    /* Advanced Error Reporting */
> > +#define PCI_EXT_CAP_ID_VC      0x02    /* Virtual Channel Capability */
> > +#define PCI_EXT_CAP_ID_DSN     0x03    /* Device Serial Number */
> > +#define PCI_EXT_CAP_ID_PWR     0x04    /* Power Budgeting */
> > +#define PCI_EXT_CAP_ID_RCLD    0x05    /* Root Complex Link Declaration
> */
> > +#define PCI_EXT_CAP_ID_RCILC   0x06    /* Root Complex Internal Link
> Control */
> > +#define PCI_EXT_CAP_ID_RCEC    0x07    /* Root Complex Event Collector
> */
> > +#define PCI_EXT_CAP_ID_MFVC    0x08    /* Multi-Function VC Capability
> */
> > +#define PCI_EXT_CAP_ID_VC9     0x09    /* same as _VC */
> > +#define PCI_EXT_CAP_ID_RCRB    0x0A    /* Root Complex RB? */
> > +#define PCI_EXT_CAP_ID_VNDR    0x0B    /* Vendor-Specific */
> > +#define PCI_EXT_CAP_ID_CAC     0x0C    /* Config Access - obsolete */
> > +#define PCI_EXT_CAP_ID_ACS     0x0D    /* Access Control Services */
> > +#define PCI_EXT_CAP_ID_ARI     0x0E    /* Alternate Routing ID */
> > +#define PCI_EXT_CAP_ID_ATS     0x0F    /* Address Translation Services */
> > +#define PCI_EXT_CAP_ID_SRIOV   0x10    /* Single Root I/O Virtualization
> */
> > +#define PCI_EXT_CAP_ID_MRIOV   0x11    /* Multi Root I/O Virtualization
> */
> > +#define PCI_EXT_CAP_ID_MCAST   0x12    /* Multicast */
> > +#define PCI_EXT_CAP_ID_PRI     0x13    /* Page Request Interface */
> > +#define PCI_EXT_CAP_ID_AMD_XXX 0x14    /* Reserved for AMD */
> > +#define PCI_EXT_CAP_ID_REBAR   0x15    /* Resizable BAR */
> > +#define PCI_EXT_CAP_ID_DPA     0x16    /* Dynamic Power Allocation */
> > +#define PCI_EXT_CAP_ID_TPH     0x17    /* TPH Requester */
> > +#define PCI_EXT_CAP_ID_LTR     0x18    /* Latency Tolerance Reporting */
> > +#define PCI_EXT_CAP_ID_SECPCI  0x19    /* Secondary PCIe Capability */
> > +#define PCI_EXT_CAP_ID_PMUX    0x1A    /* Protocol Multiplexing */
> > +#define PCI_EXT_CAP_ID_PASID   0x1B    /* Process Address Space ID */
> > +
> >  /* Include the ID list */
> >
> >  #include <pci_ids.h>
> > @@ -674,6 +710,11 @@ extern int pci_hose_find_cap_start(struct
> > pci_controller *hose, pci_dev_t dev,  extern int pci_find_cap(struct
> pci_controller *hose, pci_dev_t dev, int pos,
> >                         int cap);
> >
> > +int pci_find_next_ext_capability(struct pci_controller *hose,
> > +                                pci_dev_t dev, int start, int cap);
> > +int pci_hose_find_ext_capability(struct pci_controller *hose,
> > +                                pci_dev_t dev, int cap);
> > +
> >  #ifdef CONFIG_PCI_FIXUP_DEV
> >  extern void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t
> dev,
> >                                 unsigned short vendor,
> > --
> 
> Regards,
> Bin
diff mbox

Patch

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 157491c..c9bc098 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -526,3 +526,48 @@  int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap)
 	}
 	return 0;
 }
+
+int pci_find_next_ext_capability(struct pci_controller *hose, pci_dev_t dev,
+				 int start, int cap)
+{
+	u32 header;
+	int ttl, pos = PCI_CFG_SPACE_SIZE;
+
+	/* minimum 8 bytes per capability */
+	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+	if (start)
+		pos = start;
+
+	pci_hose_read_config_dword(hose, dev, pos, &header);
+	if (header == 0xffffffff || header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (PCI_EXT_CAP_ID(header) == cap && pos != start)
+			return pos;
+
+		pos = PCI_EXT_CAP_NEXT(header);
+		if (pos < PCI_CFG_SPACE_SIZE)
+			break;
+
+		pci_hose_read_config_dword(hose, dev, pos, &header);
+		if (header == 0xffffffff || header == 0)
+			break;
+	}
+
+	return 0;
+}
+
+/**
+ * pci_host_find_ext_capability - Find an extended capability
+ *
+ * Returns the address of the requested extended capability structure
+ * within the device's PCI configuration space or 0 if the device does
+ * not support it.
+ */
+int pci_hose_find_ext_capability(struct pci_controller *hose, pci_dev_t dev,
+				 int cap)
+{
+	return pci_find_next_ext_capability(hose, dev, 0, cap);
+}
diff --git a/include/pci.h b/include/pci.h
index 07b1e9a..2f88714 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -11,6 +11,9 @@ 
 #ifndef _PCI_H
 #define _PCI_H
 
+#define PCI_CFG_SPACE_SIZE	256
+#define PCI_CFG_SPACE_EXP_SIZE	4096
+
 /*
  * Under PCI, each device has 256 bytes of configuration address space,
  * of which the first 64 bytes are standardized as follows:
@@ -413,6 +416,39 @@ 
 #define PCI_FIND_CAP_TTL 0x48
 #define CAP_START_POS 0x40
 
+/* Extended Capabilities (PCI-X 2.0 and Express) */
+#define PCI_EXT_CAP_ID(header)		(header & 0x0000ffff)
+#define PCI_EXT_CAP_VER(header)		((header >> 16) & 0xf)
+#define PCI_EXT_CAP_NEXT(header)	((header >> 20) & 0xffc)
+
+#define PCI_EXT_CAP_ID_ERR	0x01	/* Advanced Error Reporting */
+#define PCI_EXT_CAP_ID_VC	0x02	/* Virtual Channel Capability */
+#define PCI_EXT_CAP_ID_DSN	0x03	/* Device Serial Number */
+#define PCI_EXT_CAP_ID_PWR	0x04	/* Power Budgeting */
+#define PCI_EXT_CAP_ID_RCLD	0x05	/* Root Complex Link Declaration */
+#define PCI_EXT_CAP_ID_RCILC	0x06	/* Root Complex Internal Link Control */
+#define PCI_EXT_CAP_ID_RCEC	0x07	/* Root Complex Event Collector */
+#define PCI_EXT_CAP_ID_MFVC	0x08	/* Multi-Function VC Capability */
+#define PCI_EXT_CAP_ID_VC9	0x09	/* same as _VC */
+#define PCI_EXT_CAP_ID_RCRB	0x0A	/* Root Complex RB? */
+#define PCI_EXT_CAP_ID_VNDR	0x0B	/* Vendor-Specific */
+#define PCI_EXT_CAP_ID_CAC	0x0C	/* Config Access - obsolete */
+#define PCI_EXT_CAP_ID_ACS	0x0D	/* Access Control Services */
+#define PCI_EXT_CAP_ID_ARI	0x0E	/* Alternate Routing ID */
+#define PCI_EXT_CAP_ID_ATS	0x0F	/* Address Translation Services */
+#define PCI_EXT_CAP_ID_SRIOV	0x10	/* Single Root I/O Virtualization */
+#define PCI_EXT_CAP_ID_MRIOV	0x11	/* Multi Root I/O Virtualization */
+#define PCI_EXT_CAP_ID_MCAST	0x12	/* Multicast */
+#define PCI_EXT_CAP_ID_PRI	0x13	/* Page Request Interface */
+#define PCI_EXT_CAP_ID_AMD_XXX	0x14	/* Reserved for AMD */
+#define PCI_EXT_CAP_ID_REBAR	0x15	/* Resizable BAR */
+#define PCI_EXT_CAP_ID_DPA	0x16	/* Dynamic Power Allocation */
+#define PCI_EXT_CAP_ID_TPH	0x17	/* TPH Requester */
+#define PCI_EXT_CAP_ID_LTR	0x18	/* Latency Tolerance Reporting */
+#define PCI_EXT_CAP_ID_SECPCI	0x19	/* Secondary PCIe Capability */
+#define PCI_EXT_CAP_ID_PMUX	0x1A	/* Protocol Multiplexing */
+#define PCI_EXT_CAP_ID_PASID	0x1B	/* Process Address Space ID */
+
 /* Include the ID list */
 
 #include <pci_ids.h>
@@ -674,6 +710,11 @@  extern int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
 extern int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos,
 			int cap);
 
+int pci_find_next_ext_capability(struct pci_controller *hose,
+				 pci_dev_t dev, int start, int cap);
+int pci_hose_find_ext_capability(struct pci_controller *hose,
+				 pci_dev_t dev, int cap);
+
 #ifdef CONFIG_PCI_FIXUP_DEV
 extern void board_pci_fixup_dev(struct pci_controller *hose, pci_dev_t dev,
 				unsigned short vendor,