diff --git a/target/linux/airoha/dts/an7581-nokia-valyrian.dts b/target/linux/airoha/dts/an7581-nokia-valyrian.dts index 26d5e1788e..589048af0c 100644 --- a/target/linux/airoha/dts/an7581-nokia-valyrian.dts +++ b/target/linux/airoha/dts/an7581-nokia-valyrian.dts @@ -359,10 +359,23 @@ }; &pcie0 { - airoha,x2-mode; + status = "okay"; + + reg = <0x0 0x1fc00000 0x0 0x1670>, + <0x0 0x1fc20000 0x0 0x1670>; + reg-names = "pcie-mac", "sec-pcie-mac"; + + resets = <&scuclk EN7581_PCIE0_RST>, + <&scuclk EN7581_PCIE1_RST>, + <&scuclk EN7581_PCIC_PERSTOUT0_RST>, + <&scuclk EN7581_PCIC_PERSTOUT1_RST>; + reset-names = "phy-lane0", "phy-lane1", + "perstout", "sec-perstout"; + + num-lanes = <2>; + pinctrl-names = "default"; pinctrl-0 = <&pcie1_rst_pins>; - status = "okay"; pcie@0,0 { reg = <0x0000 0 0 0 0>; @@ -401,6 +414,10 @@ }; }; +&pcie1 { + status = "disabled"; +}; + &pcie2 { pinctrl-names = "default"; pinctrl-0 = <&pcie2_rst_pins>; diff --git a/target/linux/airoha/dts/an7581-w1700k-ubi.dts b/target/linux/airoha/dts/an7581-w1700k-ubi.dts index d306f8f8e6..8d9498a29b 100644 --- a/target/linux/airoha/dts/an7581-w1700k-ubi.dts +++ b/target/linux/airoha/dts/an7581-w1700k-ubi.dts @@ -235,7 +235,18 @@ &pcie0 { status = "okay"; - airoha,x2-mode; + reg = <0x0 0x1fc00000 0x0 0x1670>, + <0x0 0x1fc20000 0x0 0x1670>; + reg-names = "pcie-mac", "sec-pcie-mac"; + + resets = <&scuclk EN7581_PCIE0_RST>, + <&scuclk EN7581_PCIE1_RST>, + <&scuclk EN7581_PCIC_PERSTOUT0_RST>, + <&scuclk EN7581_PCIC_PERSTOUT1_RST>; + reset-names = "phy-lane0", "phy-lane1", + "perstout", "sec-perstout"; + + num-lanes = <2>; pinctrl-names = "default"; pinctrl-0 = <&pcie0_rst_pins>; @@ -278,6 +289,10 @@ }; }; +&pcie1 { + status = "disabled"; +}; + &pcie2 { status = "okay"; diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index e7bfd69165..4a6b741e6e 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -779,15 +779,11 @@ ranges = <0x02000000 0 0x20000000 0x0 0x20000000 0 0x4000000>; - resets = <&scuclk EN7581_PCIE0_RST>, - <&scuclk EN7581_PCIE1_RST>, - <&scuclk EN7581_PCIE2_RST>; - reset-names = "phy-lane0", "phy-lane1", "phy-lane2"; + resets = <&scuclk EN7581_PCIE0_RST>, <&scuclk EN7581_PCIC_PERSTOUT0_RST>; + reset-names = "phy-lane0", "perstout"; mediatek,pbus-csr = <&pbus_csr 0x0 0x4>; - airoha,np-scu = <&scuclk>; - interrupts = ; bus-range = <0x00 0xff>; #interrupt-cells = <1>; @@ -824,10 +820,8 @@ ranges = <0x02000000 0 0x24000000 0x0 0x24000000 0 0x4000000>; - resets = <&scuclk EN7581_PCIE0_RST>, - <&scuclk EN7581_PCIE1_RST>, - <&scuclk EN7581_PCIE2_RST>; - reset-names = "phy-lane0", "phy-lane1", "phy-lane2"; + resets = <&scuclk EN7581_PCIE1_RST>, <&scuclk EN7581_PCIC_PERSTOUT1_RST>; + reset-names = "phy-lane1", "perstout"; mediatek,pbus-csr = <&pbus_csr 0x8 0xc>; @@ -867,15 +861,11 @@ ranges = <0x02000000 0 0x28000000 0x0 0x28000000 0 0x4000000>; - resets = <&scuclk EN7581_PCIE0_RST>, - <&scuclk EN7581_PCIE1_RST>, - <&scuclk EN7581_PCIE2_RST>; - reset-names = "phy-lane0", "phy-lane1", "phy-lane2"; + resets = <&scuclk EN7581_PCIE2_RST>, <&scuclk EN7581_PCIC_PERSTOUT2_RST>; + reset-names = "phy-lane2", "perstout"; mediatek,pbus-csr = <&pbus_csr 0x10 0x14>; - airoha,np-scu = <&scuclk>; - interrupts = ; bus-range = <0x00 0xff>; #interrupt-cells = <1>; diff --git a/target/linux/airoha/patches-6.18/609-01-dt-bindings-clock-airoha-Add-additional-reset-for-PC.patch b/target/linux/airoha/patches-6.18/609-01-dt-bindings-clock-airoha-Add-additional-reset-for-PC.patch new file mode 100644 index 0000000000..f2f008e052 --- /dev/null +++ b/target/linux/airoha/patches-6.18/609-01-dt-bindings-clock-airoha-Add-additional-reset-for-PC.patch @@ -0,0 +1,26 @@ +From 198c66755440564bec1bf16f37cfa9702394fd02 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 25 Jun 2026 13:48:34 +0200 +Subject: [PATCH 1/3] dt-bindings: clock: airoha: Add additional reset for PCIe + PERSTOUT + +Add additional reset to control PCIe PERSTOUT reset line for each of the 3 +PCIe lines. + +Signed-off-by: Christian Marangi +--- + include/dt-bindings/reset/airoha,en7581-reset.h | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/include/dt-bindings/reset/airoha,en7581-reset.h ++++ b/include/dt-bindings/reset/airoha,en7581-reset.h +@@ -62,5 +62,9 @@ + #define EN7581_CPU_TIMER_RST 50 + #define EN7581_PCIE_HB_RST 51 + #define EN7581_XPON_MAC_RST 52 ++/* RST_PCIC */ ++#define EN7581_PCIC_PERSTOUT0_RST 53 ++#define EN7581_PCIC_PERSTOUT1_RST 54 ++#define EN7581_PCIC_PERSTOUT2_RST 55 + + #endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7581_H_ */ diff --git a/target/linux/airoha/patches-6.18/609-02-clk-en7523-add-support-for-dedicated-PCIe-PERSTOUT-r.patch b/target/linux/airoha/patches-6.18/609-02-clk-en7523-add-support-for-dedicated-PCIe-PERSTOUT-r.patch new file mode 100644 index 0000000000..b204f27593 --- /dev/null +++ b/target/linux/airoha/patches-6.18/609-02-clk-en7523-add-support-for-dedicated-PCIe-PERSTOUT-r.patch @@ -0,0 +1,101 @@ +From 335db8dda524add9d8ec3bdd88eddc339d5d3439 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 25 Jun 2026 13:49:39 +0200 +Subject: [PATCH 2/4] clk: en7523: add support for dedicated PCIe PERSTOUT + reset + +Add support for resetting the PCIe lines with the PERSTOUT reset. These +special reset are controlled by the PCIC register and are specific to each +of the 3 PCIe lines. + +Notice that reset logic is inverted for these bit where 0 is assert and 1 +deassert. This is intenrally handled in the reset function. + +PCI enable/disable are updated to drop PERSTOUT bits in favor dedicated +reset handling. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 39 ++++++++++++++++++++++++++++----------- + 1 file changed, 28 insertions(+), 11 deletions(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -451,6 +451,7 @@ static const struct en_clk_desc an7583_b + static const u16 en7581_rst_ofs[] = { + REG_RST_CTRL2, + REG_RST_CTRL1, ++ REG_NP_SCU_PCIC, + }; + + static const u16 en7523_rst_map[] = { +@@ -556,6 +557,11 @@ static const u16 en7581_rst_map[] = { + [EN7581_CPU_TIMER_RST] = RST_NR_PER_BANK + 28, + [EN7581_PCIE_HB_RST] = RST_NR_PER_BANK + 29, + [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, ++ ++ /* RST_PCIC */ ++ [EN7581_PCIC_PERSTOUT0_RST] = 2 * RST_NR_PER_BANK + 29, ++ [EN7581_PCIC_PERSTOUT1_RST] = 2 * RST_NR_PER_BANK + 26, ++ [EN7581_PCIC_PERSTOUT2_RST] = 2 * RST_NR_PER_BANK + 16, + }; + + static const u16 an7583_rst_map[] = { +@@ -960,9 +966,7 @@ static int en7581_pci_enable(struct clk_ + struct regmap *map = cg->map; + u32 mask; + +- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | +- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | +- REG_PCI_CONTROL_PERSTOUT; ++ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; + regmap_set_bits(map, REG_PCI_CONTROL, mask); + + return 0; +@@ -974,9 +978,7 @@ static void en7581_pci_disable(struct cl + struct regmap *map = cg->map; + u32 mask; + +- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | +- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | +- REG_PCI_CONTROL_PERSTOUT; ++ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; + regmap_clear_bits(map, REG_PCI_CONTROL, mask); + usleep_range(1000, 2000); + } +@@ -1027,9 +1029,16 @@ static int en7523_reset_update(struct re + { + struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); + u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK]; ++ u32 val; ++ ++ /* For PCIC reset logic is inverted, 0:assert 1:deassert*/ ++ if (addr == REG_NP_SCU_PCIC) ++ val |= assert ? 0 : BIT(id % RST_NR_PER_BANK); ++ else ++ val |= assert ? BIT(id % RST_NR_PER_BANK) : 0; + + regmap_update_bits(rst_data->map, addr, BIT(id % RST_NR_PER_BANK), +- assert ? BIT(id % RST_NR_PER_BANK) : 0); ++ val); + + return 0; + } +@@ -1051,10 +1060,16 @@ static int en7523_reset_status(struct re + { + struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); + u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK]; ++ bool inverted = false; + u32 val; + ++ /* For PCIC reset logic is inverted, 0:assert 1:deassert*/ ++ if (addr == REG_NP_SCU_PCIC) ++ inverted = true; ++ + regmap_read(rst_data->map, addr, &val); +- return !!(val & BIT(id % RST_NR_PER_BANK)); ++ val &= BIT(id % RST_NR_PER_BANK); ++ return inverted ? !val : !!val; + } + + static int en7523_reset_xlate(struct reset_controller_dev *rcdev, diff --git a/target/linux/airoha/patches-6.18/609-04-PCI-mediatek-gen3-Add-2-lanes-mode-support-for-Airoh.patch b/target/linux/airoha/patches-6.18/609-04-PCI-mediatek-gen3-Add-2-lanes-mode-support-for-Airoh.patch new file mode 100644 index 0000000000..4d6bf2cd81 --- /dev/null +++ b/target/linux/airoha/patches-6.18/609-04-PCI-mediatek-gen3-Add-2-lanes-mode-support-for-Airoh.patch @@ -0,0 +1,218 @@ +From 25984a8f0891959a47eff4aa00709de3c23c21e6 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 25 Jun 2026 16:20:16 +0200 +Subject: [PATCH v4 4/4] PCI: mediatek-gen3: Add 2-lanes mode support for + Airoha AN7581 + +The Airoha AN7581 SoC supports configuring the first PCIe0 lane to 2-lanes +mode (2x link) by bonding it with the second PCIe lane (PCIe1). This is +done by configuring the PCIe MUX in the SCU register. + +To correctly configure PCIe0 in 2x link, define in DT the following +additional property: +- additional reg, 'sec-pcie-mac' for the secondary PCIe. +- PERSTOUT reset for both main and secondary PCIE0, called 'perstout' and + 'sec-perstout' +- airoha,scu property to correctly configure the SCU register for the PCIe + MUX +- 'num-lanes' set to '2' to enable PCIe0 in 2x link + +In such configuration the EQ preset are configured to the same values. + +To permit correct configuration of the PCIe line, additional logic is added +to assert and deassert the PERSTOUT resets. + +Signed-off-by: Christian Marangi +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 106 ++++++++++++++++---- + 1 file changed, 89 insertions(+), 17 deletions(-) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -31,6 +31,11 @@ + + #include "../pci.h" + ++/* AN7581 SCU register */ ++#define SCU_PCIC 0x88 ++#define SCU_PCIC_PCIE_CTRL GENMASK(7, 0) ++ ++/* PCIe register */ + #define PCIE_BASE_CFG_REG 0x14 + #define PCIE_BASE_CFG_SPEED GENMASK(15, 8) + +@@ -130,6 +135,7 @@ + #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) + + #define MAX_NUM_PHY_RESETS 3 ++#define MAX_NUM_PERSTOUT_RESETS 2 + + #define PCIE_MTK_RESET_TIME_US 10 + +@@ -202,9 +208,11 @@ struct mtk_msi_set { + struct mtk_gen3_pcie { + struct device *dev; + void __iomem *base; ++ void __iomem *sec_base; + phys_addr_t reg_base; + struct reset_control *mac_reset; + struct reset_control_bulk_data phy_resets[MAX_NUM_PHY_RESETS]; ++ struct reset_control_bulk_data perstout_resets[MAX_NUM_PERSTOUT_RESETS]; + struct phy *phy; + struct clk_bulk_data *clks; + int num_clks; +@@ -893,6 +901,14 @@ static int mtk_pcie_parse_port(struct mt + return ret; + } + ++ pcie->perstout_resets[0].id = "perstout"; ++ pcie->perstout_resets[1].id = "sec-perstout"; ++ ++ ret = devm_reset_control_bulk_get_optional_exclusive(dev, MAX_NUM_PERSTOUT_RESETS, ++ pcie->perstout_resets); ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to get PERSTOUT bulk reset\n"); ++ + pcie->mac_reset = devm_reset_control_get_optional_exclusive(dev, "mac"); + if (IS_ERR(pcie->mac_reset)) { + ret = PTR_ERR(pcie->mac_reset); +@@ -926,18 +942,38 @@ static int mtk_pcie_parse_port(struct mt + pcie->num_lanes = num_lanes; + } + ++ /* Map secondary PCIe for 2-lanes mode for EN7581 */ ++ if (pcie->num_lanes == 2 && device_is_compatible(dev, "airoha,en7581-pcie")) { ++ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec-pcie-mac"); ++ if (!regs) ++ return -EINVAL; ++ pcie->sec_base = devm_ioremap_resource(dev, regs); ++ if (IS_ERR(pcie->sec_base)) ++ return dev_err_probe(dev, PTR_ERR(pcie->sec_base), "failed to map secondary register base\n"); ++ } ++ + return 0; + } + + static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie) + { + struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); ++ unsigned int num_lanes = max(1, pcie->num_lanes); ++ struct regmap *pbus_regmap, *scu; + struct device *dev = pcie->dev; + struct resource_entry *entry; +- struct regmap *pbus_regmap; + u32 val, args[2], size; + resource_size_t addr; +- int err; ++ int i, err; ++ ++ if (num_lanes > 2) ++ return dev_err_probe(dev, -EINVAL, "unsupported num-lanes, maximum 2 lanes supported\n"); ++ ++ if (num_lanes == 2) { ++ scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,scu"); ++ if (IS_ERR(scu)) ++ return dev_err_probe(dev, PTR_ERR(scu), "failed to map SCU regmap\n"); ++ } + + /* + * The controller may have been left out of reset by the bootloader +@@ -975,6 +1011,19 @@ static int mtk_pcie_en7581_power_up(stru + return err; + } + ++ /* Assert PERSTOUT for all relevant lines */ ++ err = reset_control_bulk_assert(MAX_NUM_PERSTOUT_RESETS, ++ pcie->perstout_resets); ++ if (err) { ++ dev_err(dev, "failed to assert PERSTOUTs\n"); ++ return err; ++ } ++ ++ /* Configure SCU MUX to disable PCIE1 for 2 lines mode */ ++ if (num_lanes == 2) ++ regmap_update_bits(scu, SCU_PCIC, SCU_PCIC_PCIE_CTRL, ++ FIELD_PREP(SCU_PCIC_PCIE_CTRL, BIT(1))); ++ + /* + * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 + * requires PHY initialization and power-on before PHY reset deassert. +@@ -1007,18 +1056,6 @@ static int mtk_pcie_en7581_power_up(stru + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + +- val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | +- FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | +- FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | +- FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41); +- writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG); +- +- val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT | +- FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) | +- FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) | +- FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); +- writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); +- + err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks); + if (err) { + dev_err(dev, "failed to prepare clock\n"); +@@ -1026,14 +1063,47 @@ static int mtk_pcie_en7581_power_up(stru + } + + /* +- * Airoha EN7581 performs PCIe reset via clk callbacks since it has a +- * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to +- * complete the PCIe reset. ++ * Old Airoha EN7581 clock driver performed PCIe reset via ++ * clk callbacks since it has a hw issue with PCIE_PE_RSTB signal. ++ * This is now handled by dedicated PERSTOUT resets with clk ++ * driver only enabling the refclk. ++ * ++ * Wait is still needed for refclk to stabilize + */ + msleep(PCIE_T_PVPERL_MS); + ++ /* Configure all the lines to the same EQ config */ ++ for (i = 0; i < num_lanes; i++) { ++ void __iomem *base = pcie->base; ++ ++ if (i == 1) ++ base = pcie->sec_base; ++ ++ val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | ++ FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | ++ FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | ++ FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41); ++ writel_relaxed(val, base + PCIE_EQ_PRESET_01_REG); ++ ++ val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT | ++ FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) | ++ FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) | ++ FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); ++ writel_relaxed(val, base + PCIE_PIPE4_PIE8_REG); ++ } ++ ++ /* Deassert PERSTOUT for all relevant lines */ ++ err = reset_control_bulk_deassert(MAX_NUM_PERSTOUT_RESETS, ++ pcie->perstout_resets); ++ if (err) { ++ dev_err(dev, "failed to deassert PERSTOUTs\n"); ++ goto err_perstout_deassert; ++ } ++ + return 0; + ++err_perstout_deassert: ++ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks); + err_clk_prepare_enable: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); +@@ -1119,6 +1189,8 @@ static void mtk_pcie_power_down(struct m + + phy_power_off(pcie->phy); + phy_exit(pcie->phy); ++ reset_control_bulk_assert(MAX_NUM_PERSTOUT_RESETS, ++ pcie->perstout_resets); + reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, + pcie->phy_resets); + } diff --git a/target/linux/airoha/patches-6.18/911-clk-en7581-Separate-PERST-from-refclk-in-PCIe-clock.patch b/target/linux/airoha/patches-6.18/911-clk-en7581-Separate-PERST-from-refclk-in-PCIe-clock.patch deleted file mode 100644 index 9469c1c5ba..0000000000 --- a/target/linux/airoha/patches-6.18/911-clk-en7581-Separate-PERST-from-refclk-in-PCIe-clock.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Ryan Chen -Subject: clk: en7581: Separate PERST from refclk in PCIe clock callbacks - -The EN7581 PCIe clock enable/disable callbacks currently toggle both -PERST (reset) and reference clock signals together. This prevents the -PCIe controller driver from properly sequencing PERST relative to MAC -register configuration, which is required for x2 link mode. - -Separate the two concerns: clock callbacks only manage reference clocks -(REFCLK_EN0/EN1), while PERST (PERSTOUT/PERSTOUT1/PERSTOUT2) is left -to the PCIe controller driver to manage directly via the NP_SCU regmap. - -Signed-off-by: Ryan Chen ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -960,9 +960,11 @@ static int en7581_pci_enable(struct clk_ - struct regmap *map = cg->map; - u32 mask; - -- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | -- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | -- REG_PCI_CONTROL_PERSTOUT; -+ /* Only enable reference clocks - PERST is managed separately by the -+ * PCIe controller driver to allow proper sequencing of MAC register -+ * configuration between PERST assert and deassert. -+ */ -+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; - regmap_set_bits(map, REG_PCI_CONTROL, mask); - - return 0; -@@ -974,9 +976,8 @@ static void en7581_pci_disable(struct cl - struct regmap *map = cg->map; - u32 mask; - -- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | -- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | -- REG_PCI_CONTROL_PERSTOUT; -+ /* Only disable reference clocks - PCIe driver manages PERST */ -+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; - regmap_clear_bits(map, REG_PCI_CONTROL, mask); - usleep_range(1000, 2000); - } diff --git a/target/linux/airoha/patches-6.18/912-pcie-mediatek-gen3-Add-x2-link-support-for-Airoha-EN7581.patch b/target/linux/airoha/patches-6.18/912-pcie-mediatek-gen3-Add-x2-link-support-for-Airoha-EN7581.patch deleted file mode 100644 index ec45c45711..0000000000 --- a/target/linux/airoha/patches-6.18/912-pcie-mediatek-gen3-Add-x2-link-support-for-Airoha-EN7581.patch +++ /dev/null @@ -1,244 +0,0 @@ -From: Ryan Chen -Subject: PCI: mediatek-gen3: Add PCIe x2 link support for Airoha EN7581 - -The Airoha EN7581 SoC supports PCIe x2 mode where two PCIe lanes are -bonded together for a single x2 link. This requires coordination with -the NP_SCU system controller for serdes mux routing, PERST management, -and lane configuration. - -The x2 initialization sequence: -1. Assert serdes reset and PERST before enabling clocks -2. Configure serdes mux for 2-lane mode -3. Enable reference clocks, deassert serdes reset -4. Clear x1 mode bit and write EQ presets on both MACs -5. Deassert PERST to start link training - -After initial link training, if the link negotiates Gen2 instead of -Gen3, a serdes reset toggle forces the MAC to re-discover the PHY -Gen3 capability from the Link Capabilities 2 register, allowing the -link to retrain at Gen3 x2 (8 GT/s). - -Signed-off-by: Ryan Chen ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -67,6 +67,14 @@ - #define PCIE_LTSSM_STATE(val) ((val & PCIE_LTSSM_STATE_MASK) >> 24) - #define PCIE_LTSSM_STATE_L2_IDLE 0x14 - -+/* EN7581 x2 mode support */ -+#define PCIE_SETTING_REG_X1_MODE BIT(13) -+ -+/* EN7581 NP_SCU register offsets for x2 link init */ -+#define NP_SCU_LANE_CFG0 0x830 -+#define NP_SCU_LANE_CFG1 0x834 -+#define NP_SCU_CTRL_REG 0x88 -+ - #define PCIE_LINK_STATUS_REG 0x154 - #define PCIE_PORT_LINKUP BIT(8) - -@@ -221,6 +229,11 @@ struct mtk_gen3_pcie { - DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM); - - const struct mtk_gen3_pcie_pdata *soc; -+ -+ /* EN7581 x2 mode support */ -+ struct regmap *np_scu; -+ bool x2_mode; -+ void __iomem *sister_base; - }; - - /* LTSSM state in PCIE_LTSSM_STATUS_REG bit[28:24] */ -@@ -969,6 +982,28 @@ static int mtk_pcie_en7581_power_up(stru - size = lower_32_bits(resource_size(entry->res)); - regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); - -+ /* Lookup NP_SCU regmap for x2 mode support */ -+ pcie->np_scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,np-scu"); -+ if (IS_ERR(pcie->np_scu)) { -+ dev_dbg(dev, "np_scu not available, x2 mode disabled\n"); -+ pcie->np_scu = NULL; -+ } -+ -+ /* Check for x2 mode property */ -+ pcie->x2_mode = of_property_read_bool(dev->of_node, "airoha,x2-mode"); -+ if (pcie->x2_mode) -+ dev_info(dev, "x2 mode enabled\n"); -+ -+ /* Map sister MAC for x2 mode (MAC1 at +0x20000) */ -+ if (pcie->x2_mode) { -+ pcie->sister_base = devm_ioremap(dev, -+ pcie->reg_base + 0x20000, 0x20000); -+ if (!pcie->sister_base) -+ dev_warn(dev, "failed to map sister MAC for x2\n"); -+ else -+ dev_info(dev, "x2 mode: sister MAC mapped\n"); -+ } -+ - err = phy_set_mode(pcie->phy, PHY_MODE_PCIE); - if (err) { - dev_err(dev, "failed to set PHY mode\n"); -@@ -1007,17 +1042,28 @@ static int mtk_pcie_en7581_power_up(stru - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - -- val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | -- FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | -- FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | -- FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41); -- writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG); -- -- val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT | -- FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) | -- FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) | -- FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); -- writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); -+ /* -+ * EN7581 x2: Assert PERST and serdes reset before enabling clocks -+ * so that MAC registers can be configured while devices are held -+ * in reset, ensuring link trains with the correct x2 settings. -+ */ -+ if (pcie->x2_mode && pcie->np_scu) { -+ /* Assert serdes reset on all lanes */ -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -+ BIT(26) | BIT(27), BIT(26) | BIT(27)); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -+ BIT(27), BIT(27)); -+ msleep(100); -+ -+ /* Assert PERST on all ports */ -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -+ BIT(16) | BIT(26) | BIT(29), 0); -+ -+ /* Set serdes mux for 2-lane mode (bits[1:0] = 2) */ -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -+ BIT(0) | BIT(1), BIT(1)); -+ mdelay(1); -+ } - - err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks); - if (err) { -@@ -1026,12 +1072,121 @@ static int mtk_pcie_en7581_power_up(stru - } - - /* -- * Airoha EN7581 performs PCIe reset via clk callbacks since it has a -- * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to -- * complete the PCIe reset. -+ * Airoha EN7581: clock enable only provides refclk (patch 911). -+ * For x2, PERST + serdes are already asserted above. -+ * Wait for refclk to stabilize. - */ - msleep(PCIE_T_PVPERL_MS); - -+ if (pcie->x2_mode && pcie->np_scu) { -+ /* -+ * EN7581 x2: PERST asserted, serdes reset asserted, -+ * refclk now stable. Complete the init sequence. -+ */ -+ msleep(30); -+ -+ /* Deassert serdes reset on all lanes */ -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -+ BIT(26) | BIT(27), 0); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -+ BIT(27), 0); -+ -+ /* Clear SETTING_REG bit 13 for x2 mode on both MACs */ -+ val = readl_relaxed(pcie->base + PCIE_SETTING_REG); -+ writel_relaxed(val & ~PCIE_SETTING_REG_X1_MODE, -+ pcie->base + PCIE_SETTING_REG); -+ if (pcie->sister_base) { -+ val = readl_relaxed(pcie->sister_base + 0x80); -+ writel_relaxed(val & ~PCIE_SETTING_REG_X1_MODE, -+ pcie->sister_base + 0x80); -+ } -+ -+ /* EQ presets on both MACs */ -+ writel_relaxed(0x41474147, pcie->base + PCIE_EQ_PRESET_01_REG); -+ if (pcie->sister_base) -+ writel_relaxed(0x41474147, pcie->sister_base + 0x100); -+ writel_relaxed(0x1018020f, pcie->base + PCIE_PIPE4_PIE8_REG); -+ if (pcie->sister_base) -+ writel_relaxed(0x1018020f, pcie->sister_base + 0x338); -+ -+ /* Deassert PERST for all ports - link training starts */ -+ msleep(10); -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -+ BIT(16) | BIT(26) | BIT(29), -+ BIT(16) | BIT(26) | BIT(29)); -+ -+ /* Wait for link training to complete */ -+ msleep(800); -+ -+ /* -+ * Check if link trained at Gen3. If not, toggle serdes -+ * reset to force MAC to re-discover PHY Gen3 capability. -+ * Without this, MAC only advertises Gen1-Gen2 in LnkCap2. -+ */ -+ val = readl_relaxed(pcie->base + PCIE_LINK_STATUS_REG); -+ if (val & PCIE_PORT_LINKUP) { -+ void __iomem *cfg = pcie->base + PCIE_CFG_OFFSET_ADDR; -+ u8 cap_ptr; -+ int speed = 0; -+ -+ /* Walk PCI cap list to find PCIe cap (ID=0x10) */ -+ cap_ptr = readl_relaxed(cfg + PCI_CAPABILITY_LIST) & 0xFF; -+ while (cap_ptr >= 0x40) { -+ u32 hdr = readl_relaxed(cfg + cap_ptr); -+ if ((hdr & 0xFF) == PCI_CAP_ID_EXP) { -+ u32 lnk = readl_relaxed(cfg + cap_ptr + PCI_EXP_LNKCTL); -+ speed = (lnk >> 16) & PCI_EXP_LNKSTA_CLS; -+ break; -+ } -+ cap_ptr = (hdr >> 8) & 0xFF; -+ } -+ -+ if (speed > 0 && speed < 3) { -+ dev_info(dev, "x2: link at Gen%d, toggling serdes for Gen3\n", speed); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -+ BIT(7) | BIT(8), BIT(7) | BIT(8)); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -+ BIT(26) | BIT(27), BIT(26) | BIT(27)); -+ msleep(1000); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -+ BIT(7) | BIT(8), 0); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -+ BIT(26) | BIT(27), 0); -+ msleep(2000); -+ dev_info(dev, "x2: serdes toggle done, link retraining\n"); -+ } else { -+ dev_info(dev, "x2: link at Gen%d, no toggle needed\n", speed); -+ } -+ } else { -+ dev_info(dev, "x2: link not up after init, skipping speed check\n"); -+ } -+ -+ dev_info(dev, "x2: init complete, PERST deasserted\n"); -+ } else { -+ /* -+ * Non-x2 mode: standard EQ config then deassert PERST. -+ */ -+ val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | -+ FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | -+ FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | -+ FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41); -+ writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG); -+ -+ val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT | -+ FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) | -+ FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) | -+ FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); -+ writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); -+ -+ /* Deassert PERST for all ports */ -+ if (pcie->np_scu) { -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -+ BIT(16) | BIT(26) | BIT(29), -+ BIT(16) | BIT(26) | BIT(29)); -+ msleep(100); -+ } -+ } -+ - return 0; - - err_clk_prepare_enable: diff --git a/target/linux/airoha/patches-6.18/913-clk-en7523-reset-PCIE-HB-on-init.patch b/target/linux/airoha/patches-6.18/913-clk-en7523-reset-PCIE-HB-on-init.patch new file mode 100644 index 0000000000..58e74ea1ba --- /dev/null +++ b/target/linux/airoha/patches-6.18/913-clk-en7523-reset-PCIE-HB-on-init.patch @@ -0,0 +1,25 @@ +From 12047c34237be89c85a0e144c6c99281656a1153 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 4 Jun 2026 14:26:20 +0200 +Subject: [PATCH] clk: en7523: reset PCIE HB on init + +Reset PCIE on clk HW init to handle warm boot problem with PCIe. + +Signed-off-by: Christian Marangi +--- + drivers/clk/clk-en7523.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -1147,6 +1147,10 @@ static int en7581_clk_hw_init(struct pla + regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, + FIELD_PREP(REG_PCIE_CTRL, 3)); + ++ /* Reset PCIE_HB */ ++ regmap_set_bits(clk_map, REG_RST_CTRL1, BIT(29)); ++ regmap_clear_bits(clk_map, REG_RST_CTRL1, BIT(29)); ++ + return en7581_reset_register(&pdev->dev, clk_map, en7581_rst_map, + ARRAY_SIZE(en7581_rst_map)); + } diff --git a/target/linux/airoha/patches-6.18/913-pcie-mediatek-gen3-fix-x2-mode-PERST-deassert.patch b/target/linux/airoha/patches-6.18/913-pcie-mediatek-gen3-fix-x2-mode-PERST-deassert.patch deleted file mode 100644 index e6ac81c08e..0000000000 --- a/target/linux/airoha/patches-6.18/913-pcie-mediatek-gen3-fix-x2-mode-PERST-deassert.patch +++ /dev/null @@ -1,207 +0,0 @@ -From fde8e40b0bf72436ce75d21e8778049368ea200f Mon Sep 17 00:00:00 2001 -From: Kenneth Kasilag -Date: Mon, 6 Apr 2026 23:04:38 +0000 -Subject: [PATCH] airoha: fix PERST deassert in PCIe driver - -Due to hardware bugs, the PCIE Gen3 IP in Airoha AN7581 requires a -special reset procedure: -> MAC reset asserted thru the SCU block -> PERST asserted thru the SCU for the desired PCIE lane -> PHY initialization runs, clocks enabled -> MAC reset deasserted -> EQ config (if needed) written -> PERST deasserted - -The existing code currently toggles PERST for all three PCIE -ports every time mtk_pcie_en7581_power_up is called, resulting -in PCIE link down issues. - -This issue was discovered during porting of the 6.18 kernel to -AN7581. It is not entirely clear how the hardware seemed to -function under kernel 6.12 with similar driver code, it is -presumed that differences in assert/deassert times for PERST in -6.18 changed which exposed the bug. - -Signed-off-by: Kenneth Kasilag ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 124 ++++++++------- - 1 file changed, 86 insertions(+), 38 deletions(-) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -72,8 +72,21 @@ - - /* EN7581 NP_SCU register offsets for x2 link init */ - #define NP_SCU_LANE_CFG0 0x830 -+#define NP_SCU_XSI_MAC_RST BIT(7) -+#define NP_SCU_XSI_PHY_RST BIT(8) -+#define NP_SCU_PCIE2_RST BIT(27) - #define NP_SCU_LANE_CFG1 0x834 -+#define NP_SCU_PCIE0_RST BIT(26) -+#define NP_SCU_PCIE1_RST BIT(27) - #define NP_SCU_CTRL_REG 0x88 -+#define NP_SCU_PERSTOUT BIT(29) -+#define NP_SCU_PERSTOUT1 BIT(26) -+#define NP_SCU_PERSTOUT2 BIT(16) -+#define NP_SCU_PERST_ALL (NP_SCU_PERSTOUT | \ -+ NP_SCU_PERSTOUT1 | \ -+ NP_SCU_PERSTOUT2) -+#define NP_SCU_SERDES_MUX_MASK GENMASK(1, 0) -+#define NP_SCU_SERDES_MUX_X2 2 - - #define PCIE_LINK_STATUS_REG 0x154 - #define PCIE_PORT_LINKUP BIT(8) -@@ -1004,6 +1017,23 @@ static int mtk_pcie_en7581_power_up(stru - dev_info(dev, "x2 mode: sister MAC mapped\n"); - } - -+ /* Select the correct reset for each PCIe port */ -+ u32 perst_mask = NP_SCU_PERST_ALL; -+ if (pcie->x2_mode) -+ perst_mask = NP_SCU_PERSTOUT | NP_SCU_PERSTOUT1; -+ else if (pcie->reg_base == 0x1fc00000) -+ perst_mask = NP_SCU_PERSTOUT; -+ else if (pcie->reg_base == 0x1fc20000) -+ perst_mask = NP_SCU_PERSTOUT1; -+ else if (pcie->reg_base == 0x1fc40000) -+ perst_mask = NP_SCU_PERSTOUT2; -+ -+ /* Assert selected PERST prior to PHY init */ -+ if (pcie->np_scu) { -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, perst_mask, 0); -+ msleep(1); -+ } -+ - err = phy_set_mode(pcie->phy, PHY_MODE_PCIE); - if (err) { - dev_err(dev, "failed to set PHY mode\n"); -@@ -1043,26 +1073,22 @@ static int mtk_pcie_en7581_power_up(stru - pm_runtime_get_sync(dev); - - /* -- * EN7581 x2: Assert PERST and serdes reset before enabling clocks -- * so that MAC registers can be configured while devices are held -- * in reset, ensuring link trains with the correct x2 settings. -+ * EN7581 x2: Do serdes reset before enabling clocks so that MAC -+ * registers can be configured while devices are held in reset, -+ * ensuring link trains with the correct x2 settings. - */ - if (pcie->x2_mode && pcie->np_scu) { -- /* Assert serdes reset on all lanes */ -+ /* Assert serdes reset on lanes 0 and 1 */ - regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -- BIT(26) | BIT(27), BIT(26) | BIT(27)); -- regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -- BIT(27), BIT(27)); -+ NP_SCU_PCIE0_RST | NP_SCU_PCIE1_RST, -+ NP_SCU_PCIE0_RST | NP_SCU_PCIE1_RST); - msleep(100); - -- /* Assert PERST on all ports */ -- regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -- BIT(16) | BIT(26) | BIT(29), 0); -- - /* Set serdes mux for 2-lane mode (bits[1:0] = 2) */ - regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -- BIT(0) | BIT(1), BIT(1)); -- mdelay(1); -+ NP_SCU_SERDES_MUX_MASK, -+ NP_SCU_SERDES_MUX_X2); -+ msleep(1); - } - - err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks); -@@ -1085,11 +1111,9 @@ static int mtk_pcie_en7581_power_up(stru - */ - msleep(30); - -- /* Deassert serdes reset on all lanes */ -+ /* Deassert serdes reset on lanes 0 and 1 */ - regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -- BIT(26) | BIT(27), 0); -- regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -- BIT(27), 0); -+ NP_SCU_PCIE0_RST | NP_SCU_PCIE1_RST, 0); - - /* Clear SETTING_REG bit 13 for x2 mode on both MACs */ - val = readl_relaxed(pcie->base + PCIE_SETTING_REG); -@@ -1109,59 +1133,16 @@ static int mtk_pcie_en7581_power_up(stru - if (pcie->sister_base) - writel_relaxed(0x1018020f, pcie->sister_base + 0x338); - -- /* Deassert PERST for all ports - link training starts */ -+ /* Deassert PERST on selected port - link training starts */ - msleep(10); - regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -- BIT(16) | BIT(26) | BIT(29), -- BIT(16) | BIT(26) | BIT(29)); -+ perst_mask, -+ perst_mask); - - /* Wait for link training to complete */ -- msleep(800); -- -- /* -- * Check if link trained at Gen3. If not, toggle serdes -- * reset to force MAC to re-discover PHY Gen3 capability. -- * Without this, MAC only advertises Gen1-Gen2 in LnkCap2. -- */ -- val = readl_relaxed(pcie->base + PCIE_LINK_STATUS_REG); -- if (val & PCIE_PORT_LINKUP) { -- void __iomem *cfg = pcie->base + PCIE_CFG_OFFSET_ADDR; -- u8 cap_ptr; -- int speed = 0; -- -- /* Walk PCI cap list to find PCIe cap (ID=0x10) */ -- cap_ptr = readl_relaxed(cfg + PCI_CAPABILITY_LIST) & 0xFF; -- while (cap_ptr >= 0x40) { -- u32 hdr = readl_relaxed(cfg + cap_ptr); -- if ((hdr & 0xFF) == PCI_CAP_ID_EXP) { -- u32 lnk = readl_relaxed(cfg + cap_ptr + PCI_EXP_LNKCTL); -- speed = (lnk >> 16) & PCI_EXP_LNKSTA_CLS; -- break; -- } -- cap_ptr = (hdr >> 8) & 0xFF; -- } -- -- if (speed > 0 && speed < 3) { -- dev_info(dev, "x2: link at Gen%d, toggling serdes for Gen3\n", speed); -- regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -- BIT(7) | BIT(8), BIT(7) | BIT(8)); -- regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -- BIT(26) | BIT(27), BIT(26) | BIT(27)); -- msleep(1000); -- regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -- BIT(7) | BIT(8), 0); -- regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -- BIT(26) | BIT(27), 0); -- msleep(2000); -- dev_info(dev, "x2: serdes toggle done, link retraining\n"); -- } else { -- dev_info(dev, "x2: link at Gen%d, no toggle needed\n", speed); -- } -- } else { -- dev_info(dev, "x2: link not up after init, skipping speed check\n"); -- } -+ msleep(1000); - -- dev_info(dev, "x2: init complete, PERST deasserted\n"); -+ dev_info(dev, "x2: init complete\n"); - } else { - /* - * Non-x2 mode: standard EQ config then deassert PERST. -@@ -1178,11 +1159,11 @@ static int mtk_pcie_en7581_power_up(stru - FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); - writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); - -- /* Deassert PERST for all ports */ -+ /* Deassert PERST on selected port */ - if (pcie->np_scu) { - regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -- BIT(16) | BIT(26) | BIT(29), -- BIT(16) | BIT(26) | BIT(29)); -+ perst_mask, -+ perst_mask); - msleep(100); - } - }