From 6712f48eb3a15842925171441505fa2e7699c57e Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Thu, 23 Jul 2026 21:01:31 +0200 Subject: [PATCH] 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. Contrary to the dedicated reset register where 0 deassert and 1 assert the reset line for the related bit, for PCIe PERSTOUT reset in the PCIC register, the deassert and assert value is swapped, with 1 for deassert and 0 for assert. (HW have these bit set as 1 by default after a cold boot) This is internally handled in the reset function. PCI enable/disable are updated to drop PERSTOUT bits in favor dedicated reset handling. Signed-off-by: Christian Marangi Reviewed-by: Brian Masney Signed-off-by: Brian Masney --- drivers/clk/clk-en7523.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index c450d89bfa96..5c45aacb6409 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -339,6 +339,7 @@ static const struct en_clk_desc en7581_base_clks[] = { static const u16 en7581_rst_ofs[] = { REG_RST_CTRL2, REG_RST_CTRL1, + REG_NP_SCU_PCIC, }; static const u16 en751221_rst_ofs[] = { @@ -451,6 +452,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 en751221_rst_map[] = { @@ -636,9 +642,7 @@ static int en7581_pci_enable(struct clk_hw *hw) void __iomem *np_base = cg->base; u32 val, 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; val = readl(np_base + REG_PCI_CONTROL); writel(val | mask, np_base + REG_PCI_CONTROL); @@ -651,9 +655,7 @@ static void en7581_pci_disable(struct clk_hw *hw) void __iomem *np_base = cg->base; u32 val, 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; val = readl(np_base + REG_PCI_CONTROL); writel(val & ~mask, np_base + REG_PCI_CONTROL); usleep_range(1000, 2000); @@ -755,11 +757,17 @@ static int en7523_reset_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert) { struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); - void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK]; + u32 offset = rst_data->bank_ofs[id / RST_NR_PER_BANK]; + void __iomem *addr = rst_data->base + offset; + bool inverted = false; u32 val; + /* For PCIC reset logic is inverted, 0:assert 1:deassert */ + if (offset == REG_NP_SCU_PCIC) + inverted = true; + val = readl(addr); - if (assert) + if (assert ^ inverted) val |= BIT(id % RST_NR_PER_BANK); else val &= ~BIT(id % RST_NR_PER_BANK); @@ -784,9 +792,17 @@ static int en7523_reset_status(struct reset_controller_dev *rcdev, unsigned long id) { struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); - void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK]; + u32 offset = rst_data->bank_ofs[id / RST_NR_PER_BANK]; + void __iomem *addr = rst_data->base + offset; + bool inverted = false; + u32 val; - return !!(readl(addr) & BIT(id % RST_NR_PER_BANK)); + /* For PCIC reset logic is inverted, 0:assert 1:deassert */ + if (offset == REG_NP_SCU_PCIC) + inverted = true; + + val = readl(addr) & BIT(id % RST_NR_PER_BANK); + return inverted ? !val : !!val; } static int en7523_reset_xlate(struct reset_controller_dev *rcdev,