From c1f6fd2bb7fa19ec166584c1cce50b5fde93e8ac Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Tue, 6 Jul 2021 10:19:09 -0700 Subject: [PATCH] pci: imx: use reset-gpios if defined by device-tree If reset-gpio is defined by device-tree use that if CONFIG_PCIE_IMX_PERST_GPIO is not defined. Note that after this the following boards which define CONFIG_PCIE_IMX_PERST_GPIO in their board header file as well as their device-tree should be able to remove CONFIG_PCIE_IMX_PERST_GPIO without consequence: - mx6sabresd - mx6sxsabresd - novena - tbs2910 - vining_2000 Note that the ge_bx50v3 board uses CONFIG_PCIE_IMX_PERST_GPIO and does not have reset-gpios defined it it's pcie node in the dt thus removing CONFIG_PCIE_IMX_PERST_GPIO globally can't be done until that board adds reset-gpios. Cc: Ian Ray (maintainer:GE BX50V3 BOARD) Cc: Sebastian Reichel (maintainer:GE BX50V3 BOARD) Cc: Fabio Estevam (maintainer:MX6SABRESD BOARD) Cc: Marek Vasut (maintainer:NOVENA BOARD) Cc: Soeren Moch (maintainer:TBS2910 BOARD) Cc: Silvio Fricke (maintainer:VINING_2000 BOARD) Signed-off-by: Tim Harvey --- arch/arm/include/asm/arch-mx6/sys_proto.h | 3 ++- board/gateworks/gw_ventana/gw_ventana.c | 2 +- drivers/pci/pcie_imx.c | 29 ++++++++++++++++++++++++----- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 1e5fa1a..c49759a 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -7,6 +7,7 @@ #ifndef __SYS_PROTO_IMX6_ #define __SYS_PROTO_IMX6_ +#include #include #include @@ -18,7 +19,7 @@ USBPHY_PWD_RXPWDRX)) int imx6_pcie_toggle_power(void); -int imx6_pcie_toggle_reset(void); +int imx6_pcie_toggle_reset(struct gpio_desc *gpio, bool active_high); enum ldo_reg { LDO_ARM, diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 583f1a2..468fb09 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -372,7 +372,7 @@ int power_init_board(void) return 0; } -int imx6_pcie_toggle_reset(void) +int imx6_pcie_toggle_reset(struct gpio_desc *gpio, bool active_high) { if (board_type < GW_UNKNOWN) { uint pin = gpio_cfg[board_type].pcie_rst; diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 73875e0..7b46fdb 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 reset_active_high; }; /* @@ -541,7 +543,7 @@ __weak int imx6_pcie_toggle_power(void) return 0; } -__weak int imx6_pcie_toggle_reset(void) +__weak int imx6_pcie_toggle_reset(struct gpio_desc *gpio, bool active_high) { /* * See 'PCI EXPRESS BASE SPECIFICATION, REV 3.0, SECTION 6.6.1' @@ -579,12 +581,20 @@ __weak int imx6_pcie_toggle_reset(void) mdelay(20); gpio_free(CONFIG_PCIE_IMX_PERST_GPIO); #else - puts("WARNING: Make sure the PCIe #PERST line is connected!\n"); + if (dm_gpio_is_valid(gpio)) { + /* Assert PERST# for 20ms then de-assert */ + dm_gpio_set_value(gpio, active_high ? 0 : 1); + mdelay(20); + dm_gpio_set_value(gpio, active_high ? 1 : 0); + mdelay(20); + } else { + puts("WARNING: Make sure the PCIe #PERST line is connected!\n"); + } #endif 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 +622,7 @@ static int imx6_pcie_deassert_core_reset(void) setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN); #endif - imx6_pcie_toggle_reset(); + imx6_pcie_toggle_reset(&priv->reset_gpio, priv->reset_active_high); return 0; } @@ -625,7 +635,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 +797,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->reset_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->reset_active_high ? 0 : 1); + } + return imx_pcie_link_up(priv); } -- 2.7.4