If reset-gpio is defined by device-tree use that instead of a board-specific function to toggle PCI reset.
The presense of 'reset-gpio' in the device-tree will override calling the weak imx6_pcie_toggle_reset function therefore I've Cc'd all the board maintainers who rely on that function here as I would like to remove that function completely. The only user of a board-specific weak imx6_pcie_toggle_reset is gwventana which I am the maintainer for and once this patch is accepted I will be able to remove that use case and would then like to remove the use of CONFIG_PCIE_IMX_PERST_GPIO completely. I would have preferred implementing this without changing the codepath for the users of CONFIG_PCIE_IMX_PERST_GPIO but that would require passing in the imx_pcie_priv struct to imx6_pcie_toggle_reset which creates a chicken-and-egg scenario as that's currently a weak function for boards to override. Cc: Ian Ray <ian....@ge.com> (maintainer:GE BX50V3 BOARD) Cc: Sebastian Reichel <sebastian.reic...@collabora.com> (maintainer:GE BX50V3 BOARD) Cc: Fabio Estevam <feste...@gmail.com> (maintainer:MX6SABRESD BOARD) Cc: Marek Vasut <ma...@denx.de> (maintainer:NOVENA BOARD) Cc: Soeren Moch <sm...@web.de> (maintainer:TBS2910 BOARD) Cc: Silvio Fricke <open-sou...@softing.de> (maintainer:VINING_2000 BOARD) Signed-off-by: Tim Harvey <thar...@gateworks.com> --- drivers/pci/pcie_imx.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 73875e00db..c28951655d 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -100,6 +100,8 @@ struct imx_pcie_priv { void __iomem *dbi_base; void __iomem *cfg_base; + struct gpio_desc reset_gpio; + bool gpio_active_high; }; /* @@ -584,7 +586,7 @@ __weak int imx6_pcie_toggle_reset(void) return 0; } -static int imx6_pcie_deassert_core_reset(void) +static int imx6_pcie_deassert_core_reset(struct imx_pcie_priv *priv) { struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; @@ -612,7 +614,14 @@ static int imx6_pcie_deassert_core_reset(void) setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN); #endif - imx6_pcie_toggle_reset(); + if (dm_gpio_is_valid(&priv->reset_gpio)) { + /* Assert PERST# for 50ms then de-assert */ + dm_gpio_set_value(&priv->reset_gpio, priv->gpio_active_high ? 0 : 1); + mdelay(50); + dm_gpio_set_value(&priv->reset_gpio, priv->gpio_active_high ? 1 : 0); + } else { + imx6_pcie_toggle_reset(); + } return 0; } @@ -625,7 +634,7 @@ static int imx_pcie_link_up(struct imx_pcie_priv *priv) imx6_pcie_assert_core_reset(priv, false); imx6_pcie_init_phy(); - imx6_pcie_deassert_core_reset(); + imx6_pcie_deassert_core_reset(priv); imx_pcie_regions_setup(priv); @@ -787,6 +796,15 @@ static int imx_pcie_dm_probe(struct udevice *dev) { struct imx_pcie_priv *priv = dev_get_priv(dev); + /* if PERST# valid from dt then assert it */ + gpio_request_by_name(dev, "reset-gpio", 0, &priv->reset_gpio, + GPIOD_IS_OUT); + priv->gpio_active_high = dev_read_bool(dev, "reset-gpio-active-high"); + if (dm_gpio_is_valid(&priv->reset_gpio)) { + dm_gpio_set_value(&priv->reset_gpio, + priv->gpio_active_high ? 0 : 1); + } + return imx_pcie_link_up(priv); } -- 2.17.1