Skip to content

Commit 198e69c

Browse files
shawn1221Mani-Sadhasivam
authored andcommitted
PCI: dw-rockchip: Enable ASPM L0s capability for both RC and EP modes
L0s capability isn't enabled on all Rockchip SoCs by default, so enable it in order to make ASPM L0s work on Rockchip platforms. Testing the L0s for a long time revealed that the default N_FTS value of 210 in the hardware doesn't work stable and causes LTSSM to switch between L0s and Recovery states. This leads to long exit latency and also causes link down sometimes. So override the value to the max 255, which seems to work fine under both PHYs used on Rockchip platforms. Signed-off-by: Shawn Lin <[email protected]> [mani: subject and description rewording] Signed-off-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Niklas Cassel <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent 7d9b5d6 commit 198e69c

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

drivers/pci/controller/dwc/pcie-dw-rockchip.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,21 @@ static int rockchip_pcie_link_up(struct dw_pcie *pci)
182182
return 0;
183183
}
184184

185+
static void rockchip_pcie_enable_l0s(struct dw_pcie *pci)
186+
{
187+
u32 cap, lnkcap;
188+
189+
/* Enable L0S capability for all SoCs */
190+
cap = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
191+
if (cap) {
192+
lnkcap = dw_pcie_readl_dbi(pci, cap + PCI_EXP_LNKCAP);
193+
lnkcap |= PCI_EXP_LNKCAP_ASPM_L0S;
194+
dw_pcie_dbi_ro_wr_en(pci);
195+
dw_pcie_writel_dbi(pci, cap + PCI_EXP_LNKCAP, lnkcap);
196+
dw_pcie_dbi_ro_wr_dis(pci);
197+
}
198+
}
199+
185200
static int rockchip_pcie_start_link(struct dw_pcie *pci)
186201
{
187202
struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
@@ -231,6 +246,8 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
231246
irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
232247
rockchip);
233248

249+
rockchip_pcie_enable_l0s(pci);
250+
234251
return 0;
235252
}
236253

@@ -271,6 +288,8 @@ static void rockchip_pcie_ep_init(struct dw_pcie_ep *ep)
271288
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
272289
enum pci_barno bar;
273290

291+
rockchip_pcie_enable_l0s(pci);
292+
274293
for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
275294
dw_pcie_ep_reset_bar(pci, bar);
276295
};
@@ -599,6 +618,10 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
599618
rockchip->pci.ops = &dw_pcie_ops;
600619
rockchip->data = data;
601620

621+
/* Default N_FTS value (210) is broken, override it to 255 */
622+
rockchip->pci.n_fts[0] = 255; /* Gen1 */
623+
rockchip->pci.n_fts[1] = 255; /* Gen2+ */
624+
602625
ret = rockchip_pcie_resource_get(pdev, rockchip);
603626
if (ret)
604627
return ret;

0 commit comments

Comments
 (0)