144-PCI-iproc-Improve-link-detection-logic.patch 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. From aaf22ab4e916afa68a2e1aed4e913b76cbd58276 Mon Sep 17 00:00:00 2001
  2. From: Ray Jui <rjui@broadcom.com>
  3. Date: Tue, 15 Sep 2015 17:39:19 -0700
  4. Subject: [PATCH 144/147] PCI: iproc: Improve link detection logic
  5. Improve the link detection logic by explicitly querying the link status
  6. register to ensure link is active.
  7. Also force class to PCI_CLASS_BRIDGE_PCI (0x0604) through the host
  8. configuration space register.
  9. Signed-off-by: Ray Jui <rjui@broadcom.com>
  10. Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
  11. Reviewed-by: Anup Patel <anup.patel@broadcom.com>
  12. Reviewed-by: Scott Branden <sbranden@broadcom.com>
  13. ---
  14. drivers/pci/host/pcie-iproc.c | 29 +++++++++++++++++++++++------
  15. 1 file changed, 23 insertions(+), 6 deletions(-)
  16. --- a/drivers/pci/host/pcie-iproc.c
  17. +++ b/drivers/pci/host/pcie-iproc.c
  18. @@ -60,6 +60,12 @@
  19. #define SYS_RC_INTX_EN 0x330
  20. #define SYS_RC_INTX_MASK 0xf
  21. +#define PCIE_LINK_STATUS_OFFSET 0xf0c
  22. +#define PCIE_PHYLINKUP_SHIFT 3
  23. +#define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT)
  24. +#define PCIE_DL_ACTIVE_SHIFT 2
  25. +#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
  26. +
  27. static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
  28. {
  29. struct iproc_pcie *pcie;
  30. @@ -138,9 +144,15 @@ static void iproc_pcie_reset(struct ipro
  31. static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
  32. {
  33. u8 hdr_type;
  34. - u32 link_ctrl;
  35. + u32 link_ctrl, class, val;
  36. u16 pos, link_status;
  37. - int link_is_active = 0;
  38. + bool link_is_active = false;
  39. +
  40. + val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
  41. + if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
  42. + dev_err(pcie->dev, "PHY or data link is INACTIVE!\n");
  43. + return -ENODEV;
  44. + }
  45. /* make sure we are not in EP mode */
  46. pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type);
  47. @@ -150,14 +162,19 @@ static int iproc_pcie_check_link(struct
  48. }
  49. /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
  50. - pci_bus_write_config_word(bus, 0, PCI_CLASS_DEVICE,
  51. - PCI_CLASS_BRIDGE_PCI);
  52. +#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
  53. +#define PCI_CLASS_BRIDGE_MASK 0xffff00
  54. +#define PCI_CLASS_BRIDGE_SHIFT 8
  55. + pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class);
  56. + class &= ~PCI_CLASS_BRIDGE_MASK;
  57. + class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
  58. + pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class);
  59. /* check link status to see if link is active */
  60. pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP);
  61. pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status);
  62. if (link_status & PCI_EXP_LNKSTA_NLW)
  63. - link_is_active = 1;
  64. + link_is_active = true;
  65. if (!link_is_active) {
  66. /* try GEN 1 link speed */
  67. @@ -181,7 +198,7 @@ static int iproc_pcie_check_link(struct
  68. pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA,
  69. &link_status);
  70. if (link_status & PCI_EXP_LNKSTA_NLW)
  71. - link_is_active = 1;
  72. + link_is_active = true;
  73. }
  74. }