[U-Boot] FW: [PATCH v3] PCIe:change the method to get the address of a requested capability in configuration space.

Zhao Qiang-B45475 B45475 at freescale.com
Thu Oct 10 03:39:49 CEST 2013


Hi Tom,

	Please keep an eye on this patch http://patchwork.ozlabs.org/patch/275173/

Regards
Zhao Qiang

> -----Original Message-----
> From: Zhao Qiang-B45475
> Sent: Monday, September 30, 2013 11:10 AM
> To: 'trini at ti.com'
> Cc: u-boot at lists.denx.de
> Subject: RE: [PATCH v3] PCIe:change the method to get the address of a
> requested capability in configuration space.
> 
> Hi Tom,
> 
> I'd like you to pay attention on this patch
> http://patchwork.ozlabs.org/patch/275173/
> 
> Regards
> Zhao Qiang
> 
> > -----Original Message-----
> > From: Zhao Qiang-B45475
> > Sent: Monday, September 16, 2013 5:28 PM
> > To: u-boot at lists.denx.de
> > Cc: Zhao Qiang-B45475
> > Subject: [PATCH v3] PCIe:change the method to get the address of a
> > requested capability in configuration space.
> >
> > Previously, the address of a requested capability is define like that
> > 	"#define PCI_DCR	0x78"
> > But, the addresses of capabilities is different with regard to PCIe
> revs.
> > So this method is not flexible.
> >
> > Now a function to get the address of a requested capability is added
> > and used.
> > It can get the address dynamically by capability ID.
> > The step of this function:
> > 	1. Read Status register in PCIe configuration space to confirm that
> > 	   Capabilities List is valid.
> > 	2. Find the address of Capabilities Pointer Register.
> > 	3. Find the address of requested capability from the first
> > capability.
> >
> > Signed-off-by: Zhao Qiang <B45475 at freescale.com>
> > ---
> > Changes for v2:
> > 	-Put an variable into "#ifdef" and "#endif"
> > Changes for v3:
> > 	-Modify the patch description
> >
> >
> >  arch/powerpc/include/asm/fsl_pci.h | 13 +-------
> >  drivers/pci/fsl_pci_init.c         | 44 +++++++++++++++++++-------
> >  drivers/pci/pci.c                  | 65
> > ++++++++++++++++++++++++++++++++++++++
> >  include/pci.h                      | 10 ++++++
> >  4 files changed, 108 insertions(+), 24 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/fsl_pci.h
> > b/arch/powerpc/include/asm/fsl_pci.h
> > index 90b0a2f..6b12afa 100644
> > --- a/arch/powerpc/include/asm/fsl_pci.h
> > +++ b/arch/powerpc/include/asm/fsl_pci.h
> > @@ -32,22 +32,11 @@
> >  /* Freescale-specific PCI config registers */
> >  #define FSL_PCI_PBFR		0x44
> >
> > -#ifdef CONFIG_SYS_FSL_PCI_VER_3_X
> > +#ifndef CONFIG_SYS_FSL_PCI_VER_3_X
> >  /* Currently only the PCIe capability is used, so hardcode the offset.
> >   * if more capabilities need to be justified, the capability link
> method
> >   * should be applied here
> >   */
> > -#define FSL_PCIE_CAP_ID		0x70
> > -#define PCI_DCR		0x78    /* PCIe Device Control Register */
> > -#define PCI_DSR		0x7a    /* PCIe Device Status Register */
> > -#define PCI_LSR		0x82    /* PCIe Link Status Register */
> > -#define PCI_LCR		0x80    /* PCIe Link Control Register */
> > -#else
> > -#define FSL_PCIE_CAP_ID		0x4c
> > -#define PCI_DCR		0x54    /* PCIe Device Control Register */
> > -#define PCI_DSR		0x56    /* PCIe Device Status Register */
> > -#define PCI_LSR		0x5e    /* PCIe Link Status Register */
> > -#define PCI_LCR		0x5c    /* PCIe Link Control Register */
> >  #define FSL_PCIE_CFG_RDY	0x4b0
> >  #endif
> >  #define FSL_PCI_CFG_READY	1 /* Endpoint: allow inbound configuration
> > */
> > diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
> > index 76337fe..492efcf 100644
> > --- a/drivers/pci/fsl_pci_init.c
> > +++ b/drivers/pci/fsl_pci_init.c
> > @@ -308,6 +308,15 @@ void fsl_pci_init(struct pci_controller *hose,
> > struct fsl_pci_info *pci_info)
> >  	int enabled, r, inbound = 0;
> >  	u16 ltssm;
> >  	u8 temp8, pcie_cap;
> > +	int pcie_cap_pos;
> > +	int pci_dcr;
> > +	int pci_dsr;
> > +	int pci_lsr;
> > +
> > +#if defined(CONFIG_FSL_PCIE_DISABLE_ASPM)
> > +	int pci_lcr;
> > +#endif
> > +
> >  	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *)cfg_addr;
> >  	struct pci_region *reg = hose->regions + hose->region_count;
> >  	pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0); @@ -380,7 +389,12
> > @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info
> > *pci_info)
> >  	hose->region_count++;
> >
> >  	/* see if we are a PCIe or PCI controller */
> > -	pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
> > +	pcie_cap_pos = pci_hose_find_capability(hose, dev, PCI_CAP_ID_EXP);
> > +	pci_dcr = pcie_cap_pos + 0x08;
> > +	pci_dsr = pcie_cap_pos + 0x0a;
> > +	pci_lsr = pcie_cap_pos + 0x12;
> > +
> > +	pci_hose_read_config_byte(hose, dev, pcie_cap_pos, &pcie_cap);
> >
> >  #ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
> >  	/* boot from PCIE --master */
> > @@ -419,15 +433,16 @@ void fsl_pci_init(struct pci_controller *hose,
> > struct fsl_pci_info *pci_info)
> >  					 * - Master PERR (pci)
> >  					 * - ICCA (PCIe)
> >  					 */
> > -	pci_hose_read_config_dword(hose, dev, PCI_DCR, &temp32);
> > +	pci_hose_read_config_dword(hose, dev, pci_dcr, &temp32);
> >  	temp32 |= 0xf000e;		/* set URR, FER, NFER (but not CER)
> > */
> > -	pci_hose_write_config_dword(hose, dev, PCI_DCR, temp32);
> > +	pci_hose_write_config_dword(hose, dev, pci_dcr, temp32);
> >
> >  #if defined(CONFIG_FSL_PCIE_DISABLE_ASPM)
> > +	pci_lcr = pcie_cap_pos + 0x10;
> >  	temp32 = 0;
> > -	pci_hose_read_config_dword(hose, dev, PCI_LCR, &temp32);
> > +	pci_hose_read_config_dword(hose, dev, pci_lcr, &temp32);
> >  	temp32 &= ~0x03;		/* Disable ASPM  */
> > -	pci_hose_write_config_dword(hose, dev, PCI_LCR, temp32);
> > +	pci_hose_write_config_dword(hose, dev, pci_lcr, temp32);
> >  	udelay(1);
> >  #endif
> >  	if (pcie_cap == PCI_CAP_ID_EXP) {
> > @@ -507,7 +522,7 @@ void fsl_pci_init(struct pci_controller *hose,
> > struct fsl_pci_info *pci_info)
> >  		out_be32(&pci->pme_msg_int_en, 0xffffffff);
> >
> >  		/* Print the negotiated PCIe link width */
> > -		pci_hose_read_config_word(hose, dev, PCI_LSR, &temp16);
> > +		pci_hose_read_config_word(hose, dev, pci_lsr, &temp16);
> >  		printf("x%d, regs @ 0x%lx\n", (temp16 & 0x3f0 ) >> 4,
> >  			pci_info->regs);
> >
> > @@ -554,9 +569,9 @@ void fsl_pci_init(struct pci_controller *hose,
> > struct fsl_pci_info *pci_info)
> >  		out_be32(&pci->pme_msg_det, 0xffffffff);
> >  	out_be32(&pci->pedr, 0xffffffff);
> >
> > -	pci_hose_read_config_word (hose, dev, PCI_DSR, &temp16);
> > +	pci_hose_read_config_word(hose, dev, pci_dsr, &temp16);
> >  	if (temp16) {
> > -		pci_hose_write_config_word(hose, dev, PCI_DSR, 0xffff);
> > +		pci_hose_write_config_word(hose, dev, pci_dsr, 0xffff);
> >  	}
> >
> >  	pci_hose_read_config_word (hose, dev, PCI_SEC_STATUS, &temp16); @@
> > -567,10 +582,12 @@ void fsl_pci_init(struct pci_controller *hose,
> > struct fsl_pci_info *pci_info)
> >
> >  int fsl_is_pci_agent(struct pci_controller *hose)  {
> > +	int pcie_cap_pos;
> >  	u8 pcie_cap;
> >  	pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
> >
> > -	pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
> > +	pcie_cap_pos = pci_hose_find_capability(hose, dev, PCI_CAP_ID_EXP);
> > +	pci_hose_read_config_byte(hose, dev, pcie_cap_pos, &pcie_cap);
> >  	if (pcie_cap == PCI_CAP_ID_EXP) {
> >  		u8 header_type;
> >
> > @@ -595,6 +612,7 @@ int fsl_pci_init_port(struct fsl_pci_info *pci_info,
> >  	volatile ccsr_fsl_pci_t *pci;
> >  	struct pci_region *r;
> >  	pci_dev_t dev = PCI_BDF(busno,0,0);
> > +	int pcie_cap_pos;
> >  	u8 pcie_cap;
> >
> >  	pci = (ccsr_fsl_pci_t *) pci_info->regs; @@ -644,7 +662,8 @@ int
> > fsl_pci_init_port(struct fsl_pci_info *pci_info,  #endif
> >  	}
> >
> > -	pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
> > +	pcie_cap_pos = pci_hose_find_capability(hose, dev, PCI_CAP_ID_EXP);
> > +	pci_hose_read_config_byte(hose, dev, pcie_cap_pos, &pcie_cap);
> >  	printf("PCI%s%x: Bus %02x - %02x\n", pcie_cap == PCI_CAP_ID_EXP ?
> >  		"e" : "", pci_info->pci_num,
> >  		hose->first_busno, hose->last_busno); @@ -656,13 +675,14 @@
> int
> > fsl_pci_init_port(struct fsl_pci_info *pci_info,  void
> > fsl_pci_config_unlock(struct pci_controller *hose)  {
> >  	pci_dev_t dev = PCI_BDF(hose->first_busno,0,0);
> > +	int pcie_cap_pos;
> >  	u8 pcie_cap;
> >  	u16 pbfr;
> >
> >  	if (!fsl_is_pci_agent(hose))
> >  		return;
> > -
> > -	pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
> > +	pcie_cap_pos = pci_hose_find_capability(hose, dev, PCI_CAP_ID_EXP);
> > +	pci_hose_read_config_byte(hose, dev, pcie_cap_pos, &pcie_cap);
> >  	if (pcie_cap != 0x0) {
> >  		/* PCIe - set CFG_READY bit of Configuration Ready Register
> */
> > #ifdef CONFIG_SYS_FSL_PCI_VER_3_X diff --git a/drivers/pci/pci.c
> > b/drivers/pci/pci.c index d864f13..c57ea6f 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -738,3 +738,68 @@ void pci_init(void)
> >  	/* now call board specific pci_init()... */
> >  	pci_init_board();
> >  }
> > +
> > +/* Returns the address of the requested capability structure within
> > +the
> > + * device's PCI configuration space or 0 in case the device does not
> > + * support it.
> > + * */
> > +int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t
> dev,
> > +			     int cap)
> > +{
> > +	int pos;
> > +	u8 hdr_type;
> > +
> > +	pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &hdr_type);
> > +
> > +	pos = pci_hose_find_cap_start(hose, dev, hdr_type & 0x7F);
> > +
> > +	if (pos)
> > +		pos = pci_find_cap(hose, dev, pos, cap);
> > +
> > +	return pos;
> > +}
> > +
> > +/* Find the header pointer to the Capabilities*/ int
> > +pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
> > +			    u8 hdr_type)
> > +{
> > +	u16 status;
> > +
> > +	pci_hose_read_config_word(hose, dev, PCI_STATUS, &status);
> > +
> > +	if (!(status & PCI_STATUS_CAP_LIST))
> > +		return 0;
> > +
> > +	switch (hdr_type) {
> > +	case PCI_HEADER_TYPE_NORMAL:
> > +	case PCI_HEADER_TYPE_BRIDGE:
> > +		return PCI_CAPABILITY_LIST;
> > +	case PCI_HEADER_TYPE_CARDBUS:
> > +		return PCI_CB_CAPABILITY_LIST;
> > +	default:
> > +		return 0;
> > +	}
> > +}
> > +
> > +int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos,
> > +int cap) {
> > +	int ttl = PCI_FIND_CAP_TTL;
> > +	u8 id;
> > +	u8 next_pos;
> > +
> > +	while (ttl--) {
> > +		pci_hose_read_config_byte(hose, dev, pos, &next_pos);
> > +		if (next_pos < CAP_START_POS)
> > +			break;
> > +		next_pos &= ~3;
> > +		pos = (int) next_pos;
> > +		pci_hose_read_config_byte(hose, dev,
> > +					  pos + PCI_CAP_LIST_ID, &id);
> > +		if (id == 0xff)
> > +			break;
> > +		if (id == cap)
> > +			return pos;
> > +		pos += PCI_CAP_LIST_NEXT;
> > +	}
> > +	return 0;
> > +}
> > diff --git a/include/pci.h b/include/pci.h index 7e3b3b6..477835e
> > 100644
> > --- a/include/pci.h
> > +++ b/include/pci.h
> > @@ -426,6 +426,9 @@
> >  #define PCI_MAX_PCI_DEVICES	32
> >  #define PCI_MAX_PCI_FUNCTIONS	8
> >
> > +#define PCI_FIND_CAP_TTL 0x48
> > +#define CAP_START_POS 0x40
> > +
> >  /* Include the ID list */
> >
> >  #include <pci_ids.h>
> > @@ -663,6 +666,13 @@ extern int pci_hose_config_device(struct
> > pci_controller *hose,
> >  				  pci_addr_t mem,
> >  				  unsigned long command);
> >
> > +extern int pci_hose_find_capability(struct pci_controller *hose,
> > pci_dev_t dev,
> > +				    int cap);
> > +extern int pci_hose_find_cap_start(struct pci_controller *hose,
> > pci_dev_t dev,
> > +				   u8 hdr_type);
> > +extern int pci_find_cap(struct pci_controller *hose, pci_dev_t dev,
> > +int
> > pos,
> > +			int cap);
> > +
> >  const char * pci_class_str(u8 class);  int pci_last_busno(void);
> >
> > --
> > 1.8.0




More information about the U-Boot mailing list