lantiq: use gpiod API for PCIe GPIO reset

This is the recommended way for the OF based platform. According to
the original patch, set GPIO to low level to assert the reset, set
GPIO to high level to deassert. Hence, adjust the dts GPIO polarity
to active-low.

Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/18948
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
This commit is contained in:
Shiji Yang
2025-05-28 00:32:56 +08:00
committed by Jonas Jelonek
parent 8b5702e328
commit 7ff96bf05c
11 changed files with 57 additions and 55 deletions
+1 -1
View File
@@ -537,7 +537,7 @@
device_type = "pci";
gpio-reset = <&gpio 38 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
};
pci0: pci@e105400 {
@@ -235,7 +235,7 @@
&pcie0 {
status = "okay";
gpio-reset = <&gpio 21 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
};
&usb_phy0 {
@@ -339,7 +339,7 @@
&pcie0 {
status = "okay";
gpio-reset = <&gpio 25 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
};
&usb_phy0 {
@@ -203,7 +203,7 @@
};
&pcie0 {
gpio-reset = <&gpio 21 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
pcie@0 {
reg = <0 0 0 0 0>;
@@ -283,7 +283,7 @@
&pcie0 {
status = "okay";
gpio-reset = <&gpio 21 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
pcie@0 {
reg = <0 0 0 0 0>;
@@ -105,7 +105,7 @@
};
&pcie0 {
gpio-reset = <&gpio 21 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
};
&eth0 {
@@ -152,7 +152,7 @@
&pcie0 {
status = "okay";
gpio-reset = <&gpio 11 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
pcie@0 {
reg = <0 0 0 0 0>;
@@ -164,7 +164,7 @@
&pcie0 {
status = "okay";
gpio-reset = <&gpio 11 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
pcie@0 {
reg = <0 0 0 0 0>;
@@ -171,6 +171,6 @@
&pcie0 {
status = "okay";
gpio-reset = <&gpio 21 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
lantiq,switch-pcie-endianess;
};
@@ -33,7 +33,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/platform_device.h>
+
#include "ifxmips_pcie.h"
@@ -55,7 +55,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
static DEFINE_SPINLOCK(ifx_pcie_lock);
u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
+static int pcie_reset_gpio;
+static struct gpio_desc *reset_gpio;
+static struct phy *ltq_pcie_phy;
+static struct reset_control *ltq_pcie_reset;
+static struct regmap *ltq_rcu_regmap;
@@ -87,30 +87,32 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
},
},
},
@@ -82,6 +84,22 @@ void ifx_pcie_debug(const char *fmt, ...
@@ -82,6 +84,24 @@ void ifx_pcie_debug(const char *fmt, ...
printk("%s", buf);
}
+static inline void pcie_ep_gpio_rst_init(int pcie_port)
+{
+ gpio_direction_output(pcie_reset_gpio, 1);
+ gpio_set_value(pcie_reset_gpio, 1);
+ if (reset_gpio)
+ gpiod_set_value_cansleep(reset_gpio, 0);
+}
+
+static inline void pcie_device_rst_assert(int pcie_port)
+{
+ gpio_set_value(pcie_reset_gpio, 0);
+ if (reset_gpio)
+ gpiod_set_value_cansleep(reset_gpio, 1);
+}
+
+static inline void pcie_device_rst_deassert(int pcie_port)
+{
+ mdelay(100);
+ gpio_direction_output(pcie_reset_gpio, 1);
+ if (reset_gpio)
+ gpiod_set_value_cansleep(reset_gpio, 0);
+}
static inline int pcie_ltssm_enable(int pcie_port)
{
@@ -857,7 +875,8 @@ pcie_rc_core_int_init(int pcie_port)
@@ -857,7 +877,8 @@ pcie_rc_core_int_init(int pcie_port)
ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, 0,
pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
if (ret)
@@ -120,7 +122,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
return ret;
}
@@ -988,10 +1007,26 @@ int ifx_pcie_bios_plat_dev_init(struct
@@ -988,10 +1009,26 @@ int ifx_pcie_bios_plat_dev_init(struct
static int
pcie_rc_initialize(int pcie_port)
{
@@ -149,7 +151,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
pcie_ep_gpio_rst_init(pcie_port);
@@ -1000,26 +1035,21 @@ pcie_rc_initialize(int pcie_port)
@@ -1000,26 +1037,21 @@ pcie_rc_initialize(int pcie_port)
* reset PCIe PHY will solve this issue
*/
for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
@@ -186,7 +188,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
/* Enable PCIe PHY and Clock */
pcie_core_pmu_setup(pcie_port);
@@ -1035,6 +1065,10 @@ pcie_rc_initialize(int pcie_port)
@@ -1035,6 +1067,10 @@ pcie_rc_initialize(int pcie_port)
/* Once link is up, break out */
if (pcie_app_loigc_setup(pcie_port) == 0)
break;
@@ -197,7 +199,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
}
if (i >= IFX_PCIE_PHY_LOOP_CNT) {
printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
@@ -1045,17 +1079,73 @@ pcie_rc_initialize(int pcie_port)
@@ -1045,17 +1081,72 @@ pcie_rc_initialize(int pcie_port)
return 0;
}
@@ -260,20 +262,19 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
+ if (IS_ERR(ltq_rcu_regmap))
+ return PTR_ERR(ltq_rcu_regmap);
+
+ pcie_reset_gpio = of_get_named_gpio(node, "gpio-reset", 0);
+ if (gpio_is_valid(pcie_reset_gpio)) {
+ int ret = devm_gpio_request(&pdev->dev, pcie_reset_gpio, "pcie-reset");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request gpio %d\n", pcie_reset_gpio);
+ return ret;
+ }
+ gpio_direction_output(pcie_reset_gpio, 1);
+ }
+ reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(reset_gpio))
+ return dev_err_probe(&pdev->dev, PTR_ERR(reset_gpio),
+ "failed to request reset gpio\n");
+
+ if (reset_gpio)
+ gpiod_set_consumer_name(reset_gpio, "pcie-reset");
+
for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
if (pcie_rc_initialize(pcie_port) == 0) {
IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
@@ -1066,7 +1156,19 @@ static int __init ifx_pcie_bios_init(voi
@@ -1066,7 +1157,19 @@ static int __init ifx_pcie_bios_init(voi
IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
return -ENOMEM;
}
@@ -293,7 +294,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
/* XXX, clear error status */
@@ -1083,6 +1185,29 @@ static int __init ifx_pcie_bios_init(voi
@@ -1083,6 +1186,29 @@ static int __init ifx_pcie_bios_init(voi
return 0;
}
@@ -33,7 +33,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/platform_device.h>
+
#include "ifxmips_pcie.h"
@@ -55,7 +55,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
static DEFINE_SPINLOCK(ifx_pcie_lock);
u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
+static int pcie_reset_gpio;
+static struct gpio_desc *reset_gpio;
+static struct phy *ltq_pcie_phy;
+static struct reset_control *ltq_pcie_reset;
+static struct regmap *ltq_rcu_regmap;
@@ -87,30 +87,32 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
},
},
},
@@ -82,6 +84,22 @@ void ifx_pcie_debug(const char *fmt, ...
@@ -82,6 +84,24 @@ void ifx_pcie_debug(const char *fmt, ...
printk("%s", buf);
}
+static inline void pcie_ep_gpio_rst_init(int pcie_port)
+{
+ gpio_direction_output(pcie_reset_gpio, 1);
+ gpio_set_value(pcie_reset_gpio, 1);
+ if (reset_gpio)
+ gpiod_set_value_cansleep(reset_gpio, 0);
+}
+
+static inline void pcie_device_rst_assert(int pcie_port)
+{
+ gpio_set_value(pcie_reset_gpio, 0);
+ if (reset_gpio)
+ gpiod_set_value_cansleep(reset_gpio, 1);
+}
+
+static inline void pcie_device_rst_deassert(int pcie_port)
+{
+ mdelay(100);
+ gpio_direction_output(pcie_reset_gpio, 1);
+ if (reset_gpio)
+ gpiod_set_value_cansleep(reset_gpio, 0);
+}
static inline int pcie_ltssm_enable(int pcie_port)
{
@@ -857,7 +875,8 @@ pcie_rc_core_int_init(int pcie_port)
@@ -857,7 +877,8 @@ pcie_rc_core_int_init(int pcie_port)
ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, 0,
pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
if (ret)
@@ -120,7 +122,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
return ret;
}
@@ -988,10 +1007,26 @@ int ifx_pcie_bios_plat_dev_init(struct
@@ -988,10 +1009,26 @@ int ifx_pcie_bios_plat_dev_init(struct
static int
pcie_rc_initialize(int pcie_port)
{
@@ -149,7 +151,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
pcie_ep_gpio_rst_init(pcie_port);
@@ -1000,26 +1035,21 @@ pcie_rc_initialize(int pcie_port)
@@ -1000,26 +1037,21 @@ pcie_rc_initialize(int pcie_port)
* reset PCIe PHY will solve this issue
*/
for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
@@ -186,7 +188,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
/* Enable PCIe PHY and Clock */
pcie_core_pmu_setup(pcie_port);
@@ -1035,6 +1065,10 @@ pcie_rc_initialize(int pcie_port)
@@ -1035,6 +1067,10 @@ pcie_rc_initialize(int pcie_port)
/* Once link is up, break out */
if (pcie_app_loigc_setup(pcie_port) == 0)
break;
@@ -197,7 +199,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
}
if (i >= IFX_PCIE_PHY_LOOP_CNT) {
printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
@@ -1045,17 +1079,73 @@ pcie_rc_initialize(int pcie_port)
@@ -1045,17 +1081,72 @@ pcie_rc_initialize(int pcie_port)
return 0;
}
@@ -260,20 +262,19 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
+ if (IS_ERR(ltq_rcu_regmap))
+ return PTR_ERR(ltq_rcu_regmap);
+
+ pcie_reset_gpio = of_get_named_gpio(node, "gpio-reset", 0);
+ if (gpio_is_valid(pcie_reset_gpio)) {
+ int ret = devm_gpio_request_one(&pdev->dev, pcie_reset_gpio, GPIOF_OUT_INIT_HIGH, "pcie-reset");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request gpio %d\n", pcie_reset_gpio);
+ return ret;
+ }
+ gpio_direction_output(pcie_reset_gpio, 1);
+ }
+ reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(reset_gpio))
+ return dev_err_probe(&pdev->dev, PTR_ERR(reset_gpio),
+ "failed to request reset gpio\n");
+
+ if (reset_gpio)
+ gpiod_set_consumer_name(reset_gpio, "pcie-reset");
+
for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
if (pcie_rc_initialize(pcie_port) == 0) {
IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
@@ -1066,7 +1156,19 @@ static int __init ifx_pcie_bios_init(voi
@@ -1066,7 +1157,19 @@ static int __init ifx_pcie_bios_init(voi
IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
return -ENOMEM;
}
@@ -293,7 +294,7 @@ Signed-off-by: Eddi De Pieri <eddi@depieri.net>
register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
/* XXX, clear error status */
@@ -1083,6 +1185,29 @@ static int __init ifx_pcie_bios_init(voi
@@ -1083,6 +1186,29 @@ static int __init ifx_pcie_bios_init(voi
return 0;
}