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: 'tr...@ti.com' > Cc: u-boot@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@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 <b45...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot