]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
PCI: rockchip: Disable RC's ASPM L0s based on DT "aspm-no-l0s"
authorShawn Lin <shawn.lin@rock-chips.com>
Thu, 12 Jan 2017 01:53:17 +0000 (09:53 +0800)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 12 Jan 2017 21:31:43 +0000 (15:31 -0600)
Rockchip's RC produces a 100MHz reference clock but there are two methods
for the PHY to generate it:

  (1) Use the system PLL to generate a 100MHz clock.  The PHY will relock
      it, filter signal noise, and output the reference clock.  ASPM L0s
      works correctly, but circuit noise issues make it difficult to pass
      the TX compatibility test.

  (2) Share the SoC's 24MHZ crystal oscillator with the PHY and force the
      PHY's PLL to generate 100MHz internally.  In this case, exit from
      ASPM L0s sometimes fails due to a design error in the RC receiver
      circuit.  Even if we use extended-synch, the PHY sometimes fails to
      relock the bits from FTS, which will hang the system.

We want the flexibility to use both clocking methods, so add a DT property,
"aspm-no-l0s".  If that's present, disable L0s to avoid the issues with
case (2).

[bhelgaas: changelog]
Reported-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Acked-by: Rob Herring <robh@kernel.org>
Documentation/devicetree/bindings/pci/rockchip-pcie.txt
drivers/pci/host/pcie-rockchip.c

index 71aeda1ca05598d74e8db3f429f212d0095f702a..1453a734c2f5b53bf606807e99871619ca132b12 100644 (file)
@@ -43,6 +43,8 @@ Required properties:
 - interrupt-map-mask and interrupt-map: standard PCI properties
 
 Optional Property:
+- aspm-no-l0s: RC won't support ASPM L0s. This property is needed if
+       using 24MHz OSC for RC's PHY.
 - ep-gpios: contain the entry for pre-reset gpio
 - num-lanes: number of lanes to use
 - vpcie3v3-supply: The phandle to the 3.3v regulator to use for PCIe.
index 03923494825d8c61a0b0434ecb4d4bc92b7c2571..0d6e8ee5b0173d073e57ec626b27807891c83160 100644 (file)
 #define   PCIE_RC_CONFIG_DCR_CSPL_SHIFT                18
 #define   PCIE_RC_CONFIG_DCR_CSPL_LIMIT                0xff
 #define   PCIE_RC_CONFIG_DCR_CPLS_SHIFT                26
+#define PCIE_RC_CONFIG_LINK_CAP                (PCIE_RC_CONFIG_BASE + 0xcc)
+#define   PCIE_RC_CONFIG_LINK_CAP_L0S          BIT(10)
 #define PCIE_RC_CONFIG_LCS             (PCIE_RC_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
 #define PCIE_RC_CONFIG_THP_CAP         (PCIE_RC_CONFIG_BASE + 0x274)
@@ -665,6 +667,13 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
        status &= ~PCIE_RC_CONFIG_THP_CAP_NEXT_MASK;
        rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_THP_CAP);
 
+       /* Clear L0s from RC's link cap */
+       if (of_property_read_bool(dev->of_node, "aspm-no-l0s")) {
+               status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LINK_CAP);
+               status &= ~PCIE_RC_CONFIG_LINK_CAP_L0S;
+               rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LINK_CAP);
+       }
+
        rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF);
 
        rockchip_pcie_write(rockchip,