The 'reset-gpios' property specified in the device-tree corresponds to
the PCI PERST# signal that is used to reset a PCI Endpoint. Since the
on-board circuitry may not reset the PCI Endpoint, fetch the 'reset-gpios'
device-tree property and toggle the GPIO line corresponding to the PERST#
signal to enable the PCI Endpoint. In the absence of the 'reset-gpios'
property in the device-tree, existing behavior is retained rather than
returning an error.

Signed-off-by: Siddharth Vadapalli <[email protected]>
---
 drivers/pci/pcie_dw_ti.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/pci/pcie_dw_ti.c b/drivers/pci/pcie_dw_ti.c
index fb39132f7c1..a34b142bbfb 100644
--- a/drivers/pci/pcie_dw_ti.c
+++ b/drivers/pci/pcie_dw_ti.c
@@ -58,6 +58,7 @@ struct pcie_dw_ti {
        /* Must be first member of the struct */
        struct pcie_dw dw;
        void *app_base;
+       struct gpio_desc rst_gpio;
        u32 num_lanes;
 };
 
@@ -252,6 +253,17 @@ static int pcie_dw_ti_probe(struct udevice *dev)
                return ret;
        }
 
+       ret = gpio_request_by_name(dev, "reset-gpios", 0, &pci->rst_gpio,
+                                  GPIOD_IS_OUT);
+       if (ret && ret != -ENOENT) {
+               dev_err(dev, "failed to get reset-gpios\n");
+               return ret;
+       }
+
+       /* Keep the reset-line asserted until the PCI Controller is ready */
+       if (dm_gpio_is_valid(&pci->rst_gpio))
+               dm_gpio_set_value(&pci->rst_gpio, 1);
+
        ret = generic_phy_get_by_name(dev,  "pcie-phy0", &phy0);
        if (ret) {
                dev_err(dev, "Unable to get phy0");
@@ -281,6 +293,15 @@ static int pcie_dw_ti_probe(struct udevice *dev)
 
        dw_pcie_link_set_max_link_width(&pci->dw, pci->num_lanes);
 
+       /*
+        * The reset-gpio (PERST#) should be held deasserted for at-least 100 ms
+        * before the link is brought up.
+        */
+       if (dm_gpio_is_valid(&pci->rst_gpio)) {
+               dm_gpio_set_value(&pci->rst_gpio, 0);
+               mdelay(100);
+       }
+
        if (!pcie_dw_ti_pcie_link_up(pci, LINK_SPEED_GEN_2)) {
                printf("PCIE-%d: Link down\n", dev_seq(dev));
                return -ENODEV;
-- 
2.51.1

Reply via email to