Add reset support to EN7581 clk driver
v2 cover Add reset support to EN7581 clk driver
Introduce reset-controller support to the Airoha EN7581 clock module.
Changes since v1:
- squash patch 1/5 and 2/5
- introduce reset line mapping in order to take into account possible holes in reset definitions
- fix error path in en7523_clk_probe()
Lorenzo Bianconi (4):
dt-bindings: clock: airoha: Add reset support to EN7581 clock binding
arm64: dts: airoha: Add reset-controller support to EN7581 clock node
clk: en7523: Add reset-controller support for EN7581 SoC
clk: en7523: Remove pcie prepare/unpreare callbacks for EN7581 SoC
.../bindings/clock/airoha,en7523-scu.yaml | 21 ++ arch/arm64/boot/dts/airoha/en7581.dtsi | 2 + drivers/clk/clk-en7523.c | 230 ++++++++++++++---- .../dt-bindings/reset/airoha,en7581-reset.h | 66 +++++ 4 files changed, 278 insertions(+), 41 deletions(-) create mode 100644 include/dt-bindings/reset/airoha,en7581-reset.h
Signature · 1 line
2.45.0
PATCH v2 1/4 dt-bindings: clock: airoha: Add reset support to EN7581 clock binding
Introduce reset capability to EN7581 device-tree clock binding documentation.
--- .../bindings/clock/airoha,en7523-scu.yaml | 21 ++++++ .../dt-bindings/reset/airoha,en7581-reset.h | 66 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 include/dt-bindings/reset/airoha,en7581-reset.h
Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +21 -0
@@ -43,6 +43,10 @@ properties: clocks. const: 1 + '#reset-cells': + description: ID of the controller reset line + const: 1 + required: - compatible - reg
@@ -60,6 +64,8 @@ allOf: - description: scu base address - description: misc scu base address + '#reset-cells': false + - if: properties: compatible:
@@ -83,3 +89,18 @@ examples: <0x1fb00000 0x1000>; #clock-cells = <1>; }; + + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + scuclk: clock-controller@1fa20000 { + compatible = "airoha,en7581-scu"; + reg = <0x0 0x1fa20000 0x0 0x400>, + <0x0 0x1fb00000 0x0 0x1000>, + <0x0 0x1fbe3400 0x0 0xfc>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + };
include/dt-bindings/reset/airoha,en7581-reset.h new file +66 -0
66 lines not on this page · raw message
Signature · 1 line
2.45.0
PATCH v2 2/4 arm64: dts: airoha: Add reset-controller support to EN7581 clock node
In reply to Lorenzo BianconiIntroduce reset capability to scuclk clock-controller device-tree node for EN7581 SoC.
--- arch/arm64/boot/dts/airoha/en7581.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/airoha/en7581.dtsi +2 -0
@@ -3,6 +3,7 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/en7523-clk.h> +#include <dt-bindings/reset/airoha,en7581-reset.h> / { interrupt-parent = <&gic>;
@@ -158,6 +159,7 @@ scuclk: clock-controller@1fa20000 { <0x0 0x1fb00000 0x0 0x1000>, <0x0 0x1fbe3400 0x0 0xfc>; #clock-cells = <1>; + #reset-cells = <1>; }; snfi: spi@1fa10000 {
Signature · 1 line
2.45.0
PATCH v2 3/4 clk: en7523: Add reset-controller support for EN7581 SoC
In reply to Lorenzo BianconiIntroduce reset API support to EN7581 clock driver.
--- drivers/clk/clk-en7523.c | 189 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 2 deletions(-)
drivers/clk/clk-en7523.c +187 -2
@@ -6,7 +6,11 @@#include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/reset-controller.h> #include <dt-bindings/clock/en7523-clk.h> +#include <dt-bindings/reset/airoha,en7581-reset.h> + +#define RST_NR_PER_BANK 32#define REG_PCI_CONTROL 0x88#define REG_PCI_CONTROL_PERSTOUT BIT(29)
@@ -65,8 +69,20 @@ struct en_clk_gate {struct clk_hw hw; }; +struct en_rst_data { +const u16 *bank_ofs; +const u16 *idx_map; +void __iomem *base; +struct reset_controller_dev rcdev; +}; +struct en_clk_soc_data {const struct clk_ops pcie_ops; +struct { +const u16 *bank_ofs; +const u16 *idx_map; +u16 idx_map_nr; + } reset;int (*hw_init)(struct platform_device *pdev,void __iomem *base,void __iomem *np_base); };
@@ -169,6 +185,69 @@ static const struct en_clk_desc en7523_base_clks[] = { } }; +static const u16 en7581_rst_ofs[] = { +REG_RESET_CONTROL2 , +REG_RESET_CONTROL1 , +}; + +static const u16 en7581_rst_map[] = { +/* RST_CTRL2 */ + [EN7581_XPON_PHY_RST ] =0 , + [EN7581_CPU_TIMER2_RST ] =2 , + [EN7581_HSUART_RST ] =3 , + [EN7581_UART4_RST ] =4 , + [EN7581_UART5_RST ] =5 , + [EN7581_I2C2_RST ] =6 , + [EN7581_XSI_MAC_RST ] =7 , + [EN7581_XSI_PHY_RST ] =8 , + [EN7581_NPU_RST ] =9 , + [EN7581_I2S_RST ] =10 , + [EN7581_TRNG_RST ] =11 , + [EN7581_TRNG_MSTART_RST ] =12 , + [EN7581_DUAL_HSI0_RST ] =13 , + [EN7581_DUAL_HSI1_RST ] =14 , + [EN7581_HSI_RST ] =15 , + [EN7581_DUAL_HSI0_MAC_RST ] =16 , + [EN7581_DUAL_HSI1_MAC_RST ] =17 , + [EN7581_HSI_MAC_RST ] =18 , + [EN7581_WDMA_RST ] =19 , + [EN7581_WOE0_RST ] =20 , + [EN7581_WOE1_RST ] =21 , + [EN7581_HSDMA_RST ] =22 , + [EN7581_TDMA_RST ] =24 , + [EN7581_EMMC_RST ] =25 , + [EN7581_SOE_RST ] =26 , + [EN7581_PCIE2_RST ] =27 , + [EN7581_XFP_MAC_RST ] =28 , + [EN7581_USB_HOST_P1_RST ] =29 , + [EN7581_USB_HOST_P1_U3_PHY_RST ] =30 , +/* RST_CTRL1 */ + [EN7581_PCM1_ZSI_ISI_RST ] =RST_NR_PER_BANK +0 , + [EN7581_FE_PDMA_RST ] =RST_NR_PER_BANK +1 , + [EN7581_FE_QDMA_RST ] =RST_NR_PER_BANK +2 , + [EN7581_PCM_SPIWP_RST ] =RST_NR_PER_BANK +4 , + [EN7581_CRYPTO_RST ] =RST_NR_PER_BANK +6 , + [EN7581_TIMER_RST ] =RST_NR_PER_BANK +8 , + [EN7581_PCM1_RST ] =RST_NR_PER_BANK +11 , + [EN7581_UART_RST ] =RST_NR_PER_BANK +12 , + [EN7581_GPIO_RST ] =RST_NR_PER_BANK +13 , + [EN7581_GDMA_RST ] =RST_NR_PER_BANK +14 , + [EN7581_I2C_MASTER_RST ] =RST_NR_PER_BANK +16 , + [EN7581_PCM2_ZSI_ISI_RST ] =RST_NR_PER_BANK +17 , + [EN7581_SFC_RST ] =RST_NR_PER_BANK +18 , + [EN7581_UART2_RST ] =RST_NR_PER_BANK +19 , + [EN7581_GDMP_RST ] =RST_NR_PER_BANK +20 , + [EN7581_FE_RST ] =RST_NR_PER_BANK +21 , + [EN7581_USB_HOST_P0_RST ] =RST_NR_PER_BANK +22 , + [EN7581_GSW_RST ] =RST_NR_PER_BANK +23 , + [EN7581_SFC2_PCM_RST ] =RST_NR_PER_BANK +25 , + [EN7581_PCIE0_RST ] =RST_NR_PER_BANK +26 , + [EN7581_PCIE1_RST ] =RST_NR_PER_BANK +27 , + [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 , +}; +static unsigned int en7523_get_base_rate (void __iomem *base,unsigned int i) {const struct en_clk_desc *desc = &en7523_base_clks[i];
@@ -424,6 +503,96 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat clk_data->num =EN7523_NUM_CLOCKS ; } +static int en7523_reset_update (struct reset_controller_dev *rcdev, +unsigned long id,bool assert) +{ +struct en_rst_data *rst_data; +void __iomem *addr; +u32 val; + + rst_data = container_of(rcdev, struct en_rst_data, rcdev); + addr = rst_data->base + rst_data->bank_ofs[id /RST_NR_PER_BANK ]; + + val =readl (addr); +if (assert) + val |=BIT (id %RST_NR_PER_BANK ); +else + val &= ~BIT (id %RST_NR_PER_BANK ); +writel (val, addr); + +return 0 ; +} + +static int en7523_reset_assert (struct reset_controller_dev *rcdev, +unsigned long id) +{ +return en7523_reset_update (rcdev, id, true); +} + +static int en7523_reset_deassert (struct reset_controller_dev *rcdev, +unsigned long id) +{ +return en7523_reset_update (rcdev, id, false); +} + +static int en7523_reset_status (struct reset_controller_dev *rcdev, +unsigned long id) +{ +struct en_rst_data *rst_data; +void __iomem *addr; + + rst_data = container_of(rcdev, struct en_rst_data, rcdev); + addr = rst_data->base + rst_data->bank_ofs[id /RST_NR_PER_BANK ]; + +return !!(readl (addr) &BIT (id %RST_NR_PER_BANK )); +} + +static int en7523_reset_xlate (struct reset_controller_dev *rcdev, +const struct of_phandle_args *reset_spec) +{ +struct en_rst_data *rst_data; + + rst_data = container_of(rcdev, struct en_rst_data, rcdev); +if (reset_spec->args[0 ] >= rcdev->nr_resets) +return -EINVAL ; + +return rst_data->idx_map[reset_spec->args[0 ]]; +} + +static const struct reset_control_ops en7523_reset_ops = { + .assert = en7523_reset_assert, + .deassert = en7523_reset_deassert, + .status = en7523_reset_status, +}; + +static int en7523_reset_register (struct device *dev,void __iomem *base, +const struct en_clk_soc_data *soc_data) +{ +struct en_rst_data *rst_data; + +/* no reset lines available */ +if (!soc_data->reset.idx_map_nr) +return 0 ; + + rst_data =devm_kzalloc (dev,sizeof (*rst_data),GFP_KERNEL ); +if (!rst_data) +return -ENOMEM ; + + rst_data->bank_ofs = soc_data->reset.bank_ofs; + rst_data->idx_map = soc_data->reset.idx_map; + rst_data->base = base; + + rst_data->rcdev.nr_resets = soc_data->reset.idx_map_nr; + rst_data->rcdev.of_xlate = en7523_reset_xlate; + rst_data->rcdev.ops = &en7523_reset_ops; + rst_data->rcdev.of_node = dev->of_node; + rst_data->rcdev.of_reset_n_cells =1 ; + rst_data->rcdev.owner =THIS_MODULE ; + rst_data->rcdev.dev = dev; + +return devm_reset_controller_register (dev, &rst_data->rcdev); +} +static int en7523_clk_probe (struct platform_device *pdev) {struct device_node *node = pdev->dev.of_node;
@@ -456,12 +625,23 @@ static int en7523_clk_probe(struct platform_device *pdev)en7523_register_clocks (&pdev->dev, clk_data, base, np_base); r =of_clk_add_hw_provider (node, of_clk_hw_onecell_get, clk_data); -if (r) +if (r) {dev_err (&pdev->dev,"could not register clock provider: %s: %d\n" , pdev->name, r); +return r; + } + + r =en7523_reset_register (&pdev->dev, np_base, soc_data); +if (r) { +dev_err (&pdev->dev, +"could not register reset controller: %s: %d\n" , + pdev->name, r); +of_clk_del_provider (node); +return r; + } -return r; +return 0 ; }static const struct en_clk_soc_data en7523_data = {
@@ -480,6 +660,11 @@ static const struct en_clk_soc_data en7581_data = { .unprepare = en7581_pci_unprepare, .disable = en7581_pci_disable, }, + .reset = { + .bank_ofs = en7581_rst_ofs, + .idx_map = en7581_rst_map, + .idx_map_nr = ARRAY_SIZE(en7581_rst_map), + }, .hw_init = en7581_clk_hw_init, };
Signature · 1 line
2.45.0
PATCH v2 4/4 clk: en7523: Remove pcie prepare/unpreare callbacks for EN7581 SoC
In reply to Lorenzo BianconiGet rid of prepare and unpreare callbacks for PCIe clock since they can be modeled as a reset line cosumed by the PCIe driver (pcie-mediatek-gen3)
--- drivers/clk/clk-en7523.c | 41 ++-------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-)
drivers/clk/clk-en7523.c +2 -39
@@ -359,9 +359,8 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev, cg->base = np_base; cg->hw.init = &init; -if (init.ops->disable) - init.ops->disable (&cg->hw); - init.ops->unprepare (&cg->hw); +if (init.ops->unprepare) + init.ops->unprepare (&cg->hw);if (clk_hw_register (dev, &cg->hw))return NULL ;
@@ -379,23 +378,6 @@ static int en7581_pci_is_enabled(struct clk_hw *hw)return (val & mask) == mask; } -static int en7581_pci_prepare (struct clk_hw *hw) -{ - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); -void __iomem *np_base = cg->base; -u32 val, mask; - - mask =REG_RESET_CONTROL_PCIE1 |REG_RESET_CONTROL_PCIE2 | -REG_RESET_CONTROL_PCIEHB ; - val =readl (np_base +REG_RESET_CONTROL1 ); -writel (val & ~mask, np_base +REG_RESET_CONTROL1 ); - val =readl (np_base +REG_RESET_CONTROL2 ); -writel (val & ~REG_RESET2_CONTROL_PCIE2 , np_base +REG_RESET_CONTROL2 ); -usleep_range (5000 ,10000 ); - -return 0 ; -} -static int en7581_pci_enable (struct clk_hw *hw) { struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
@@ -412,23 +394,6 @@ static int en7581_pci_enable(struct clk_hw *hw)return 0 ; } -static void en7581_pci_unprepare (struct clk_hw *hw) -{ - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); -void __iomem *np_base = cg->base; -u32 val, mask; - - mask =REG_RESET_CONTROL_PCIE1 |REG_RESET_CONTROL_PCIE2 | -REG_RESET_CONTROL_PCIEHB ; - val =readl (np_base +REG_RESET_CONTROL1 ); -writel (val | mask, np_base +REG_RESET_CONTROL1 ); - mask =REG_RESET_CONTROL_PCIE1 |REG_RESET_CONTROL_PCIE2 ; -writel (val | mask, np_base +REG_RESET_CONTROL1 ); - val =readl (np_base +REG_RESET_CONTROL2 ); -writel (val |REG_RESET_CONTROL_PCIE2 , np_base +REG_RESET_CONTROL2 ); -msleep (100 ); -} -static void en7581_pci_disable (struct clk_hw *hw) { struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
@@ -655,9 +620,7 @@ static const struct en_clk_soc_data en7523_data = {static const struct en_clk_soc_data en7581_data = { .pcie_ops = { .is_enabled = en7581_pci_is_enabled, - .prepare = en7581_pci_prepare, .enable = en7581_pci_enable, - .unprepare = en7581_pci_unprepare, .disable = en7581_pci_disable, }, .reset = {
Signature · 1 line
2.45.0
Re: [PATCH v2 3/4] clk: en7523: Add reset-controller support for EN7581 SoC
In reply to Lorenzo BianconiIl 17/05/24 14:28, Lorenzo Bianconi ha scritto:
Quoted 4 lines
Introduce reset API support to EN7581 clock driver.
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>
Re: [PATCH v2 2/4] arm64: dts: airoha: Add reset-controller support to EN7581 clock node
In reply to Lorenzo BianconiIl 17/05/24 14:28, Lorenzo Bianconi ha scritto:
Quoted 5 lines
Introduce reset capability to scuclk clock-controller device-tree node for EN7581 SoC.
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>
Re: [PATCH v2 1/4] dt-bindings: clock: airoha: Add reset support to EN7581 clock binding
In reply to Lorenzo BianconiIl 17/05/24 14:28, Lorenzo Bianconi ha scritto:
Quoted 6 lines
Introduce reset capability to EN7581 device-tree clock binding documentation.
Acked-by Conor Dooley <[email protected]>Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>