Patchwork [U-Boot] fsl_pci: use 'Header Type' field to judge PCIE mode

login
register
mail settings
Submitter Minghuan Lian
Date Aug. 22, 2012, 9:35 a.m.
Message ID <1345628142-15303-1-git-send-email-Minghuan.Lian@freescale.com>
Download mbox | patch
Permalink /patch/179564/
State Accepted, archived
Delegated to: Andy Fleming
Headers show

Comments

Minghuan Lian - Aug. 22, 2012, 9:35 a.m.
The original code uses 'Programming Interface' field to judge if PCIE is
EP or RC mode, however, T4240 does not support this functionality.
According to PCIE specification, 'Header Type' offset 0x0e is used to
indicate header type, so for PCIE controller, the patch changes code to
use 'Header Type' field to identify if the PCIE is EP or RC mode.

Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
---
 drivers/pci/fsl_pci_init.c |   30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

Patch

diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
index 1d75a82..0c61f5c 100644
--- a/drivers/pci/fsl_pci_init.c
+++ b/drivers/pci/fsl_pci_init.c
@@ -1,5 +1,5 @@ 
 /*
- * Copyright 2007-2011 Freescale Semiconductor, Inc.
+ * Copyright 2007-2012 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -393,13 +393,7 @@  void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info)
 	}
 
 #ifndef CONFIG_PCI_NOSCAN
-	pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &temp8);
-
-	/* Programming Interface (PCI_CLASS_PROG)
-	 * 0 == pci host or pcie root-complex,
-	 * 1 == pci agent or pcie end-point
-	 */
-	if (!temp8) {
+	if (!fsl_is_pci_agent(hose)) {
 		debug("           Scanning PCI bus %02x\n",
 			hose->current_busno);
 		hose->last_busno = pci_hose_scan_bus(hose, hose->current_busno);
@@ -437,12 +431,22 @@  void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info)
 
 int fsl_is_pci_agent(struct pci_controller *hose)
 {
-	u8 prog_if;
+	u8 pcie_cap;
 	pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
 
-	pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prog_if);
+	pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
+	if (pcie_cap == PCI_CAP_ID_EXP) {
+		u8 header_type;
+
+		pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE,
+					  &header_type);
+		return (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
+	} else {
+		u8 prog_if;
 
-	return (prog_if == FSL_PROG_IF_AGENT);
+		pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prog_if);
+		return (prog_if == FSL_PROG_IF_AGENT);
+	}
 }
 
 int fsl_pci_init_port(struct fsl_pci_info *pci_info,
@@ -502,12 +506,10 @@  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);
-	u8 agent;
 	u8 pcie_cap;
 	u16 pbfr;
 
-	pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &agent);
-	if (!agent)
+	if (!fsl_is_pci_agent(hose))
 		return;
 
 	pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);