mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	This updates the iProc PCIe driver to the version currently submitted for kernel 4.5. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> SVN-Revision: 47688
		
			
				
	
	
		
			85 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From aaf22ab4e916afa68a2e1aed4e913b76cbd58276 Mon Sep 17 00:00:00 2001
 | |
| From: Ray Jui <rjui@broadcom.com>
 | |
| Date: Tue, 15 Sep 2015 17:39:19 -0700
 | |
| Subject: [PATCH 144/147] PCI: iproc: Improve link detection logic
 | |
| 
 | |
| Improve the link detection logic by explicitly querying the link status
 | |
| register to ensure link is active.
 | |
| 
 | |
| Also force class to PCI_CLASS_BRIDGE_PCI (0x0604) through the host
 | |
| configuration space register.
 | |
| 
 | |
| Signed-off-by: Ray Jui <rjui@broadcom.com>
 | |
| Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
 | |
| Reviewed-by: Anup Patel <anup.patel@broadcom.com>
 | |
| Reviewed-by: Scott Branden <sbranden@broadcom.com>
 | |
| ---
 | |
|  drivers/pci/host/pcie-iproc.c | 29 +++++++++++++++++++++++------
 | |
|  1 file changed, 23 insertions(+), 6 deletions(-)
 | |
| 
 | |
| --- a/drivers/pci/host/pcie-iproc.c
 | |
| +++ b/drivers/pci/host/pcie-iproc.c
 | |
| @@ -60,6 +60,12 @@
 | |
|  #define SYS_RC_INTX_EN               0x330
 | |
|  #define SYS_RC_INTX_MASK             0xf
 | |
|  
 | |
| +#define PCIE_LINK_STATUS_OFFSET      0xf0c
 | |
| +#define PCIE_PHYLINKUP_SHIFT         3
 | |
| +#define PCIE_PHYLINKUP               BIT(PCIE_PHYLINKUP_SHIFT)
 | |
| +#define PCIE_DL_ACTIVE_SHIFT         2
 | |
| +#define PCIE_DL_ACTIVE               BIT(PCIE_DL_ACTIVE_SHIFT)
 | |
| +
 | |
|  static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
 | |
|  {
 | |
|  	struct iproc_pcie *pcie;
 | |
| @@ -138,9 +144,15 @@ static void iproc_pcie_reset(struct ipro
 | |
|  static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
 | |
|  {
 | |
|  	u8 hdr_type;
 | |
| -	u32 link_ctrl;
 | |
| +	u32 link_ctrl, class, val;
 | |
|  	u16 pos, link_status;
 | |
| -	int link_is_active = 0;
 | |
| +	bool link_is_active = false;
 | |
| +
 | |
| +	val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
 | |
| +	if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
 | |
| +		dev_err(pcie->dev, "PHY or data link is INACTIVE!\n");
 | |
| +		return -ENODEV;
 | |
| +	}
 | |
|  
 | |
|  	/* make sure we are not in EP mode */
 | |
|  	pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type);
 | |
| @@ -150,14 +162,19 @@ static int iproc_pcie_check_link(struct
 | |
|  	}
 | |
|  
 | |
|  	/* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
 | |
| -	pci_bus_write_config_word(bus, 0, PCI_CLASS_DEVICE,
 | |
| -				  PCI_CLASS_BRIDGE_PCI);
 | |
| +#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
 | |
| +#define PCI_CLASS_BRIDGE_MASK      0xffff00
 | |
| +#define PCI_CLASS_BRIDGE_SHIFT     8
 | |
| +	pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class);
 | |
| +	class &= ~PCI_CLASS_BRIDGE_MASK;
 | |
| +	class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
 | |
| +	pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class);
 | |
|  
 | |
|  	/* check link status to see if link is active */
 | |
|  	pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP);
 | |
|  	pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status);
 | |
|  	if (link_status & PCI_EXP_LNKSTA_NLW)
 | |
| -		link_is_active = 1;
 | |
| +		link_is_active = true;
 | |
|  
 | |
|  	if (!link_is_active) {
 | |
|  		/* try GEN 1 link speed */
 | |
| @@ -181,7 +198,7 @@ static int iproc_pcie_check_link(struct
 | |
|  			pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA,
 | |
|  						 &link_status);
 | |
|  			if (link_status & PCI_EXP_LNKSTA_NLW)
 | |
| -				link_is_active = 1;
 | |
| +				link_is_active = true;
 | |
|  		}
 | |
|  	}
 | |
|  
 |