PCI: rockchip: Increase the Max Credit update interval
authorRajat Jain <rajatja@google.com>
Fri, 23 Sep 2016 00:50:42 +0000 (17:50 -0700)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 4 Oct 2016 17:16:03 +0000 (12:16 -0500)
Increase the likelihood of link state to automatically go to L1 and save
some power.

The default credit update interval of 7.5 us results in the rootport
sending UpdateFC-P and UpdateFC-NP packets too often, thus resulting in the
link never going to L1, and always staying in L0/L0s.  The value 24 us was
chosen after some experiments and peeking over the PCIe bus to see that we
do enter L1 substate when there is not enough traffic on the PCIe bus.

Signed-off-by: Rajat Jain <rajatja@google.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Shawn Lin <shawn.lin@rock-chips.com>
drivers/pci/host/pcie-rockchip.c

index 8bedc1e..91f6fa2 100644 (file)
 #define   PCIE_CORE_PL_CONF_SPEED_MASK         0x00000018
 #define   PCIE_CORE_PL_CONF_LANE_MASK          0x00000006
 #define   PCIE_CORE_PL_CONF_LANE_SHIFT         1
+#define PCIE_CORE_TXCREDIT_CFG1                (PCIE_CORE_CTRL_MGMT_BASE + 0x020)
+#define   PCIE_CORE_TXCREDIT_CFG1_MUI_MASK     0xFFFF0000
+#define   PCIE_CORE_TXCREDIT_CFG1_MUI_SHIFT    16
+#define   PCIE_CORE_TXCREDIT_CFG1_MUI_ENCODE(x) \
+               (((x) >> 3) << PCIE_CORE_TXCREDIT_CFG1_MUI_SHIFT)
 #define PCIE_CORE_INT_STATUS           (PCIE_CORE_CTRL_MGMT_BASE + 0x20c)
 #define   PCIE_CORE_INT_PRFPE                  BIT(0)
 #define   PCIE_CORE_INT_CRFPE                  BIT(1)
@@ -224,6 +229,17 @@ static void rockchip_pcie_clr_bw_int(struct rockchip_pcie *rockchip)
        rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS);
 }
 
+static void rockchip_pcie_update_txcredit_mui(struct rockchip_pcie *rockchip)
+{
+       u32 val;
+
+       /* Update Tx credit maximum update interval */
+       val = rockchip_pcie_read(rockchip, PCIE_CORE_TXCREDIT_CFG1);
+       val &= ~PCIE_CORE_TXCREDIT_CFG1_MUI_MASK;
+       val |= PCIE_CORE_TXCREDIT_CFG1_MUI_ENCODE(24000);       /* ns */
+       rockchip_pcie_write(rockchip, val, PCIE_CORE_TXCREDIT_CFG1);
+}
+
 static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip,
                                      struct pci_bus *bus, int dev)
 {
@@ -597,6 +613,7 @@ static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg)
                rockchip_pcie_write(rockchip, sub_reg, PCIE_CORE_INT_STATUS);
        } else if (reg & PCIE_CLIENT_INT_PHY) {
                dev_dbg(dev, "phy link changes\n");
+               rockchip_pcie_update_txcredit_mui(rockchip);
                rockchip_pcie_clr_bw_int(rockchip);
        }