From d43b47a114c8504fc057bfd088831023112b4fa2 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 20 May 2021 08:52:35 +0800 Subject: [PATCH] PCI: rockchip: dw: Reset device before enabling power To more precisely follow the spec, we should make sure refclk is available and stable for device only after stable training. In previous way, if the refclk is provided by external chip, enabling power means refclk is ready before anything, and then we reset the device to hope the chip back to the initial state. But we find some devices are not really meant to do that, that being said, the spec is vague here so we can't make any promise from the vendor that #PERST will take everything back. Move resetting device before enabling power to restrictly follow the spec, no matter whether #PERST is work or not, we just rely on the power control. Fixes: c84a4aa411b2 ("PCI: rockchip: dw: Move deassert #PERST after enabling LTSSM") Signed-off-by: Shawn Lin Change-Id: Ie1f4aa1a3fb7b6de813512bf4b2c025328e0c17f --- drivers/pci/controller/dwc/pcie-dw-rockchip.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index 901281fa122c..fdc3597ed6d5 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -443,9 +443,6 @@ static int rk_pcie_establish_link(struct dw_pcie *pci) return 0; } - /* Rest the device */ - gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0); - rk_pcie_disable_ltssm(rk_pcie); rk_pcie_link_status_clear(rk_pcie); rk_pcie_enable_debug(rk_pcie); @@ -1286,6 +1283,16 @@ static int rk_pcie_really_probe(void *p) dev_info(dev, "no vpcie3v3 regulator found\n"); } + /* + * Rest the device before enabling power because some of the + * platforms may use external refclk input with the some power + * rail connect to 100MHz OSC chip. So once the power is up for + * the slot and the refclk is available, which isn't quite follow + * the spec. We should make sure it is in reset state before + * everthing's ready. + */ + gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0); + ret = rk_pcie_enable_power(rk_pcie); if (ret) return ret;