Introduce clock support for Airoha EN7581 SoC
Subsystems (3)
cover Introduce clock support for Airoha EN7581 SoC
This series is based on the following series:
https://patchwork.kernel.org/project/linux-arm-kernel/cover/[email protected]/
Lorenzo Bianconi (4):
dt-bindings: clock: airoha: add EN7581 binding
arm64: dts: airoha: Add EN7581 clock node
clk: en7523: make pcie clk_ops accessible through of_device_id struct
clk: en7523: add EN7581 support
.../bindings/clock/airoha,en7523-scu.yaml | 26 ++- arch/arm64/boot/dts/airoha/en7581.dtsi | 9 + drivers/clk/clk-en7523.c | 155 ++++++++++++++++-- 3 files changed, 171 insertions(+), 19 deletions(-)
Signature · 1 line
2.44.0
PATCH 1/4 dt-bindings: clock: airoha: add EN7581 binding
Introduce Airoha EN7581 entry in Airoha EN7523 clock binding
--- .../bindings/clock/airoha,en7523-scu.yaml | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +24 -2
@@ -29,10 +29,13 @@ description: | properties: compatible: items: - - const: airoha,en7523-scu + - enum: + - airoha,en7523-scu + - airoha,en7581-scu reg: - maxItems: 2 + minItems: 2 + maxItems: 3 "#clock-cells": description:
@@ -45,6 +48,25 @@ required: - reg - '#clock-cells' +allOf: + - if: + properties: + compatible: + const: airoha,en7523-scu + then: + properties: + reg: + maxItems: 2 + + - if: + properties: + compatible: + const: airoha,en7581-scu + then: + properties: + reg: + maxItems: 3 + additionalProperties: false examples:
Signature · 1 line
2.44.0
Re: [PATCH 1/4] dt-bindings: clock: airoha: add EN7581 binding
Quoted 39 lines · Lorenzo Bianconi
Introduce Airoha EN7581 entry in Airoha EN7523 clock binding
Signed-off-by Lorenzo Bianconi <[email protected]>--- .../bindings/clock/airoha,en7523-scu.yaml | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +13
-2@@ -29,10 +29,13 @@ description: | properties: compatible: items: - - const: airoha,en7523-scu + - enum: + - airoha,en7523-scu + - airoha,en7581-scu reg: - maxItems: 2 + minItems: 2 + maxItems: 3 "#clock-cells": description:@@ -45,6 +48,25 @@ required: - reg - '#clock-cells' +allOf: + - if: + properties: + compatible: + const: airoha,en7523-scu + then: + properties: + reg:
Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml required: · line 68
Quoted 10 lines
Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +10
-0+ maxItems: 2 + + - if: + properties: + compatible: + const: airoha,en7581-scu + then: + properties: + reg: + maxItems: 3
Original code had here issue - lack of description of the items. You are now growing it. Please instead list the items (items: - description: foo bar .....).
Best regards,
Krzysztof
Re: [PATCH 1/4] dt-bindings: clock: airoha: add EN7581 binding
Quoted 46 lines · Lorenzo Bianconi
Quoted 45 lines
Introduce Airoha EN7581 entry in Airoha EN7523 clock binding
Signed-off-by Lorenzo Bianconi <[email protected]>--- .../bindings/clock/airoha,en7523-scu.yaml | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +19
-2@@ -29,10 +29,13 @@ description: | properties: compatible: items: - - const: airoha,en7523-scu + - enum: + - airoha,en7523-scu + - airoha,en7581-scu reg: - maxItems: 2 + minItems: 2 + maxItems: 3 "#clock-cells": description:@@ -45,6 +48,25 @@ required: - reg - '#clock-cells' +allOf: + - if: + properties: + compatible: + const: airoha,en7523-scu + then: + properties: + reg: + maxItems: 2 + + - if: + properties: + compatible: + const: airoha,en7581-scu
Quoted 8 lines
Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml required: · line 68
Quoted 4 lines
Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +4
-0+ then: + properties: + reg: + maxItems: 3Original code had here issue - lack of description of the items. You are now growing it. Please instead list the items (items: - description: foo bar .....).
ack, I will fix it.
Regards,
Lorenzo
Quoted 4 lines
Best regards,
Krzysztof
PATCH 2/4 arm64: dts: airoha: Add EN7581 clock node
In reply to Lorenzo BianconiIntroduce the Airoha EN7581 clock node in Airoha EN7581 dtsi
--- arch/arm64/boot/dts/airoha/en7581.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/arm64/boot/dts/airoha/en7581.dtsi +9 -0
@@ -2,6 +2,7 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/en7523-clk.h> / { interrupt-parent = <&gic>;
@@ -150,5 +151,13 @@ uart1: serial@1fbf0000 { interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; clock-frequency = <1843200>; }; + + scu: system-controller@1fa20000 { + compatible = "airoha,en7581-scu"; + reg = <0x0 0x1fa20000 0x0 0x400>, + <0x0 0x1fb00000 0x0 0x1000>, + <0x0 0x1fbe3400 0x0 0xfc>; + #clock-cells = <1>; + }; }; };
Signature · 1 line
2.44.0
AngeloGioacchino Del Regno
maintainerRe: [PATCH 2/4] arm64: dts: airoha: Add EN7581 clock node
Il 03/04/24 18:20, Lorenzo Bianconi ha scritto:
Quoted 21 lines
Introduce the Airoha EN7581 clock node in Airoha EN7581 dtsi
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- arch/arm64/boot/dts/airoha/en7581.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)arch/arm64/boot/dts/airoha/en7581.dtsi +1
-0@@ -2,6 +2,7 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/en7523-clk.h> / { interrupt-parent = <&gic>;
arch/arm64/boot/dts/airoha/en7581.dtsi uart1: serial@1fbf0000 { · line 155
Quoted 5 lines
arch/arm64/boot/dts/airoha/en7581.dtsi +2
-0@@ -150,5 +151,13 @@ uart1: serial@1fbf0000 { interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; clock-frequency = <1843200>; }; + + scu: system-controller@1fa20000 {
Uhm, why is this not a clock-controller but a system-controller?
Cheers,
Angelo
Quoted 8 lines
arch/arm64/boot/dts/airoha/en7581.dtsi +6
-0+ compatible = "airoha,en7581-scu"; + reg = <0x0 0x1fa20000 0x0 0x400>, + <0x0 0x1fb00000 0x0 0x1000>, + <0x0 0x1fbe3400 0x0 0xfc>; + #clock-cells = <1>; + }; }; };
Re: [PATCH 2/4] arm64: dts: airoha: Add EN7581 clock node
Quoted 19 lines
Il 03/04/24 18:20, Lorenzo Bianconi ha scritto:
Quoted 18 lines
Introduce the Airoha EN7581 clock node in Airoha EN7581 dtsi
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- arch/arm64/boot/dts/airoha/en7581.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)arch/arm64/boot/dts/airoha/en7581.dtsi +1
-0@@ -2,6 +2,7 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/en7523-clk.h> / { interrupt-parent = <&gic>;
Quoted 8 lines
arch/arm64/boot/dts/airoha/en7581.dtsi uart1: serial@1fbf0000 { · line 155
Quoted 6 lines
arch/arm64/boot/dts/airoha/en7581.dtsi +2
-0@@ -150,5 +151,13 @@ uart1: serial@1fbf0000 { interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; clock-frequency = <1843200>; }; + + scu: system-controller@1fa20000 {Uhm, why is this not a clock-controller but a system-controller?
I used the same approach used for en7523.dtsi. I guess it is done that way because the registers come from scu (system control unit) regmap, but I guess we can use clock-controller instead.
Regards,
Lorenzo
Quoted 15 lines
Cheers,
AngeloQuoted 8 lines
arch/arm64/boot/dts/airoha/en7581.dtsi +6
-0+ compatible = "airoha,en7581-scu"; + reg = <0x0 0x1fa20000 0x0 0x400>, + <0x0 0x1fb00000 0x0 0x1000>, + <0x0 0x1fbe3400 0x0 0xfc>; + #clock-cells = <1>; + }; }; };
AngeloGioacchino Del Regno
maintainerRe: [PATCH 2/4] arm64: dts: airoha: Add EN7581 clock node
Il 04/04/24 10:57, Lorenzo Bianconi ha scritto:
Quoted 28 lines
Quoted 19 lines
Il 03/04/24 18:20, Lorenzo Bianconi ha scritto:
Quoted 18 lines
Introduce the Airoha EN7581 clock node in Airoha EN7581 dtsi
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- arch/arm64/boot/dts/airoha/en7581.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)arch/arm64/boot/dts/airoha/en7581.dtsi +1
-0@@ -2,6 +2,7 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/en7523-clk.h> / { interrupt-parent = <&gic>;Quoted 8 lines
arch/arm64/boot/dts/airoha/en7581.dtsi uart1: serial@1fbf0000 { · line 155
Quoted 6 lines
arch/arm64/boot/dts/airoha/en7581.dtsi +2
-0@@ -150,5 +151,13 @@ uart1: serial@1fbf0000 { interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; clock-frequency = <1843200>; }; + + scu: system-controller@1fa20000 {Uhm, why is this not a clock-controller but a system-controller?
Quoted 4 lines
I used the same approach used for
en7523.dtsi. I guess it is done that way because the registers come from scu (system control unit) regmap, but I guess we can use clock-controller instead.
Yeah, comes from there but you're actually defining a node for a clock-controller, not a system-controller... makes sense to define this as
scuclk: clock-controller@1fa20000
...or something along that line (for the phandle) so that, if another scu related node appears for whatever reason, we distinguish between scuxyz and scuclk.
Cheers
Quoted 18 lines
Regards,
LorenzoQuoted 15 lines
Cheers,
AngeloQuoted 8 lines
arch/arm64/boot/dts/airoha/en7581.dtsi +6
-0+ compatible = "airoha,en7581-scu"; + reg = <0x0 0x1fa20000 0x0 0x400>, + <0x0 0x1fb00000 0x0 0x1000>, + <0x0 0x1fbe3400 0x0 0xfc>; + #clock-cells = <1>; + }; }; };
Re: [PATCH 2/4] arm64: dts: airoha: Add EN7581 clock node
Quoted 34 lines
Il 04/04/24 10:57, Lorenzo Bianconi ha scritto:
Quoted 28 lines
Quoted 19 lines
Il 03/04/24 18:20, Lorenzo Bianconi ha scritto:
Quoted 18 lines
Introduce the Airoha EN7581 clock node in Airoha EN7581 dtsi
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- arch/arm64/boot/dts/airoha/en7581.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)arch/arm64/boot/dts/airoha/en7581.dtsi +1
-0@@ -2,6 +2,7 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/en7523-clk.h> / { interrupt-parent = <&gic>;Quoted 8 lines
arch/arm64/boot/dts/airoha/en7581.dtsi uart1: serial@1fbf0000 { · line 155
Quoted 6 lines
arch/arm64/boot/dts/airoha/en7581.dtsi +2
-0@@ -150,5 +151,13 @@ uart1: serial@1fbf0000 { interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; clock-frequency = <1843200>; }; + + scu: system-controller@1fa20000 {Uhm, why is this not a clock-controller but a system-controller?
Quoted 4 lines
I used the same approach used for
en7523.dtsi. I guess it is done that way because the registers come from scu (system control unit) regmap, but I guess we can use clock-controller instead.
Quoted 7 lines
Yeah, comes from there but you're actually defining a node for a clock-controller, not a system-controller... makes sense to define this as
scuclk: clock-controller@1fa20000...or something along that line (for the phandle) so that, if another scu related node appears for whatever reason, we distinguish between scuxyz and scuclk.
ack, I agree. I will fix it.
Regards,
Lorenzo
Quoted 23 lines
Cheers
Quoted 18 lines
Regards,
LorenzoQuoted 15 lines
Cheers,
AngeloQuoted 8 lines
arch/arm64/boot/dts/airoha/en7581.dtsi +6
-0+ compatible = "airoha,en7581-scu"; + reg = <0x0 0x1fa20000 0x0 0x400>, + <0x0 0x1fb00000 0x0 0x1000>, + <0x0 0x1fbe3400 0x0 0xfc>; + #clock-cells = <1>; + }; }; };
PATCH 3/4 clk: en7523: make pcie clk_ops accessible through of_device_id struct
In reply to Lorenzo BianconiMake pcie clk_ops structure accessible through of_device_id data pointer in order to define multiple clk_ops for each supported SoC. This is a preliminary patch to introduce EN7581 clock support.
--- drivers/clk/clk-en7523.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/clk/clk-en7523.c +13 -12
@@ -145,11 +145,6 @@ static const struct en_clk_desc en7523_base_clks[] = { } }; -static const struct of_device_id of_match_clk_en7523[] = { - { .compatible ="airoha,en7523-scu" , }, - {/* sentinel */ } -}; -static unsigned int en7523_get_base_rate (void __iomem *base,unsigned int i) {const struct en_clk_desc *desc = &en7523_base_clks[i];
@@ -247,14 +242,9 @@ static void en7523_pci_unprepare(struct clk_hw *hw)static struct clk_hw *en7523_register_pcie_clk (struct device *dev,void __iomem *np_base) { -static const struct clk_ops pcie_gate_ops = { - .is_enabled = en7523_pci_is_enabled, - .prepare = en7523_pci_prepare, - .unprepare = en7523_pci_unprepare, - };struct clk_init_data init = { .name ="pcie" , - .ops = &pcie_gate_ops, + .ops =of_device_get_match_data (dev), };struct en_clk_gate *cg;
@@ -264,7 +254,7 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev, cg->base = np_base; cg->hw.init = &init; -en7523_pci_unprepare (&cg->hw); + init.ops->unprepare (&cg->hw);if (clk_hw_register (dev, &cg->hw))return NULL ;
@@ -333,6 +323,17 @@ static int en7523_clk_probe(struct platform_device *pdev)return r; } +static const struct clk_ops en7523_pcie_ops = { + .is_enabled = en7523_pci_is_enabled, + .prepare = en7523_pci_prepare, + .unprepare = en7523_pci_unprepare, +}; + +static const struct of_device_id of_match_clk_en7523[] = { + { .compatible ="airoha,en7523-scu" , .data = &en7523_pcie_ops }, + {/* sentinel */ } +}; +static struct platform_driver clk_en7523_drv = { .probe = en7523_clk_probe, .driver = {
Signature · 1 line
2.44.0
PATCH 4/4 clk: en7523: add EN7581 support
In reply to Lorenzo BianconiIntroduce EN7581 clock support to clk-en7523 driver.
--- drivers/clk/clk-en7523.c | 130 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 5 deletions(-)
drivers/clk/clk-en7523.c +125 -5
@@ -4,13 +4,16 @@#include <linux/clk-provider.h> #include <linux/io.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <dt-bindings/clock/en7523-clk.h> #define REG_PCI_CONTROL 0x88#define REG_PCI_CONTROL_PERSTOUT BIT(29)#define REG_PCI_CONTROL_PERSTOUT1 BIT(26) +#define REG_PCI_CONTROL_REFCLK_EN0 BIT(23)#define REG_PCI_CONTROL_REFCLK_EN1 BIT(22) +#define REG_PCI_CONTROL_PERSTOUT2 BIT(16)#define REG_GSW_CLK_DIV_SEL 0x1b4#define REG_EMI_CLK_DIV_SEL 0x1b8#define REG_BUS_CLK_DIV_SEL 0x1bc
@@ -18,10 +21,25 @@#define REG_SPI_CLK_FREQ_SEL 0x1c8#define REG_NPU_CLK_DIV_SEL 0x1fc#define REG_CRYPTO_CLKSRC 0x200 -#define REG_RESET_CONTROL 0x834 +#define REG_RESET_CONTROL2 0x830 +#define REG_RESET2_CONTROL_PCIE2 BIT(27) +#define REG_RESET_CONTROL1 0x834#define REG_RESET_CONTROL_PCIEHB BIT(29)#define REG_RESET_CONTROL_PCIE1 BIT(27)#define REG_RESET_CONTROL_PCIE2 BIT(26) +/* EN7581 */ +#define REG_PCIE0_MEM 0x00 +#define REG_PCIE0_MEM_MASK 0x04 +#define REG_PCIE1_MEM 0x08 +#define REG_PCIE1_MEM_MASK 0x0c +#define REG_PCIE2_MEM 0x10 +#define REG_PCIE2_MEM_MASK 0x14 +#define REG_PCIE_RESET_OPEN_DRAIN 0x018c +#define REG_PCIE_RESET_OPEN_DRAIN_MASK GENMASK(2, 0) +#define REG_NP_SCU_PCIC 0x88 +#define REG_NP_SCU_SSTR 0x9c +#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) +#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)struct en_clk_desc {int id;
@@ -207,14 +225,14 @@ static int en7523_pci_prepare(struct clk_hw *hw)usleep_range (1000 ,2000 );/* Reset to default */ - val =readl (np_base +REG_RESET_CONTROL ); + val =readl (np_base +REG_RESET_CONTROL1 ); mask =REG_RESET_CONTROL_PCIE1 |REG_RESET_CONTROL_PCIE2 |REG_RESET_CONTROL_PCIEHB ; -writel (val & ~mask, np_base +REG_RESET_CONTROL ); +writel (val & ~mask, np_base +REG_RESET_CONTROL1 );usleep_range (1000 ,2000 ); -writel (val | mask, np_base +REG_RESET_CONTROL ); +writel (val | mask, np_base +REG_RESET_CONTROL1 );msleep (100 ); -writel (val & ~mask, np_base +REG_RESET_CONTROL ); +writel (val & ~mask, np_base +REG_RESET_CONTROL1 );usleep_range (5000 ,10000 );/* Release device */
@@ -262,6 +280,64 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev,return &cg->hw; } +static int en7581_pci_is_enabled (struct clk_hw *hw) +{ + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); +u32 val, mask; + + mask =REG_PCI_CONTROL_REFCLK_EN0 |REG_PCI_CONTROL_REFCLK_EN1 ; + val =readl (cg->base +REG_PCI_CONTROL ); +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 ); + + mask =REG_PCI_CONTROL_REFCLK_EN0 |REG_PCI_CONTROL_REFCLK_EN1 | +REG_PCI_CONTROL_PERSTOUT1 |REG_PCI_CONTROL_PERSTOUT2 | +REG_PCI_CONTROL_PERSTOUT ; + val =readl (np_base +REG_PCI_CONTROL ); +writel (val | mask, np_base +REG_PCI_CONTROL ); +msleep (250 ); + +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_PCI_CONTROL_REFCLK_EN0 |REG_PCI_CONTROL_REFCLK_EN1 | +REG_PCI_CONTROL_PERSTOUT1 |REG_PCI_CONTROL_PERSTOUT2 | +REG_PCI_CONTROL_PERSTOUT ; + val =readl (np_base +REG_PCI_CONTROL ); +writel (val & ~mask, np_base +REG_PCI_CONTROL ); +usleep_range (1000 ,2000 ); + + 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 en7523_register_clocks (struct device *dev,struct clk_hw_onecell_data *clk_data,void __iomem *base,void __iomem *np_base) {
@@ -291,6 +367,37 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat clk_data->num =EN7523_NUM_CLOCKS ; } +static int en7581_clk_hw_init (struct platform_device *pdev, +void __iomem *base, +void __iomem *np_base) +{ +void __iomem *pb_base; +u32 val; + + pb_base =devm_platform_ioremap_resource (pdev,2 ); +if (IS_ERR (pb_base)) +return PTR_ERR (pb_base); + + val =readl (np_base +REG_NP_SCU_SSTR ); + val &= ~(REG_PCIE_XSI0_SEL_MASK |REG_PCIE_XSI1_SEL_MASK ); +writel (val, np_base +REG_NP_SCU_SSTR ); + val =readl (np_base +REG_NP_SCU_PCIC ); +writel (val |3 , np_base +REG_NP_SCU_PCIC ); + +writel (0x20000000 , pb_base +REG_PCIE0_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE0_MEM_MASK ); +writel (0x24000000 , pb_base +REG_PCIE1_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE1_MEM_MASK ); +writel (0x28000000 , pb_base +REG_PCIE2_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE2_MEM_MASK ); + + val =readl (base +REG_PCIE_RESET_OPEN_DRAIN ); +writel (val |REG_PCIE_RESET_OPEN_DRAIN_MASK , + base +REG_PCIE_RESET_OPEN_DRAIN ); + +return 0 ; +} +static int en7523_clk_probe (struct platform_device *pdev) {struct device_node *node = pdev->dev.of_node;
@@ -306,6 +413,12 @@ static int en7523_clk_probe(struct platform_device *pdev)if (IS_ERR (np_base))return PTR_ERR (np_base); +if (of_device_is_compatible (node,"airoha,en7581-scu" )) { + r =en7581_clk_hw_init (pdev, base, np_base); +if (r) +return r; + } + clk_data =devm_kzalloc (&pdev->dev,struct_size (clk_data, hws,EN7523_NUM_CLOCKS ),GFP_KERNEL );
@@ -329,8 +442,15 @@ static const struct clk_ops en7523_pcie_ops = { .unprepare = en7523_pci_unprepare, }; +static const struct clk_ops en7581_pcie_ops = { + .is_enabled = en7581_pci_is_enabled, + .prepare = en7581_pci_prepare, + .unprepare = en7581_pci_unprepare, +}; +static const struct of_device_id of_match_clk_en7523[] = { { .compatible ="airoha,en7523-scu" , .data = &en7523_pcie_ops }, + { .compatible ="airoha,en7581-scu" , .data = &en7581_pcie_ops }, {/* sentinel */ } };
Signature · 1 line
2.44.0
Re: [PATCH 4/4] clk: en7523: add EN7581 support
Quoted 13 lines · Lorenzo Bianconi
Introduce EN7581 clock support to clk-en7523 driver.
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>drivers/clk/clk-en7523.c +3
-0+return 0 ; +} +static int en7523_clk_probe (struct platform_device *pdev) {struct device_node *node = pdev->dev.of_node;
drivers/clk/clk-en7523.c static int en7523_clk_probe(struct platform_device *pdev) · line 416
Quoted 4 lines
drivers/clk/clk-en7523.c +1
-0@@ -306,6 +413,12 @@ static int en7523_clk_probe(struct platform_device *pdev)if (IS_ERR (np_base))return PTR_ERR (np_base); +if (of_device_is_compatible (node,"airoha,en7581-scu" )) {
Having matching and compatible comparisons inside various code is discouraged. Does not scale. Use driver/match data to store some sort of flags and check for the flag or some other parameter. The best if compatible appears once and only once: in of_device_id.
Quoted 14 lines
drivers/clk/clk-en7523.c +7
-0+ r =en7581_clk_hw_init (pdev, base, np_base); +if (r) +return r; + } + clk_data =devm_kzalloc (&pdev->dev,struct_size (clk_data, hws,EN7523_NUM_CLOCKS ),GFP_KERNEL );@@ -329,8 +442,15 @@ static const struct clk_ops en7523_pcie_ops = { .unprepare = en7523_pci_unprepare, }; +static const struct clk_ops en7581_pcie_ops = { + .is_enabled = en7581_pci_is_enabled,
drivers/clk/clk-en7523.c static const struct clk_ops en7523_pcie_ops = { · line 456
Quoted 10 lines
drivers/clk/clk-en7523.c +5
-0+ .prepare = en7581_pci_prepare, + .unprepare = en7581_pci_unprepare, +}; +static const struct of_device_id of_match_clk_en7523[] = { { .compatible ="airoha,en7523-scu" , .data = &en7523_pcie_ops }, + { .compatible ="airoha,en7581-scu" , .data = &en7581_pcie_ops }, {/* sentinel */ } };
Best regards,
Krzysztof
Re: [PATCH 4/4] clk: en7523: add EN7581 support
Quoted 17 lines · Lorenzo Bianconi
Quoted 16 lines
Introduce EN7581 clock support to clk-en7523 driver.
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>drivers/clk/clk-en7523.c +3
-0+return 0 ; +} +static int en7523_clk_probe (struct platform_device *pdev) {struct device_node *node = pdev->dev.of_node;@@ -306,6 +413,12 @@ static int en7523_clk_probe(struct platform_device *pdev)if (IS_ERR (np_base))return PTR_ERR (np_base);
Quoted 6 lines
drivers/clk/clk-en7523.c static int en7523_clk_probe(struct platform_device *pdev) · line 416
Quoted 1 line
drivers/clk/clk-en7523.c +1
-0+if (of_device_is_compatible (node,"airoha,en7581-scu" )) {Having matching and compatible comparisons inside various code is discouraged. Does not scale. Use driver/match data to store some sort of flags and check for the flag or some other parameter. The best if compatible appears once and only once: in
of_device_id.
ack, I will fix it.
Regards,
Lorenzo
Quoted 29 lines
Quoted 15 lines
drivers/clk/clk-en7523.c +7
-0+ r =en7581_clk_hw_init (pdev, base, np_base); +if (r) +return r; + } + clk_data =devm_kzalloc (&pdev->dev,struct_size (clk_data, hws,EN7523_NUM_CLOCKS ),GFP_KERNEL );@@ -329,8 +442,15 @@ static const struct clk_ops en7523_pcie_ops = { .unprepare = en7523_pci_unprepare, }; +static const struct clk_ops en7581_pcie_ops = { + .is_enabled = en7581_pci_is_enabled,drivers/clk/clk-en7523.c static const struct clk_ops en7523_pcie_ops = { · line 456
Quoted 10 lines
drivers/clk/clk-en7523.c +5
-0+ .prepare = en7581_pci_prepare, + .unprepare = en7581_pci_unprepare, +}; +static const struct of_device_id of_match_clk_en7523[] = { { .compatible ="airoha,en7523-scu" , .data = &en7523_pcie_ops }, + { .compatible ="airoha,en7581-scu" , .data = &en7581_pcie_ops }, {/* sentinel */ } };Best regards,
Krzysztof
AngeloGioacchino Del Regno
maintainerRe: [PATCH 4/4] clk: en7523: add EN7581 support
In reply to Lorenzo BianconiIl 03/04/24 18:20, Lorenzo Bianconi ha scritto:
Quoted 30 lines
Introduce EN7581 clock support to clk-en7523 driver.
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/clk/clk-en7523.c | 130 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 5 deletions(-)drivers/clk/clk-en7523.c +3
-0@@ -4,13 +4,16 @@#include <linux/clk-provider.h> #include <linux/io.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <dt-bindings/clock/en7523-clk.h> #define REG_PCI_CONTROL 0x88#define REG_PCI_CONTROL_PERSTOUT BIT(29)#define REG_PCI_CONTROL_PERSTOUT1 BIT(26) +#define REG_PCI_CONTROL_REFCLK_EN0 BIT(23)#define REG_PCI_CONTROL_REFCLK_EN1 BIT(22) +#define REG_PCI_CONTROL_PERSTOUT2 BIT(16)#define REG_GSW_CLK_DIV_SEL 0x1b4#define REG_EMI_CLK_DIV_SEL 0x1b8#define REG_BUS_CLK_DIV_SEL 0x1bc
drivers/clk/clk-en7523.c line 24
Quoted 5 lines
drivers/clk/clk-en7523.c +1
-1@@ -18,10 +21,25 @@#define REG_SPI_CLK_FREQ_SEL 0x1c8#define REG_NPU_CLK_DIV_SEL 0x1fc#define REG_CRYPTO_CLKSRC 0x200 -#define REG_RESET_CONTROL 0x834 +#define REG_RESET_CONTROL2 0x830
Wait what? The RESET2 register comes before RESET1 ?!?!
Is this a typo? :-)
Quoted 61 lines
drivers/clk/clk-en7523.c +36
-4+#define REG_RESET2_CONTROL_PCIE2 BIT(27) +#define REG_RESET_CONTROL1 0x834#define REG_RESET_CONTROL_PCIEHB BIT(29)#define REG_RESET_CONTROL_PCIE1 BIT(27)#define REG_RESET_CONTROL_PCIE2 BIT(26) +/* EN7581 */ +#define REG_PCIE0_MEM 0x00 +#define REG_PCIE0_MEM_MASK 0x04 +#define REG_PCIE1_MEM 0x08 +#define REG_PCIE1_MEM_MASK 0x0c +#define REG_PCIE2_MEM 0x10 +#define REG_PCIE2_MEM_MASK 0x14 +#define REG_PCIE_RESET_OPEN_DRAIN 0x018c +#define REG_PCIE_RESET_OPEN_DRAIN_MASK GENMASK(2, 0) +#define REG_NP_SCU_PCIC 0x88 +#define REG_NP_SCU_SSTR 0x9c +#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) +#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)struct en_clk_desc {int id;@@ -207,14 +225,14 @@ static int en7523_pci_prepare(struct clk_hw *hw)usleep_range (1000 ,2000 );/* Reset to default */ - val =readl (np_base +REG_RESET_CONTROL ); + val =readl (np_base +REG_RESET_CONTROL1 ); mask =REG_RESET_CONTROL_PCIE1 |REG_RESET_CONTROL_PCIE2 |REG_RESET_CONTROL_PCIEHB ; -writel (val & ~mask, np_base +REG_RESET_CONTROL ); +writel (val & ~mask, np_base +REG_RESET_CONTROL1 );usleep_range (1000 ,2000 ); -writel (val | mask, np_base +REG_RESET_CONTROL ); +writel (val | mask, np_base +REG_RESET_CONTROL1 );msleep (100 ); -writel (val & ~mask, np_base +REG_RESET_CONTROL ); +writel (val & ~mask, np_base +REG_RESET_CONTROL1 );usleep_range (5000 ,10000 );/* Release device */ @@ -262,6 +280,64 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev,return &cg->hw; } +static int en7581_pci_is_enabled (struct clk_hw *hw) +{ + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); +u32 val, mask; + + mask =REG_PCI_CONTROL_REFCLK_EN0 |REG_PCI_CONTROL_REFCLK_EN1 ; + val =readl (cg->base +REG_PCI_CONTROL ); +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 |
drivers/clk/clk-en7523.c static struct clk_hw *en7523_register_pcie_clk(struct device *dev, · line 309
Quoted 10 lines
drivers/clk/clk-en7523.c +10
-0+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 ); + + mask =REG_PCI_CONTROL_REFCLK_EN0 |REG_PCI_CONTROL_REFCLK_EN1 | +REG_PCI_CONTROL_PERSTOUT1 |REG_PCI_CONTROL_PERSTOUT2 | +REG_PCI_CONTROL_PERSTOUT ;
I'm not sure that this is actually something to control in a clock driver...
the right thing to do would be to add a reset controller to this clock driver and then assert/deassert reset in the PCIe PHY/MAC driver.
Perhaps REFCLK_EN0/EN1 can be manipulated in a .enable() callback, treating this really just as what it appears to really be: a gate clock! (hint: check clk-gate.c)
Quoted 4 lines
drivers/clk/clk-en7523.c +4
-0+ val =readl (np_base +REG_PCI_CONTROL ); +writel (val | mask, np_base +REG_PCI_CONTROL ); +msleep (250 ); +
drivers/clk/clk-en7523.c static struct clk_hw *en7523_register_pcie_clk(struct device *dev, · line 323
Quoted 10 lines
drivers/clk/clk-en7523.c +10
-0+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_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
...and this should be a clk-gate .disable() callback, I guess :-)
Quoted 30 lines
drivers/clk/clk-en7523.c +23
-0+REG_PCI_CONTROL_PERSTOUT1 |REG_PCI_CONTROL_PERSTOUT2 | +REG_PCI_CONTROL_PERSTOUT ; + val =readl (np_base +REG_PCI_CONTROL ); +writel (val & ~mask, np_base +REG_PCI_CONTROL ); +usleep_range (1000 ,2000 ); + + 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 en7523_register_clocks (struct device *dev,struct clk_hw_onecell_data *clk_data,void __iomem *base,void __iomem *np_base) {@@ -291,6 +367,37 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat clk_data->num =EN7523_NUM_CLOCKS ; } +static int en7581_clk_hw_init (struct platform_device *pdev, +void __iomem *base, +void __iomem *np_base) +{ +void __iomem *pb_base; +u32 val;
drivers/clk/clk-en7523.c static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat · line 385
Quoted 10 lines
drivers/clk/clk-en7523.c +10
-0+ + pb_base =devm_platform_ioremap_resource (pdev,2 ); +if (IS_ERR (pb_base)) +return PTR_ERR (pb_base); + + val =readl (np_base +REG_NP_SCU_SSTR ); + val &= ~(REG_PCIE_XSI0_SEL_MASK |REG_PCIE_XSI1_SEL_MASK ); +writel (val, np_base +REG_NP_SCU_SSTR ); + val =readl (np_base +REG_NP_SCU_PCIC ); +writel (val |3 , np_base +REG_NP_SCU_PCIC );
What is 3?
#define SOMETHING 3 ??
drivers/clk/clk-en7523.c static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat · line 392
Quoted 7 lines
drivers/clk/clk-en7523.c +7
-0+ +writel (0x20000000 , pb_base +REG_PCIE0_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE0_MEM_MASK ); +writel (0x24000000 , pb_base +REG_PCIE1_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE1_MEM_MASK ); +writel (0x28000000 , pb_base +REG_PCIE2_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE2_MEM_MASK );
And... this is .. some BIT() and some GENMASK() as far as I understand... do we have any clue about what you're setting to those registers?
Can MediaTek/Airoha help with this, please?
#define SOMETHING BIT(29) /* this is 0x20000000 */ #define SOME_MASK GENMASK(31, 26) /* this is 0xfc00000 */
Quoted 25 lines
drivers/clk/clk-en7523.c +14
-0+ + val =readl (base +REG_PCIE_RESET_OPEN_DRAIN ); +writel (val |REG_PCIE_RESET_OPEN_DRAIN_MASK , + base +REG_PCIE_RESET_OPEN_DRAIN ); + +return 0 ; +} +static int en7523_clk_probe (struct platform_device *pdev) {struct device_node *node = pdev->dev.of_node;@@ -306,6 +413,12 @@ static int en7523_clk_probe(struct platform_device *pdev)if (IS_ERR (np_base))return PTR_ERR (np_base); +if (of_device_is_compatible (node,"airoha,en7581-scu" )) { + r =en7581_clk_hw_init (pdev, base, np_base); +if (r) +return r; + } + clk_data =devm_kzalloc (&pdev->dev,struct_size (clk_data, hws,EN7523_NUM_CLOCKS ),GFP_KERNEL );
drivers/clk/clk-en7523.c static const struct clk_ops en7523_pcie_ops = { · line 444
Quoted 3 lines
drivers/clk/clk-en7523.c +0
-0@@ -329,8 +442,15 @@ static const struct clk_ops en7523_pcie_ops = { .unprepare = en7523_pci_unprepare, };
static const struct clk_en7523_pdata en7581_pdata = {
.init = en7581_clk_hw_init, /* if (pdata->init) pdata->init(x, y, z) */
.ops = en7581_pcie_ops,
};or, alternatively:
static const struct .... = {
.init = ...,
.ops = (const struct clk_ops) {
.is_enabled = en7581_pci_is_enabled,
.... etc
}
};Cheers,
Angelo
drivers/clk/clk-en7523.c static const struct clk_ops en7523_pcie_ops = { · line 456
Quoted 12 lines
drivers/clk/clk-en7523.c +7
-0+static const struct clk_ops en7581_pcie_ops = { + .is_enabled = en7581_pci_is_enabled, + .prepare = en7581_pci_prepare, + .unprepare = en7581_pci_unprepare, +}; +static const struct of_device_id of_match_clk_en7523[] = { { .compatible ="airoha,en7523-scu" , .data = &en7523_pcie_ops }, + { .compatible ="airoha,en7581-scu" , .data = &en7581_pcie_ops }, {/* sentinel */ } };
-
Re: [PATCH 4/4] clk: en7523: add EN7581 support
Quoted 38 lines
Il 03/04/24 18:20, Lorenzo Bianconi ha scritto:
Quoted 29 lines
Introduce EN7581 clock support to clk-en7523 driver.
Tested-by Zhengping Zhang <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/clk/clk-en7523.c | 130 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 5 deletions(-)drivers/clk/clk-en7523.c +3
-0@@ -4,13 +4,16 @@#include <linux/clk-provider.h> #include <linux/io.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <dt-bindings/clock/en7523-clk.h> #define REG_PCI_CONTROL 0x88#define REG_PCI_CONTROL_PERSTOUT BIT(29)#define REG_PCI_CONTROL_PERSTOUT1 BIT(26) +#define REG_PCI_CONTROL_REFCLK_EN0 BIT(23)#define REG_PCI_CONTROL_REFCLK_EN1 BIT(22) +#define REG_PCI_CONTROL_PERSTOUT2 BIT(16)#define REG_GSW_CLK_DIV_SEL 0x1b4#define REG_EMI_CLK_DIV_SEL 0x1b8#define REG_BUS_CLK_DIV_SEL 0x1bcdrivers/clk/clk-en7523.c line 24
Quoted 5 lines
drivers/clk/clk-en7523.c +1
-1@@ -18,10 +21,25 @@#define REG_SPI_CLK_FREQ_SEL 0x1c8#define REG_NPU_CLK_DIV_SEL 0x1fc#define REG_CRYPTO_CLKSRC 0x200 -#define REG_RESET_CONTROL 0x834 +#define REG_RESET_CONTROL2 0x830Wait what? The RESET2 register comes before RESET1 ?!?!
Quoted 1 line
Is this a typo? :-)
actually not :)
Quoted 71 lines
Quoted 58 lines
drivers/clk/clk-en7523.c +36
-4+#define REG_RESET2_CONTROL_PCIE2 BIT(27) +#define REG_RESET_CONTROL1 0x834#define REG_RESET_CONTROL_PCIEHB BIT(29)#define REG_RESET_CONTROL_PCIE1 BIT(27)#define REG_RESET_CONTROL_PCIE2 BIT(26) +/* EN7581 */ +#define REG_PCIE0_MEM 0x00 +#define REG_PCIE0_MEM_MASK 0x04 +#define REG_PCIE1_MEM 0x08 +#define REG_PCIE1_MEM_MASK 0x0c +#define REG_PCIE2_MEM 0x10 +#define REG_PCIE2_MEM_MASK 0x14 +#define REG_PCIE_RESET_OPEN_DRAIN 0x018c +#define REG_PCIE_RESET_OPEN_DRAIN_MASK GENMASK(2, 0) +#define REG_NP_SCU_PCIC 0x88 +#define REG_NP_SCU_SSTR 0x9c +#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) +#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)struct en_clk_desc {int id;@@ -207,14 +225,14 @@ static int en7523_pci_prepare(struct clk_hw *hw)usleep_range (1000 ,2000 );/* Reset to default */ - val =readl (np_base +REG_RESET_CONTROL ); + val =readl (np_base +REG_RESET_CONTROL1 ); mask =REG_RESET_CONTROL_PCIE1 |REG_RESET_CONTROL_PCIE2 |REG_RESET_CONTROL_PCIEHB ; -writel (val & ~mask, np_base +REG_RESET_CONTROL ); +writel (val & ~mask, np_base +REG_RESET_CONTROL1 );usleep_range (1000 ,2000 ); -writel (val | mask, np_base +REG_RESET_CONTROL ); +writel (val | mask, np_base +REG_RESET_CONTROL1 );msleep (100 ); -writel (val & ~mask, np_base +REG_RESET_CONTROL ); +writel (val & ~mask, np_base +REG_RESET_CONTROL1 );usleep_range (5000 ,10000 );/* Release device */ @@ -262,6 +280,64 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev,return &cg->hw; } +static int en7581_pci_is_enabled (struct clk_hw *hw) +{ + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); +u32 val, mask; + + mask =REG_PCI_CONTROL_REFCLK_EN0 |REG_PCI_CONTROL_REFCLK_EN1 ; + val =readl (cg->base +REG_PCI_CONTROL ); +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 |drivers/clk/clk-en7523.c static struct clk_hw *en7523_register_pcie_clk(struct device *dev, · line 308
Quoted 10 lines
drivers/clk/clk-en7523.c +10
-0+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 ); + + mask =REG_PCI_CONTROL_REFCLK_EN0 |REG_PCI_CONTROL_REFCLK_EN1 | +REG_PCI_CONTROL_PERSTOUT1 |REG_PCI_CONTROL_PERSTOUT2 | +REG_PCI_CONTROL_PERSTOUT ;I'm not sure that this is actually something to control in a clock driver...
Quoted 6 lines
the right thing to do would be to add a reset controller to this clock driver and then assert/deassert reset in the PCIe PHY/MAC driver.
Perhaps REFCLK_EN0/EN1 can be manipulated in a .enable() callback, treating this really just as what it appears to really be: a gate clock! (hint: check
clk-gate.c)
ack, I will look into it.
Quoted 17 lines
Quoted 5 lines
drivers/clk/clk-en7523.c +4
-0+ val =readl (np_base +REG_PCI_CONTROL ); +writel (val | mask, np_base +REG_PCI_CONTROL ); +msleep (250 ); +drivers/clk/clk-en7523.c static struct clk_hw *en7523_register_pcie_clk(struct device *dev, · line 323
Quoted 10 lines
drivers/clk/clk-en7523.c +10
-0+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_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |...and this should be a clk-gate .disable() callback, I guess :-)
ack, I will look into it.
Quoted 43 lines
Quoted 30 lines
drivers/clk/clk-en7523.c +23
-0+REG_PCI_CONTROL_PERSTOUT1 |REG_PCI_CONTROL_PERSTOUT2 | +REG_PCI_CONTROL_PERSTOUT ; + val =readl (np_base +REG_PCI_CONTROL ); +writel (val & ~mask, np_base +REG_PCI_CONTROL ); +usleep_range (1000 ,2000 ); + + 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 en7523_register_clocks (struct device *dev,struct clk_hw_onecell_data *clk_data,void __iomem *base,void __iomem *np_base) {@@ -291,6 +367,37 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat clk_data->num =EN7523_NUM_CLOCKS ; } +static int en7581_clk_hw_init (struct platform_device *pdev, +void __iomem *base, +void __iomem *np_base) +{ +void __iomem *pb_base; +u32 val;drivers/clk/clk-en7523.c static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat · line 384
Quoted 10 lines
drivers/clk/clk-en7523.c +10
-0+ + pb_base =devm_platform_ioremap_resource (pdev,2 ); +if (IS_ERR (pb_base)) +return PTR_ERR (pb_base); + + val =readl (np_base +REG_NP_SCU_SSTR ); + val &= ~(REG_PCIE_XSI0_SEL_MASK |REG_PCIE_XSI1_SEL_MASK ); +writel (val, np_base +REG_NP_SCU_SSTR ); + val =readl (np_base +REG_NP_SCU_PCIC ); +writel (val |3 , np_base +REG_NP_SCU_PCIC );What is 3?
Quoted 1 line
#define SOMETHING 3 ??
actullay I do not know what it means since write in the pcie_ctrl subfield of REG_NP_SCU_PCIC but it is a GENMASK(7, 0) and I do not have any more info about it.
Quoted 11 lines
drivers/clk/clk-en7523.c static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat · line 392
Quoted 8 lines
drivers/clk/clk-en7523.c +7
-0+ +writel (0x20000000 , pb_base +REG_PCIE0_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE0_MEM_MASK ); +writel (0x24000000 , pb_base +REG_PCIE1_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE1_MEM_MASK ); +writel (0x28000000 , pb_base +REG_PCIE2_MEM ); +writel (0xfc000000 , pb_base +REG_PCIE2_MEM_MASK );And... this is .. some
BIT()and someGENMASK()as far as I understand... do we have any clue about what you're setting to those registers?
same as above, they seems undocumented.
@airoha folks: any input about them?
Quoted 38 lines
Can MediaTek/Airoha help with this, please?
#define SOMETHING BIT(29) /* this is
0x20000000*/ #defineSOME_MASKGENMASK(31, 26)/* this is0xfc00000*/Quoted 24 lines
drivers/clk/clk-en7523.c +14
-0+ + val =readl (base +REG_PCIE_RESET_OPEN_DRAIN ); +writel (val |REG_PCIE_RESET_OPEN_DRAIN_MASK , + base +REG_PCIE_RESET_OPEN_DRAIN ); + +return 0 ; +} +static int en7523_clk_probe (struct platform_device *pdev) {struct device_node *node = pdev->dev.of_node;@@ -306,6 +413,12 @@ static int en7523_clk_probe(struct platform_device *pdev)if (IS_ERR (np_base))return PTR_ERR (np_base); +if (of_device_is_compatible (node,"airoha,en7581-scu" )) { + r =en7581_clk_hw_init (pdev, base, np_base); +if (r) +return r; + } + clk_data =devm_kzalloc (&pdev->dev,struct_size (clk_data, hws,EN7523_NUM_CLOCKS ),GFP_KERNEL );drivers/clk/clk-en7523.c static const struct clk_ops en7523_pcie_ops = { · line 443
Quoted 2 lines
drivers/clk/clk-en7523.c +0
-0@@ -329,8 +442,15 @@ static const struct clk_ops en7523_pcie_ops = { .unprepare = en7523_pci_unprepare, };static const struct clk_en7523_pdata en7581_pdata = { .init = en7581_clk_hw_init, /* if (pdata->init) pdata->init(x, y, z) */ .ops = en7581_pcie_ops, };
Quoted 8 lines
or, alternatively:
static const struct .... = { .init = ..., .ops = (const struct clk_ops) { .is_enabled = en7581_pci_is_enabled, .... etc }
ack, I will fix it.
Regards,
Lorenzo
Quoted 18 lines
};
Cheers,
Angelodrivers/clk/clk-en7523.c static const struct clk_ops en7523_pcie_ops = { · line 455
Quoted 11 lines
drivers/clk/clk-en7523.c +7
-0+static const struct clk_ops en7581_pcie_ops = { + .is_enabled = en7581_pci_is_enabled, + .prepare = en7581_pci_prepare, + .unprepare = en7581_pci_unprepare, +}; +static const struct of_device_id of_match_clk_en7523[] = { { .compatible ="airoha,en7523-scu" , .data = &en7523_pcie_ops }, + { .compatible ="airoha,en7581-scu" , .data = &en7581_pcie_ops }, {/* sentinel */ } };-